[spirv-reader][ir] Register names instead of using new

Switch the SPIRV-IR Reader to use `Register` instead of `New` with the
symbol table. Duplicate names are "allowed" by SPIR-V, the renaming will
be handled by the backends based on their individual rules.

Bug: 391486060
Change-Id: I5fa80034e2e6d58452f04aaa4809e7ca810bad65
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/226274
Reviewed-by: James Price <jrprice@google.com>
Commit-Queue: dan sinclair <dsinclair@chromium.org>
diff --git a/src/tint/lang/spirv/reader/parser/name_test.cc b/src/tint/lang/spirv/reader/parser/name_test.cc
index dc819e7..b61b335 100644
--- a/src/tint/lang/spirv/reader/parser/name_test.cc
+++ b/src/tint/lang/spirv/reader/parser/name_test.cc
@@ -111,7 +111,7 @@
 %main = @compute @workgroup_size(1u, 1u, 1u) func():void {
   $B1: {
     %vanilla:i32 = let 1i
-    %vanilla_1:i32 = let 2i
+    %vanilla_1:i32 = let 2i  # %vanilla_1: 'vanilla'
     ret
   }
 }
@@ -157,6 +157,55 @@
 )");
 }
 
+TEST_F(SpirvParserTest, Name_DuplicateStructNames) {
+    EXPECT_IR(R"(
+               OpCapability Shader
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint GLCompute %main "main"
+               OpExecutionMode %main LocalSize 1 1 1
+               OpName %S "Desert"
+               OpName %D "Desert"
+       %void = OpTypeVoid
+        %i32 = OpTypeInt 32 1
+        %f32 = OpTypeFloat 32
+          %S = OpTypeStruct %i32 %i32 %i32
+          %D = OpTypeStruct %i32 %i32 %f32
+        %one = OpConstant %i32 1
+        %two = OpConstant %f32 2
+          %s = OpConstantComposite %S %one %one %one
+          %d = OpConstantComposite %D %one %one %two
+    %ep_type = OpTypeFunction %void
+
+       %main = OpFunction %void None %ep_type
+ %main_start = OpLabel
+          %2 = OpCopyObject %S %s
+          %3 = OpCopyObject %D %d
+               OpReturn
+               OpFunctionEnd
+)",
+              R"(
+Desert = struct @align(4) {
+  tint_symbol:i32 @offset(0)
+  tint_symbol_1:i32 @offset(4)
+  tint_symbol_2:i32 @offset(8)
+}
+
+Desert_1 = struct @align(4) {
+  tint_symbol_3:i32 @offset(0)
+  tint_symbol_4:i32 @offset(4)
+  tint_symbol_5:f32 @offset(8)
+}
+
+%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
+  $B1: {
+    %2:Desert = let Desert(1i)
+    %3:Desert_1 = let Desert_1(1i, 1i, 2.0f)
+    ret
+  }
+}
+)");
+}
+
 TEST_F(SpirvParserTest, Name_IgnoreEmptyMemberName) {
     EXPECT_IR(R"(
                OpCapability Shader
diff --git a/src/tint/lang/spirv/reader/parser/parser.cc b/src/tint/lang/spirv/reader/parser/parser.cc
index 2f200bb..1f71f29 100644
--- a/src/tint/lang/spirv/reader/parser/parser.cc
+++ b/src/tint/lang/spirv/reader/parser/parser.cc
@@ -381,8 +381,11 @@
             Symbol name;
             if (member_names && member_names->size() > i) {
                 auto n = (*member_names)[i];
-                name = ir_.symbols.New(n);
-            } else {
+                if (!n.empty()) {
+                    name = ir_.symbols.Register(n);
+                }
+            }
+            if (!name.IsValid()) {
                 name = ir_.symbols.New();
             }
 
@@ -392,14 +395,14 @@
             current_size = offset + member_ty->Size();
         }
 
-        Symbol name = GetSymbolFor(struct_id);
+        Symbol name = GetUniqueSymbolFor(struct_id);
         if (!name.IsValid()) {
             name = ir_.symbols.New();
         }
         return ty_.Struct(name, std::move(members));
     }
 
-    Symbol GetSymbolFor(uint32_t id) {
+    Symbol GetUniqueSymbolFor(uint32_t id) {
         auto iter = id_to_name_.find(id);
         if (iter != id_to_name_.end()) {
             return ir_.symbols.New(iter->second);
@@ -407,6 +410,14 @@
         return Symbol{};
     }
 
+    Symbol GetSymbolFor(uint32_t id) {
+        auto iter = id_to_name_.find(id);
+        if (iter != id_to_name_.end()) {
+            return ir_.symbols.Register(iter->second);
+        }
+        return Symbol{};
+    }
+
     /// @param id a SPIR-V result ID for a function declaration instruction
     /// @returns a Tint function object
     core::ir::Function* Function(uint32_t id) {