transform/BoundArrayAccessors: Fix symbol renaming

We need to pre-clone the source program's symbols before creating the symbols `min` and `arrayLength`, otherwise the original program's symbols will be suffixed with a number to make them unique.

Fixes Dawn tests that triggered this issue.

Bug: tint:712
Change-Id: Ie1cf6cbcf2050a2ce1a94acf0ae131a06f635820
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/47761
Auto-Submit: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: James Price <jrprice@google.com>
Reviewed-by: James Price <jrprice@google.com>
diff --git a/src/transform/bound_array_accessors.cc b/src/transform/bound_array_accessors.cc
index d4b7bed..0ba5a49 100644
--- a/src/transform/bound_array_accessors.cc
+++ b/src/transform/bound_array_accessors.cc
@@ -29,6 +29,11 @@
 Transform::Output BoundArrayAccessors::Run(const Program* in, const DataMap&) {
   ProgramBuilder out;
   CloneContext ctx(&out, in);
+
+  // Start by cloning all the symbols. This ensures that the authored symbols
+  // won't get renamed if they collide with new symbols below.
+  ctx.CloneSymbols();
+
   ctx.ReplaceAll([&](ast::ArrayAccessorExpression* expr) {
     return Transform(expr, &ctx);
   });
diff --git a/src/transform/bound_array_accessors_test.cc b/src/transform/bound_array_accessors_test.cc
index 5205480..7ab6534 100644
--- a/src/transform/bound_array_accessors_test.cc
+++ b/src/transform/bound_array_accessors_test.cc
@@ -540,7 +540,7 @@
   a : f32;
   b : array<f32>;
 };
-var<in> s : S;
+var<storage> s : S;
 
 fn f() {
   var d : f32 = s.b[25];
@@ -554,7 +554,7 @@
   b : array<f32>;
 };
 
-var<in> s : S;
+var<storage> s : S;
 
 fn f() {
   var d : f32 = s.b[min(u32(25), (arrayLength(s.b) - 1u))];
@@ -592,6 +592,49 @@
   FAIL();
 }
 
+// Check that existing use of min() and arrayLength() do not get renamed.
+TEST_F(BoundArrayAccessorsTest, DontRenameSymbols) {
+  auto* src = R"(
+[[block]]
+struct S {
+  a : f32;
+  b : array<f32>;
+};
+
+var<storage> s : S;
+
+let c : u32 = 1u;
+
+fn f() {
+  let b : f32 = s.b[c];
+  let x : i32 = min(1, 2);
+  let y : u32 = arrayLength(s.b);
+}
+)";
+
+  auto* expect = R"(
+[[block]]
+struct S {
+  a : f32;
+  b : array<f32>;
+};
+
+var<storage> s : S;
+
+let c : u32 = 1u;
+
+fn f() {
+  let b : f32 = s.b[min(u32(c), (arrayLength(s.b) - 1u))];
+  let x : i32 = min(1, 2);
+  let y : u32 = arrayLength(s.b);
+}
+)";
+
+  auto got = Run<BoundArrayAccessors>(src);
+
+  EXPECT_EQ(expect, str(got));
+}
+
 }  // namespace
 }  // namespace transform
 }  // namespace tint