[spirv-reader] Add mergeless OpSwitch case

This is a bit pathological.

Bug: tint:3
Change-Id: I820d7d1bfd298a22be6c6014e7d4d00f1097759e
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/22740
Reviewed-by: dan sinclair <dsinclair@google.com>
This commit is contained in:
David Neto 2020-06-08 14:53:34 +00:00 committed by dan sinclair
parent 5d4c35f96e
commit dc8efd4095
1 changed files with 68 additions and 0 deletions

View File

@ -8589,6 +8589,74 @@ Return{}
)")) << ToString(fe.ast_body()); )")) << ToString(fe.ast_body());
} }
TEST_F(SpvParserTest,
DISABLED_Switch_NotAsSelectionHeader_NonDefaultBranchesAreContinue) {
// Adapted from SPIRV-Tools test MissingMergeOneUnseenTargetSwitchGood
auto* p = parser(test::Assemble(CommonTypes() + R"(
%100 = OpFunction %void None %voidfn
%entry = OpLabel
OpBranch %loop
%loop = OpLabel
OpLoopMerge %merge %cont None
OpBranchConditional %cond %merge %b1
; Here an OpSwitch is used with only one "unseen-so-far" target
; so it doesn't need an OpSelectionMerge.
; The %cont target can be implemented via "continue". So we can
; generate:
; if ((selector != 1) && (selector != 3)) { continue; }
%b1 = OpLabel
OpSwitch %selector %b2 0 %b2 1 %cont 2 %b2 3 %cont
%b2 = OpLabel ; the one unseen target
OpBranch %cont
%cont = OpLabel
OpBranchConditional %cond2 %merge %loop
%merge = 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"(unhandled case)"))
<< ToString(fe.ast_body());
}
TEST_F(SpvParserTest,
DISABLED_Switch_NotAsSelectionHeader_DefaultBranchIsContinue) {
// Adapted from SPIRV-Tools test MissingMergeOneUnseenTargetSwitchGood
auto* p = parser(test::Assemble(CommonTypes() + R"(
%100 = OpFunction %void None %voidfn
%entry = OpLabel
OpBranch %loop
%loop = OpLabel
OpLoopMerge %merge %cont None
OpBranchConditional %cond %merge %b1
; Here an OpSwitch is used with only one "unseen-so-far" target
; so it doesn't need an OpSelectionMerge.
; The %cont target can be implemented via "continue". So we can
; generate:
; if (!(selector == 0 || selector == 2)) {continue;}
%b1 = OpLabel
OpSwitch %selector %cont 0 %b2 1 %cont 2 %b2
%b2 = OpLabel ; the one unseen target
OpBranch %cont
%cont = OpLabel
OpBranchConditional %cond2 %merge %loop
%merge = 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"(unhandled case)"))
<< ToString(fe.ast_body());
}
} // namespace } // namespace
} // namespace spirv } // namespace spirv
} // namespace reader } // namespace reader