spirv-reader: test conditional address-of on function call
Bug: tint:804
Change-Id: I7178270fcd8487a20a4e25a2e5389a07e22b4dd6
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/55363
Auto-Submit: David Neto <dneto@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
Commit-Queue: David Neto <dneto@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
diff --git a/src/reader/spirv/function_var_test.cc b/src/reader/spirv/function_var_test.cc
index bd16951..cf2e9aa 100644
--- a/src/reader/spirv/function_var_test.cc
+++ b/src/reader/spirv/function_var_test.cc
@@ -2682,6 +2682,156 @@
EXPECT_EQ(got, expected) << got;
}
+TEST_F(SpvParserFunctionVarTest, EmitStatement_Hoist_UsedAsNonPtrArg) {
+ // Spawned from crbug.com/tint/804
+ const auto assembly = Preamble() + R"(
+ %fn_int = OpTypeFunction %void %int
+
+ %500 = OpFunction %void None %fn_int
+ %501 = OpFunctionParameter %int
+ %502 = OpLabel
+ OpReturn
+ OpFunctionEnd
+
+ %100 = OpFunction %void None %voidfn
+
+ %10 = OpLabel
+ OpSelectionMerge %50 None
+ OpBranchConditional %true %20 %30
+
+ %20 = OpLabel
+ %200 = OpCopyObject %int %int_1
+ OpBranch %50
+
+ %30 = OpLabel
+ OpReturn
+
+ %50 = OpLabel ; dominated by %20, but %200 needs to be hoisted
+ %201 = OpFunctionCall %void %500 %200
+ OpReturn
+ OpFunctionEnd
+)";
+ auto p = parser(test::Assemble(assembly));
+ ASSERT_TRUE(p->BuildAndParseInternalModule()) << p->error() << assembly;
+ auto fe = p->function_emitter(100);
+ EXPECT_TRUE(fe.EmitBody()) << p->error();
+
+ const auto got = ToString(p->builder(), fe.ast_body());
+ const auto* expected = R"(VariableDeclStatement{
+ Variable{
+ x_200
+ none
+ undefined
+ __i32
+ }
+}
+If{
+ (
+ ScalarConstructor[not set]{true}
+ )
+ {
+ Assignment{
+ Identifier[not set]{x_200}
+ ScalarConstructor[not set]{1}
+ }
+ }
+}
+Else{
+ {
+ Return{}
+ }
+}
+Call[not set]{
+ Identifier[not set]{x_500}
+ (
+ Identifier[not set]{x_200}
+ )
+}
+Return{}
+)";
+ EXPECT_EQ(got, expected) << got;
+}
+
+TEST_F(SpvParserFunctionVarTest, DISABLED_EmitStatement_Hoist_UsedAsPtrArg) {
+ // Spawned from crbug.com/tint/804
+ // Blocked by crbug.com/tint/98: hoisting pointer types
+ const auto assembly = Preamble() + R"(
+
+ %fn_int = OpTypeFunction %void %ptr_int
+
+ %500 = OpFunction %void None %fn_int
+ %501 = OpFunctionParameter %ptr_int
+ %502 = OpLabel
+ OpReturn
+ OpFunctionEnd
+
+ %100 = OpFunction %void None %voidfn
+
+ %10 = OpLabel
+ %199 = OpVariable %ptr_int Function
+ OpSelectionMerge %50 None
+ OpBranchConditional %true %20 %30
+
+ %20 = OpLabel
+ %200 = OpCopyObject %ptr_int %199
+ OpBranch %50
+
+ %30 = OpLabel
+ OpReturn
+
+ %50 = OpLabel ; dominated by %20, but %200 needs to be hoisted
+ %201 = OpFunctionCall %void %500 %200
+ OpReturn
+ OpFunctionEnd
+)";
+ std::cout << assembly << std::endl;
+ auto p = parser(test::Assemble(assembly));
+ ASSERT_TRUE(p->BuildAndParseInternalModule()) << p->error() << assembly;
+ auto fe = p->function_emitter(100);
+ EXPECT_TRUE(fe.EmitBody()) << p->error();
+
+ const auto got = ToString(p->builder(), fe.ast_body());
+ const auto* expected = R"(VariableDeclStatement{
+ Variable{
+ x_200
+ none
+ undefined
+ __i32
+ }
+ Variable{
+ x_199
+ none
+ undefined
+ __i32
+ }
+}
+If{
+ (
+ ScalarConstructor[not set]{true}
+ )
+ {
+ Assignment{
+ Identifier[not set]{x_200}
+ ScalarConstructor[not set]{1}
+ }
+ }
+}
+Else{
+ {
+ Return{}
+ }
+}
+Call[not set]{
+ Identifier[not set]{x_500}
+ (
+ Identifier[not set]{x_200}
+ )
+}
+Return{}
+)";
+ EXPECT_EQ(got, expected) << got;
+}
+
} // namespace
} // namespace spirv
} // namespace reader