[ir] Disable runtime-sized array clamping

Handle the config option that skips clamping of runtime-sized array
indices.

Bug: tint:1718
Change-Id: I54e1ee96e350791d84b3dab17178799b003a0cf3
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/151140
Reviewed-by: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
diff --git a/src/tint/lang/core/ir/transform/robustness.cc b/src/tint/lang/core/ir/transform/robustness.cc
index ed03c80..1d73cf9 100644
--- a/src/tint/lang/core/ir/transform/robustness.cc
+++ b/src/tint/lang/core/ir/transform/robustness.cc
@@ -129,7 +129,6 @@
         }
 
         // TODO(jrprice): Handle config.bindings_ignored.
-        // TODO(jrprice): Handle config.disable_runtime_sized_array_index_clamping.
     }
 
     /// Check if clamping should be applied to a particular address space.
@@ -223,6 +222,11 @@
                     TINT_ASSERT_OR_RETURN_VALUE(arr->Count()->Is<type::RuntimeArrayCount>(),
                                                 nullptr);
 
+                    // Skip clamping runtime-sized array indices if requested.
+                    if (config.disable_runtime_sized_array_index_clamping) {
+                        return nullptr;
+                    }
+
                     auto* object = access->Object();
                     if (i > 0) {
                         // Generate a pointer to the runtime-sized array if it isn't the base of
diff --git a/src/tint/lang/core/ir/transform/robustness_test.cc b/src/tint/lang/core/ir/transform/robustness_test.cc
index 6bb4be0..8d0b97c 100644
--- a/src/tint/lang/core/ir/transform/robustness_test.cc
+++ b/src/tint/lang/core/ir/transform/robustness_test.cc
@@ -1637,7 +1637,7 @@
 INSTANTIATE_TEST_SUITE_P(, IR_RobustnessTest, testing::Values(false, true));
 
 ////////////////////////////////////////////////////////////////
-// Test clamping non-pointer arrays.
+// Test clamping runtime-sized arrays.
 ////////////////////////////////////////////////////////////////
 
 TEST_P(IR_RobustnessTest, RuntimeSizedArray_ConstIndex) {
@@ -1876,6 +1876,60 @@
     EXPECT_EQ(GetParam() ? expect : src, str());
 }
 
+TEST_P(IR_RobustnessTest, RuntimeSizedArray_DisableClamping) {
+    auto* arr = b.Var("arr", ty.ptr(storage, ty.array<u32>()));
+    arr->SetBindingPoint(0, 0);
+    b.RootBlock()->Append(arr);
+
+    auto* func = b.Function("foo", ty.u32());
+    auto* idx = b.FunctionParam("idx", ty.u32());
+    func->SetParams({idx});
+    b.Append(func->Block(), [&] {
+        auto* access = b.Access(ty.ptr<storage, u32>(), arr, idx);
+        auto* load = b.Load(access);
+        b.Return(func, load);
+    });
+
+    auto* src = R"(
+%b1 = block {  # root
+  %arr:ptr<storage, array<u32>, read_write> = var @binding_point(0, 0)
+}
+
+%foo = func(%idx:u32):u32 -> %b2 {
+  %b2 = block {
+    %4:ptr<storage, u32, read_write> = access %arr, %idx
+    %5:u32 = load %4
+    ret %5
+  }
+}
+)";
+    EXPECT_EQ(src, str());
+
+    auto* expect = R"(
+%b1 = block {  # root
+  %arr:ptr<storage, array<u32>, read_write> = var @binding_point(0, 0)
+}
+
+%foo = func(%idx:u32):u32 -> %b2 {
+  %b2 = block {
+    %4:u32 = arrayLength %arr
+    %5:u32 = sub %4, 1u
+    %6:u32 = min %idx, %5
+    %7:ptr<storage, u32, read_write> = access %arr, %6
+    %8:u32 = load %7
+    ret %8
+  }
+}
+)";
+
+    RobustnessConfig cfg;
+    cfg.clamp_storage = true;
+    cfg.disable_runtime_sized_array_index_clamping = !GetParam();
+    Run(Robustness, cfg);
+
+    EXPECT_EQ(GetParam() ? expect : src, str());
+}
+
 ////////////////////////////////////////////////////////////////
 // Test clamping texture builtin calls.
 ////////////////////////////////////////////////////////////////