[spirv-reader] Store to module-scope variables

Bug: tint:3
Change-Id: Ib4dbb976268999529c2a1c55531aa8293e565b9c
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/19222
Reviewed-by: dan sinclair <dsinclair@google.com>
diff --git a/src/reader/spirv/function.cc b/src/reader/spirv/function.cc
index 5a2da1f..d356e1f 100644
--- a/src/reader/spirv/function.cc
+++ b/src/reader/spirv/function.cc
@@ -209,6 +209,10 @@
     return nullptr;
   }
   switch (inst->opcode()) {
+    case SpvOpVariable:
+      // This occurs for module-scope variables.
+      return std::make_unique<ast::IdentifierExpression>(
+          namer_.Name(inst->result_id()));
     default:
       break;
   }
diff --git a/src/reader/spirv/function_memory_test.cc b/src/reader/spirv/function_memory_test.cc
index 4b9899b..9b96018 100644
--- a/src/reader/spirv/function_memory_test.cc
+++ b/src/reader/spirv/function_memory_test.cc
@@ -257,6 +257,28 @@
 )"));
 }
 
+TEST_F(SpvParserTest, EmitStatement_StoreToModuleScopeVar) {
+  auto p = parser(test::Assemble(R"(
+     %void = OpTypeVoid
+     %voidfn = OpTypeFunction %void
+     %ty = OpTypeInt 32 0
+     %val = OpConstant %ty 42
+     %ptr_ty = OpTypePointer Workgroup %ty
+     %1 = OpVariable %ptr_ty Workgroup
+     %100 = OpFunction %void None %voidfn
+     %entry = OpLabel
+     OpStore %1 %val
+     OpReturn
+  )"));
+  ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
+  FunctionEmitter fe(p, *spirv_function(100));
+  EXPECT_TRUE(fe.EmitBody());
+  EXPECT_THAT(ToString(fe.ast_body()), HasSubstr(R"(Assignment{
+  Identifier{x_1}
+  ScalarConstructor{42}
+})"));
+}
+
 }  // namespace
 }  // namespace spirv
 }  // namespace reader