mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-06-06 22:53:35 +00:00
[spirv-reader] Support unreachable, as a return
Bug: tint:3 Change-Id: Ia1384f84f7851a9e155c1536a624213ef51ee0a1 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/22521 Reviewed-by: dan sinclair <dsinclair@google.com>
This commit is contained in:
parent
91332dc475
commit
1649dfadd7
@ -1772,10 +1772,24 @@ bool FunctionEmitter::EmitNormalTerminator(const BlockInfo& block_info) {
|
|||||||
// TODO(dneto): https://github.com/gpuweb/gpuweb/issues/676
|
// TODO(dneto): https://github.com/gpuweb/gpuweb/issues/676
|
||||||
AddStatement(std::make_unique<ast::KillStatement>());
|
AddStatement(std::make_unique<ast::KillStatement>());
|
||||||
return true;
|
return true;
|
||||||
|
case SpvOpUnreachable:
|
||||||
|
// Translate as if it's a return. This avoids the problem where WGSL
|
||||||
|
// requires a return statement at the end of the function body.
|
||||||
|
{
|
||||||
|
const auto* result_type = type_mgr_->GetType(function_.type_id());
|
||||||
|
if (result_type->AsVoid() != nullptr) {
|
||||||
|
AddStatement(std::make_unique<ast::ReturnStatement>());
|
||||||
|
} else {
|
||||||
|
auto* ast_type = parser_impl_.ConvertType(function_.type_id());
|
||||||
|
AddStatement(std::make_unique<ast::ReturnStatement>(
|
||||||
|
parser_impl_.MakeNullValue(ast_type)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// TODO(dneto): emit fallthrough, break, continue, kill
|
// TODO(dneto): emit fallthrough, break, continue
|
||||||
return success();
|
return success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7947,6 +7947,121 @@ Kill{}
|
|||||||
)")) << ToString(fe.ast_body());
|
)")) << ToString(fe.ast_body());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(SpvParserTest, EmitBody_Unreachable_TopLevel) {
|
||||||
|
auto* p = parser(test::Assemble(CommonTypes() + R"(
|
||||||
|
%100 = OpFunction %void None %voidfn
|
||||||
|
|
||||||
|
%10 = OpLabel
|
||||||
|
OpUnreachable
|
||||||
|
|
||||||
|
OpFunctionEnd
|
||||||
|
)"));
|
||||||
|
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
|
||||||
|
FunctionEmitter fe(p, *spirv_function(100));
|
||||||
|
EXPECT_TRUE(fe.EmitBody()) << p->error();
|
||||||
|
|
||||||
|
EXPECT_THAT(ToString(fe.ast_body()), Eq(R"(Return{}
|
||||||
|
)")) << ToString(fe.ast_body());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SpvParserTest, EmitBody_Unreachable_InsideIf) {
|
||||||
|
auto* p = parser(test::Assemble(CommonTypes() + R"(
|
||||||
|
%100 = OpFunction %void None %voidfn
|
||||||
|
|
||||||
|
%10 = OpLabel
|
||||||
|
OpSelectionMerge %99 None
|
||||||
|
OpBranchConditional %cond %20 %99
|
||||||
|
|
||||||
|
%20 = OpLabel
|
||||||
|
OpUnreachable
|
||||||
|
|
||||||
|
%99 = OpLabel
|
||||||
|
OpReturn
|
||||||
|
|
||||||
|
OpFunctionEnd
|
||||||
|
)"));
|
||||||
|
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
|
||||||
|
FunctionEmitter fe(p, *spirv_function(100));
|
||||||
|
EXPECT_TRUE(fe.EmitBody()) << p->error();
|
||||||
|
|
||||||
|
EXPECT_THAT(ToString(fe.ast_body()), Eq(R"(If{
|
||||||
|
(
|
||||||
|
ScalarConstructor{false}
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Return{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Else{
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Return{}
|
||||||
|
)")) << ToString(fe.ast_body());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SpvParserTest, EmitBody_Unreachable_InsideLoop) {
|
||||||
|
auto* p = parser(test::Assemble(CommonTypes() + R"(
|
||||||
|
%100 = OpFunction %void None %voidfn
|
||||||
|
|
||||||
|
%10 = OpLabel
|
||||||
|
OpBranch %20
|
||||||
|
|
||||||
|
%20 = OpLabel
|
||||||
|
OpLoopMerge %99 %80 None
|
||||||
|
OpBranchConditional %cond %30 %30
|
||||||
|
|
||||||
|
%30 = OpLabel
|
||||||
|
OpUnreachable
|
||||||
|
|
||||||
|
%80 = OpLabel
|
||||||
|
OpBranch %20
|
||||||
|
|
||||||
|
%99 = OpLabel
|
||||||
|
OpReturn
|
||||||
|
|
||||||
|
OpFunctionEnd
|
||||||
|
)"));
|
||||||
|
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
|
||||||
|
FunctionEmitter fe(p, *spirv_function(100));
|
||||||
|
EXPECT_TRUE(fe.EmitBody()) << p->error();
|
||||||
|
|
||||||
|
EXPECT_THAT(ToString(fe.ast_body()), Eq(R"(Loop{
|
||||||
|
Return{}
|
||||||
|
}
|
||||||
|
Return{}
|
||||||
|
)")) << ToString(fe.ast_body());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SpvParserTest, EmitBody_Unreachable_InNonVoidFunction) {
|
||||||
|
auto* p = parser(test::Assemble(CommonTypes() + R"(
|
||||||
|
%200 = OpFunction %uint None %uintfn
|
||||||
|
|
||||||
|
%210 = OpLabel
|
||||||
|
OpUnreachable
|
||||||
|
|
||||||
|
OpFunctionEnd
|
||||||
|
|
||||||
|
%100 = OpFunction %void None %voidfn
|
||||||
|
|
||||||
|
%10 = OpLabel
|
||||||
|
%11 = OpFunctionCall %uint %200
|
||||||
|
OpReturn
|
||||||
|
|
||||||
|
OpFunctionEnd
|
||||||
|
)"));
|
||||||
|
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
|
||||||
|
FunctionEmitter fe(p, *spirv_function(200));
|
||||||
|
EXPECT_TRUE(fe.EmitBody()) << p->error();
|
||||||
|
|
||||||
|
EXPECT_THAT(ToString(fe.ast_body()), Eq(R"(Return{
|
||||||
|
{
|
||||||
|
ScalarConstructor{0}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)")) << ToString(fe.ast_body());
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
} // namespace spirv
|
} // namespace spirv
|
||||||
} // namespace reader
|
} // namespace reader
|
||||||
|
Loading…
x
Reference in New Issue
Block a user