spirv-reader: support OpCopyMemory
Bug: tint:3
Change-Id: I779593c379b1f24cb805b69e788c467e64af6db3
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/51041
Auto-Submit: David Neto <dneto@google.com>
Commit-Queue: David Neto <dneto@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
diff --git a/src/reader/spirv/function.cc b/src/reader/spirv/function.cc
index 6aad051..3bb750c 100644
--- a/src/reader/spirv/function.cc
+++ b/src/reader/spirv/function.cc
@@ -3349,6 +3349,29 @@
return EmitConstDefOrWriteToHoistedVar(inst, expr);
}
+ case SpvOpCopyMemory: {
+ // Generate an assignment.
+ // TODO(dneto): When supporting ptr-ref, the LHS pointer and RHS pointer
+ // map to reference types in WGSL.
+ auto lhs = MakeOperand(inst, 0);
+ auto rhs = MakeOperand(inst, 1);
+ // Ignore any potential memory operands. Currently they are all for
+ // concepts not in WGSL:
+ // Volatile
+ // Aligned
+ // Nontemporal
+ // MakePointerAvailable ; Vulkan memory model
+ // MakePointerVisible ; Vulkan memory model
+ // NonPrivatePointer ; Vulkan memory model
+
+ if (!success()) {
+ return false;
+ }
+ AddStatement(
+ create<ast::AssignmentStatement>(Source{}, lhs.expr, rhs.expr));
+ return success();
+ }
+
case SpvOpCopyObject: {
// Arguably, OpCopyObject is purely combinatorial. On the other hand,
// it exists to make a new name for something. So we choose to make
diff --git a/src/reader/spirv/function_memory_test.cc b/src/reader/spirv/function_memory_test.cc
index a26a065..e6b1d3e 100644
--- a/src/reader/spirv/function_memory_test.cc
+++ b/src/reader/spirv/function_memory_test.cc
@@ -292,6 +292,34 @@
})"));
}
+TEST_F(SpvParserMemoryTest,
+ EmitStatement_CopyMemory_Scalar_Workgroup_To_Private) {
+ auto p = parser(test::Assemble(Preamble() + R"(
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %ty = OpTypeInt 32 0
+ %val = OpConstant %ty 42
+ %ptr_wg_ty = OpTypePointer Workgroup %ty
+ %ptr_priv_ty = OpTypePointer Private %ty
+ %1 = OpVariable %ptr_wg_ty Workgroup
+ %2 = OpVariable %ptr_priv_ty Workgroup
+ %100 = OpFunction %void None %voidfn
+ %entry = OpLabel
+ OpCopyMemory %2 %1
+ OpReturn
+ OpFunctionEnd
+ )"));
+ ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
+ auto fe = p->function_emitter(100);
+ EXPECT_TRUE(fe.EmitBody());
+ const auto got = ToString(p->builder(), fe.ast_body());
+ const auto* expected = R"(Assignment{
+ Identifier[not set]{x_2}
+ Identifier[not set]{x_1}
+})";
+ EXPECT_THAT(got, HasSubstr(expected));
+}
+
TEST_F(SpvParserMemoryTest, EmitStatement_AccessChain_NoOperands) {
auto err = test::AssembleFailure(Preamble() + R"(
%void = OpTypeVoid