Import Tint changes from Dawn

Changes:
  - f83de0f6583483d76b647ad716702723ec276a42 [tint][ast] Fix DemoteToHelper with atomicCompareExchange... by Ben Clayton <bclayton@google.com>
  - 6e4581343156949e7d895534962859ce3b63c37f GLSL: fix bug with padded struct members. by Stephen White <senorblanco@chromium.org>
GitOrigin-RevId: f83de0f6583483d76b647ad716702723ec276a42
Change-Id: I43bc90bb1e52fb76c80324a53b0e1dab8c52f5e8
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/173320
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
diff --git a/src/tint/lang/glsl/writer/ast_raise/pad_structs.cc b/src/tint/lang/glsl/writer/ast_raise/pad_structs.cc
index 0037935..0d4aa89 100644
--- a/src/tint/lang/glsl/writer/ast_raise/pad_structs.cc
+++ b/src/tint/lang/glsl/writer/ast_raise/pad_structs.cc
@@ -50,13 +50,20 @@
 
 void CreatePadding(Vector<const ast::StructMember*, 8>* new_members,
                    Hashset<const ast::StructMember*, 8>* padding_members,
+                   Hashset<std::string, 8>* member_names,
+                   int& last_padding_index,
                    ast::Builder* b,
                    uint32_t bytes) {
     const size_t count = bytes / 4u;
     padding_members->Reserve(count);
     new_members->Reserve(count);
+    member_names->Reserve(count);
+    std::string name = "pad";
     for (uint32_t i = 0; i < count; ++i) {
-        auto name = b->Symbols().New("pad");
+        while (member_names->Contains(name)) {
+            name = "pad_" + std::to_string(++last_padding_index);
+        }
+        member_names->Add(name);
         auto* member = b->Member(name, b->ty.u32());
         padding_members->Add(member);
         new_members->Push(member);
@@ -87,11 +94,18 @@
         uint32_t offset = 0;
         bool has_runtime_sized_array = false;
         tint::Vector<const ast::StructMember*, 8> new_members;
+        Hashset<std::string, 8> member_names;
+        for (auto* mem : str->Members()) {
+            member_names.Add(mem->Name().Name());
+        }
+
+        int last_padding_index = 0;
         for (auto* mem : str->Members()) {
             auto name = mem->Name().Name();
 
             if (offset < mem->Offset()) {
-                CreatePadding(&new_members, &padding_members, ctx.dst, mem->Offset() - offset);
+                CreatePadding(&new_members, &padding_members, &member_names, last_padding_index,
+                              ctx.dst, mem->Offset() - offset);
                 offset = mem->Offset();
             }
 
@@ -118,7 +132,8 @@
             struct_size = tint::RoundUp(16u, struct_size);
         }
         if (offset < struct_size && !has_runtime_sized_array) {
-            CreatePadding(&new_members, &padding_members, ctx.dst, struct_size - offset);
+            CreatePadding(&new_members, &padding_members, &member_names, last_padding_index,
+                          ctx.dst, struct_size - offset);
         }
 
         tint::Vector<const ast::Attribute*, 1> struct_attribs;
diff --git a/src/tint/lang/glsl/writer/ast_raise/pad_structs_test.cc b/src/tint/lang/glsl/writer/ast_raise/pad_structs_test.cc
index 170fad5..91107c5 100644
--- a/src/tint/lang/glsl/writer/ast_raise/pad_structs_test.cc
+++ b/src/tint/lang/glsl/writer/ast_raise/pad_structs_test.cc
@@ -580,6 +580,142 @@
     EXPECT_EQ(expect, str(got));
 }
 
+TEST_F(PadStructsTest, MemberNamedPad) {
+    auto* src = R"(
+struct S {
+  @align(8) pad_5 : u32,
+  @align(8) pad_3 : u32,
+  @align(8) pad :   u32,
+  @align(8) pad_1 : u32,
+}
+
+@group(0) @binding(0) var<uniform> s : S;
+
+fn main() {
+  _ = s;
+}
+)";
+    auto* expect = R"(
+@internal(disable_validation__ignore_struct_member)
+struct S {
+  pad_5 : u32,
+  pad_2 : u32,
+  pad_3 : u32,
+  pad_4 : u32,
+  pad : u32,
+  pad_6 : u32,
+  pad_1 : u32,
+  pad_7 : u32,
+}
+
+@group(0) @binding(0) var<uniform> s : S;
+
+fn main() {
+  _ = s;
+}
+)";
+
+    ast::transform::DataMap data;
+    auto got = Run<PadStructs>(src, data);
+
+    EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(PadStructsTest, TwoStructs) {
+    auto* src = R"(
+struct S {
+  @align(8) i : i32,
+  @align(8) u : u32,
+}
+
+struct T {
+  @align(8) i : i32,
+  @align(8) u : u32,
+}
+
+@group(0) @binding(0) var<uniform> s : S;
+@group(0) @binding(1) var<uniform> t : T;
+
+fn main() {
+  _ = s;
+  _ = t;
+}
+)";
+    auto* expect = R"(
+@internal(disable_validation__ignore_struct_member)
+struct S {
+  i : i32,
+  pad : u32,
+  u : u32,
+  pad_1 : u32,
+}
+
+@internal(disable_validation__ignore_struct_member)
+struct T {
+  i : i32,
+  pad : u32,
+  u : u32,
+  pad_1 : u32,
+}
+
+@group(0) @binding(0) var<uniform> s : S;
+
+@group(0) @binding(1) var<uniform> t : T;
+
+fn main() {
+  _ = s;
+  _ = t;
+}
+)";
+
+    ast::transform::DataMap data;
+    auto got = Run<PadStructs>(src, data);
+
+    EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(PadStructsTest, GlobalVariableNamedPad) {
+    auto* src = R"(
+@group(0) @binding(0) var<uniform> pad : u32;
+@group(0) @binding(1) var<uniform> pad_1 : u32;
+
+struct S {
+  @align(8) i : u32,
+  @align(8) j : u32,
+}
+
+@group(0) @binding(1) var<uniform> s : S;
+
+fn main() {
+  _ = s;
+}
+)";
+    auto* expect = R"(
+@group(0) @binding(0) var<uniform> pad : u32;
+
+@group(0) @binding(1) var<uniform> pad_1 : u32;
+
+@internal(disable_validation__ignore_struct_member)
+struct S {
+  i : u32,
+  pad : u32,
+  j : u32,
+  pad_1 : u32,
+}
+
+@group(0) @binding(1) var<uniform> s : S;
+
+fn main() {
+  _ = s;
+}
+)";
+
+    ast::transform::DataMap data;
+    auto got = Run<PadStructs>(src, data);
+
+    EXPECT_EQ(expect, str(got));
+}
+
 TEST_F(PadStructsTest, InitializerZeroArgs) {
     // Calls to a zero-argument initializer of a padded struct should not be modified.
     auto* src = R"(
diff --git a/src/tint/lang/wgsl/ast/transform/demote_to_helper.cc b/src/tint/lang/wgsl/ast/transform/demote_to_helper.cc
index 28e776b..1b88f20 100644
--- a/src/tint/lang/wgsl/ast/transform/demote_to_helper.cc
+++ b/src/tint/lang/wgsl/ast/transform/demote_to_helper.cc
@@ -191,50 +191,10 @@
                         //   }
                         //   let y = x + tmp;
                         auto result = b.Sym();
-                        Type result_ty;
-                        const Statement* masked_call = nullptr;
-                        if (builtin->Fn() == wgsl::BuiltinFn::kAtomicCompareExchangeWeak) {
-                            // Special case for atomicCompareExchangeWeak as we cannot name its
-                            // result type. We have to declare an equivalent struct and copy the
-                            // original member values over to it.
-
-                            // Declare a struct to hold the result values.
-                            auto* result_struct = sem_call->Type()->As<core::type::Struct>();
-                            auto* atomic_ty = result_struct->Members()[0]->Type();
-                            result_ty =
-                                b.ty(tint::GetOrAdd(atomic_cmpxchg_result_types, atomic_ty, [&] {
-                                    auto name = b.Sym();
-                                    b.Structure(
-                                        name,
-                                        tint::Vector{
-                                            b.Member("old_value", CreateASTTypeFor(ctx, atomic_ty)),
-                                            b.Member("exchanged", b.ty.bool_()),
-                                        });
-                                    return name;
-                                }));
-
-                            // Generate the masked call and member-wise copy:
-                            //   if (!tint_discarded) {
-                            //     let tmp_result = atomicCompareExchangeWeak(&p, 1, 2);
-                            //     result.exchanged = tmp_result.exchanged;
-                            //     result.old_value = tmp_result.old_value;
-                            //   }
-                            auto tmp_result = b.Sym();
-                            masked_call =
-                                b.If(b.Not(flag),
-                                     b.Block(tint::Vector{
-                                         b.Decl(b.Let(tmp_result, ctx.CloneWithoutTransform(call))),
-                                         b.Assign(b.MemberAccessor(result, "old_value"),
-                                                  b.MemberAccessor(tmp_result, "old_value")),
-                                         b.Assign(b.MemberAccessor(result, "exchanged"),
-                                                  b.MemberAccessor(tmp_result, "exchanged")),
-                                     }));
-                        } else {
-                            result_ty = CreateASTTypeFor(ctx, sem_call->Type());
-                            masked_call =
-                                b.If(b.Not(flag),
-                                     b.Block(b.Assign(result, ctx.CloneWithoutTransform(call))));
-                        }
+                        auto result_ty = CreateASTTypeFor(ctx, sem_call->Type());
+                        auto* masked_call =
+                            b.If(b.Not(flag),
+                                 b.Block(b.Assign(result, ctx.CloneWithoutTransform(call))));
                         auto* result_decl = b.Decl(b.Var(result, result_ty));
                         hoist_to_decl_before.Prepare(sem_call);
                         hoist_to_decl_before.InsertBefore(stmt, result_decl);
diff --git a/src/tint/lang/wgsl/ast/transform/demote_to_helper_test.cc b/src/tint/lang/wgsl/ast/transform/demote_to_helper_test.cc
index de590a4..0af6dd1 100644
--- a/src/tint/lang/wgsl/ast/transform/demote_to_helper_test.cc
+++ b/src/tint/lang/wgsl/ast/transform/demote_to_helper_test.cc
@@ -1187,11 +1187,6 @@
     auto* expect = R"(
 var<private> tint_discarded = false;
 
-struct tint_symbol_1 {
-  old_value : i32,
-  exchanged : bool,
-}
-
 @group(0) @binding(0) var t : texture_2d<f32>;
 
 @group(0) @binding(1) var s : sampler;
@@ -1204,20 +1199,16 @@
     tint_discarded = true;
   }
   var result = 0;
-  var tint_symbol : tint_symbol_1;
+  var tint_symbol : __atomic_compare_exchange_result_i32;
   if (!(tint_discarded)) {
-    let tint_symbol_2 = atomicCompareExchangeWeak(&(a), i32(in), 42);
-    tint_symbol.old_value = tint_symbol_2.old_value;
-    tint_symbol.exchanged = tint_symbol_2.exchanged;
+    tint_symbol = atomicCompareExchangeWeak(&(a), i32(in), 42);
   }
   if (!(tint_symbol.exchanged)) {
-    var tint_symbol_3 : tint_symbol_1;
+    var tint_symbol_1 : __atomic_compare_exchange_result_i32;
     if (!(tint_discarded)) {
-      let tint_symbol_4 = atomicCompareExchangeWeak(&(a), i32(in), 42);
-      tint_symbol_3.old_value = tint_symbol_4.old_value;
-      tint_symbol_3.exchanged = tint_symbol_4.exchanged;
+      tint_symbol_1 = atomicCompareExchangeWeak(&(a), i32(in), 42);
     }
-    let xchg = tint_symbol_3;
+    let xchg = tint_symbol_1;
     result = xchg.old_value;
   }
   result += i32(textureSample(t, s, coord).x);