[spirv-reader] Check terminators are sane
Each basic block must have a terminator, and if the terminator branches to another block, that block must name a label in the same function. Bug: tint:3 Change-Id: If22bece6a8041fef362c02b05e4dfee999a3e5bf Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/20046 Reviewed-by: dan sinclair <dsinclair@google.com>
This commit is contained in:
parent
fd1526bd33
commit
795bebf1f2
|
@ -307,6 +307,12 @@ ast::type::Type* FunctionEmitter::GetVariableStoreType(
|
|||
}
|
||||
|
||||
bool FunctionEmitter::EmitBody() {
|
||||
RegisterBasicBlocks();
|
||||
|
||||
if (!TerminatorsAreSane()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ComputeBlockOrderAndPositions();
|
||||
|
||||
if (!EmitFunctionVariables()) {
|
||||
|
@ -318,11 +324,42 @@ bool FunctionEmitter::EmitBody() {
|
|||
return success();
|
||||
}
|
||||
|
||||
void FunctionEmitter::ComputeBlockOrderAndPositions() {
|
||||
void FunctionEmitter::RegisterBasicBlocks() {
|
||||
for (auto& block : function_) {
|
||||
block_info_[block.id()] = std::make_unique<BlockInfo>(block);
|
||||
}
|
||||
}
|
||||
|
||||
bool FunctionEmitter::TerminatorsAreSane() {
|
||||
if (failed()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto entry_id = function_.begin()->id();
|
||||
for (const auto& block : function_) {
|
||||
if (!block.terminator()) {
|
||||
return Fail() << "Block " << block.id() << " has no terminator";
|
||||
}
|
||||
}
|
||||
for (const auto& block : function_) {
|
||||
block.WhileEachSuccessorLabel(
|
||||
[this, &block, entry_id](const uint32_t succ_id) -> bool {
|
||||
if (succ_id == entry_id) {
|
||||
return Fail() << "Block " << block.id()
|
||||
<< " branches to function entry block " << entry_id;
|
||||
}
|
||||
if (!GetBlockInfo(succ_id)) {
|
||||
return Fail() << "Block " << block.id() << " in function "
|
||||
<< function_.DefInst().result_id() << " branches to "
|
||||
<< succ_id << " which is not a block in the function";
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
return success();
|
||||
}
|
||||
|
||||
void FunctionEmitter::ComputeBlockOrderAndPositions() {
|
||||
block_order_ = StructuredTraverser(function_).ReverseStructuredPostOrder();
|
||||
|
||||
for (uint32_t i = 0; i < block_order_.size(); ++i) {
|
||||
|
|
|
@ -90,8 +90,18 @@ class FunctionEmitter {
|
|||
/// @returns false if emission failed.
|
||||
bool EmitBody();
|
||||
|
||||
/// Records a mapping from block ID to a BlockInfo struct. Populates
|
||||
/// |block_info_|
|
||||
void RegisterBasicBlocks();
|
||||
|
||||
/// Verifies that terminators only branch to labels in the current function.
|
||||
/// Assumes basic blocks have been registered.
|
||||
/// @returns true if terminators are sane
|
||||
bool TerminatorsAreSane();
|
||||
|
||||
/// Determines the output order for the basic blocks in the function.
|
||||
/// Populates |block_order_| and the |pos| block info member.
|
||||
/// Assumes basic blocks have been registered.
|
||||
void ComputeBlockOrderAndPositions();
|
||||
|
||||
/// @returns the reverse structured post order of the basic blocks in
|
||||
|
|
|
@ -27,6 +27,7 @@ namespace spirv {
|
|||
namespace {
|
||||
|
||||
using ::testing::ElementsAre;
|
||||
using ::testing::Eq;
|
||||
|
||||
std::string CommonTypes() {
|
||||
return R"(
|
||||
|
@ -46,6 +47,245 @@ std::string CommonTypes() {
|
|||
)";
|
||||
}
|
||||
|
||||
TEST_F(SpvParserTest, TerminatorsAreSane_SingleBlock) {
|
||||
auto* p = parser(test::Assemble(CommonTypes() + R"(
|
||||
%100 = OpFunction %void None %voidfn
|
||||
|
||||
%42 = OpLabel
|
||||
OpReturn
|
||||
|
||||
OpFunctionEnd
|
||||
)"));
|
||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
|
||||
FunctionEmitter fe(p, *spirv_function(100));
|
||||
fe.RegisterBasicBlocks();
|
||||
EXPECT_TRUE(fe.TerminatorsAreSane());
|
||||
}
|
||||
|
||||
TEST_F(SpvParserTest, TerminatorsAreSane_Sequence) {
|
||||
auto* p = parser(test::Assemble(CommonTypes() + R"(
|
||||
%100 = OpFunction %void None %voidfn
|
||||
|
||||
%20 = OpLabel
|
||||
OpBranch %30
|
||||
|
||||
%30 = OpLabel
|
||||
OpReturn
|
||||
|
||||
OpFunctionEnd
|
||||
)"));
|
||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
|
||||
FunctionEmitter fe(p, *spirv_function(100));
|
||||
fe.RegisterBasicBlocks();
|
||||
EXPECT_TRUE(fe.TerminatorsAreSane()) << p->error();
|
||||
}
|
||||
|
||||
TEST_F(SpvParserTest, TerminatorsAreSane_If) {
|
||||
auto* p = parser(test::Assemble(CommonTypes() + R"(
|
||||
%100 = OpFunction %void None %voidfn
|
||||
|
||||
%20 = OpLabel
|
||||
OpSelectionMerge %99 None
|
||||
OpBranchConditional %cond %30 %40
|
||||
|
||||
%30 = OpLabel
|
||||
OpBranch %99
|
||||
|
||||
%40 = OpLabel
|
||||
OpBranch %99
|
||||
|
||||
%99 = OpLabel
|
||||
OpReturn
|
||||
|
||||
OpFunctionEnd
|
||||
)"));
|
||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
|
||||
FunctionEmitter fe(p, *spirv_function(100));
|
||||
fe.RegisterBasicBlocks();
|
||||
EXPECT_TRUE(fe.TerminatorsAreSane()) << p->error();
|
||||
}
|
||||
|
||||
TEST_F(SpvParserTest, TerminatorsAreSane_Switch) {
|
||||
auto* p = parser(test::Assemble(CommonTypes() + R"(
|
||||
%100 = OpFunction %void None %voidfn
|
||||
|
||||
%10 = OpLabel
|
||||
OpSelectionMerge %99 None
|
||||
OpSwitch %selector %80 20 %20 30 %30
|
||||
|
||||
%20 = OpLabel
|
||||
OpBranch %30 ; fall through
|
||||
|
||||
%30 = OpLabel
|
||||
OpBranch %99
|
||||
|
||||
%80 = OpLabel
|
||||
OpBranch %99
|
||||
|
||||
%99 = OpLabel
|
||||
OpReturn
|
||||
|
||||
OpFunctionEnd
|
||||
)"));
|
||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
|
||||
FunctionEmitter fe(p, *spirv_function(100));
|
||||
fe.RegisterBasicBlocks();
|
||||
EXPECT_TRUE(fe.TerminatorsAreSane());
|
||||
}
|
||||
|
||||
TEST_F(SpvParserTest, TerminatorsAreSane_Loop_SingleBlock) {
|
||||
auto* p = parser(test::Assemble(CommonTypes() + R"(
|
||||
%100 = OpFunction %void None %voidfn
|
||||
|
||||
%10 = OpLabel
|
||||
OpBranch %20
|
||||
|
||||
%20 = OpLabel
|
||||
OpLoopMerge %99 %20 None
|
||||
OpBranchConditional %cond %20 %99
|
||||
|
||||
%99 = OpLabel
|
||||
OpReturn
|
||||
|
||||
OpFunctionEnd
|
||||
)"));
|
||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
|
||||
FunctionEmitter fe(p, *spirv_function(100));
|
||||
fe.RegisterBasicBlocks();
|
||||
EXPECT_TRUE(fe.TerminatorsAreSane());
|
||||
}
|
||||
|
||||
TEST_F(SpvParserTest, TerminatorsAreSane_Loop_Simple) {
|
||||
auto* p = parser(test::Assemble(CommonTypes() + R"(
|
||||
%100 = OpFunction %void None %voidfn
|
||||
|
||||
%10 = OpLabel
|
||||
OpBranch %20
|
||||
|
||||
%20 = OpLabel
|
||||
OpLoopMerge %99 %40 None
|
||||
OpBranchConditional %cond %30 %99
|
||||
|
||||
%30 = OpLabel
|
||||
OpBranch %40
|
||||
|
||||
%40 = OpLabel
|
||||
OpBranch %20 ; back edge
|
||||
|
||||
%99 = OpLabel
|
||||
OpReturn
|
||||
|
||||
OpFunctionEnd
|
||||
)"));
|
||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
|
||||
FunctionEmitter fe(p, *spirv_function(100));
|
||||
fe.RegisterBasicBlocks();
|
||||
EXPECT_TRUE(fe.TerminatorsAreSane());
|
||||
}
|
||||
|
||||
TEST_F(SpvParserTest, TerminatorsAreSane_Kill) {
|
||||
auto* p = parser(test::Assemble(CommonTypes() + R"(
|
||||
%100 = OpFunction %void None %voidfn
|
||||
|
||||
%10 = OpLabel
|
||||
OpKill
|
||||
|
||||
OpFunctionEnd
|
||||
)"));
|
||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
|
||||
FunctionEmitter fe(p, *spirv_function(100));
|
||||
fe.RegisterBasicBlocks();
|
||||
EXPECT_TRUE(fe.TerminatorsAreSane());
|
||||
}
|
||||
|
||||
TEST_F(SpvParserTest, TerminatorsAreSane_Unreachable) {
|
||||
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));
|
||||
fe.RegisterBasicBlocks();
|
||||
EXPECT_TRUE(fe.TerminatorsAreSane());
|
||||
}
|
||||
|
||||
TEST_F(SpvParserTest, TerminatorsAreSane_MissingTerminator) {
|
||||
auto* p = parser(test::Assemble(CommonTypes() + R"(
|
||||
%100 = OpFunction %void None %voidfn
|
||||
|
||||
%10 = OpLabel
|
||||
|
||||
OpFunctionEnd
|
||||
)"));
|
||||
// The SPIRV-Tools internal representation rejects this case earlier.
|
||||
EXPECT_FALSE(p->BuildAndParseInternalModuleExceptFunctions());
|
||||
}
|
||||
|
||||
TEST_F(SpvParserTest, TerminatorsAreSane_DisallowLoopToEntryBlock) {
|
||||
auto* p = parser(test::Assemble(CommonTypes() + R"(
|
||||
%100 = OpFunction %void None %voidfn
|
||||
|
||||
%10 = OpLabel
|
||||
OpBranch %20
|
||||
|
||||
%20 = OpLabel
|
||||
OpBranch %10 ; not allowed
|
||||
|
||||
OpFunctionEnd
|
||||
)"));
|
||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
|
||||
FunctionEmitter fe(p, *spirv_function(100));
|
||||
fe.RegisterBasicBlocks();
|
||||
EXPECT_FALSE(fe.TerminatorsAreSane());
|
||||
EXPECT_THAT(p->error(), Eq("Block 20 branches to function entry block 10"));
|
||||
}
|
||||
|
||||
TEST_F(SpvParserTest, TerminatorsAreSane_DisallowNonBlock) {
|
||||
auto* p = parser(test::Assemble(CommonTypes() + R"(
|
||||
%100 = OpFunction %void None %voidfn
|
||||
|
||||
%10 = OpLabel
|
||||
OpBranch %void ; definitely wrong
|
||||
|
||||
OpFunctionEnd
|
||||
)"));
|
||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
|
||||
FunctionEmitter fe(p, *spirv_function(100));
|
||||
fe.RegisterBasicBlocks();
|
||||
EXPECT_FALSE(fe.TerminatorsAreSane());
|
||||
EXPECT_THAT(p->error(), Eq("Block 10 in function 100 branches to 1 which is "
|
||||
"not a block in the function"));
|
||||
}
|
||||
|
||||
TEST_F(SpvParserTest, TerminatorsAreSane_DisallowBlockInDifferentFunction) {
|
||||
auto* p = parser(test::Assemble(CommonTypes() + R"(
|
||||
%100 = OpFunction %void None %voidfn
|
||||
|
||||
%10 = OpLabel
|
||||
OpBranch %210
|
||||
|
||||
OpFunctionEnd
|
||||
|
||||
|
||||
%200 = OpFunction %void None %voidfn
|
||||
|
||||
%210 = OpLabel
|
||||
OpReturn
|
||||
|
||||
OpFunctionEnd
|
||||
)"));
|
||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
|
||||
FunctionEmitter fe(p, *spirv_function(100));
|
||||
fe.RegisterBasicBlocks();
|
||||
EXPECT_FALSE(fe.TerminatorsAreSane());
|
||||
EXPECT_THAT(p->error(), Eq("Block 10 in function 100 branches to 210 which "
|
||||
"is not a block in the function"));
|
||||
}
|
||||
|
||||
TEST_F(SpvParserTest, ComputeBlockOrder_OneBlock) {
|
||||
auto* p = parser(test::Assemble(CommonTypes() + R"(
|
||||
%100 = OpFunction %void None %voidfn
|
||||
|
@ -57,6 +297,7 @@ TEST_F(SpvParserTest, ComputeBlockOrder_OneBlock) {
|
|||
)"));
|
||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
|
||||
FunctionEmitter fe(p, *spirv_function(100));
|
||||
fe.RegisterBasicBlocks();
|
||||
fe.ComputeBlockOrderAndPositions();
|
||||
|
||||
EXPECT_THAT(fe.block_order(), ElementsAre(42));
|
||||
|
@ -79,6 +320,7 @@ TEST_F(SpvParserTest, ComputeBlockOrder_IgnoreStaticalyUnreachable) {
|
|||
)"));
|
||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
|
||||
FunctionEmitter fe(p, *spirv_function(100));
|
||||
fe.RegisterBasicBlocks();
|
||||
fe.ComputeBlockOrderAndPositions();
|
||||
|
||||
EXPECT_THAT(fe.block_order(), ElementsAre(10, 20));
|
||||
|
@ -101,6 +343,7 @@ TEST_F(SpvParserTest, ComputeBlockOrder_KillIsDeadEnd) {
|
|||
)"));
|
||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
|
||||
FunctionEmitter fe(p, *spirv_function(100));
|
||||
fe.RegisterBasicBlocks();
|
||||
fe.ComputeBlockOrderAndPositions();
|
||||
|
||||
EXPECT_THAT(fe.block_order(), ElementsAre(10, 20));
|
||||
|
@ -123,6 +366,7 @@ TEST_F(SpvParserTest, ComputeBlockOrder_UnreachableIsDeadEnd) {
|
|||
)"));
|
||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
|
||||
FunctionEmitter fe(p, *spirv_function(100));
|
||||
fe.RegisterBasicBlocks();
|
||||
fe.ComputeBlockOrderAndPositions();
|
||||
|
||||
EXPECT_THAT(fe.block_order(), ElementsAre(10, 20));
|
||||
|
@ -145,6 +389,7 @@ TEST_F(SpvParserTest, ComputeBlockOrder_ReorderSequence) {
|
|||
)"));
|
||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
|
||||
FunctionEmitter fe(p, *spirv_function(100));
|
||||
fe.RegisterBasicBlocks();
|
||||
fe.ComputeBlockOrderAndPositions();
|
||||
|
||||
EXPECT_THAT(fe.block_order(), ElementsAre(10, 20, 30));
|
||||
|
@ -168,6 +413,7 @@ TEST_F(SpvParserTest, ComputeBlockOrder_DupConditionalBranch) {
|
|||
)"));
|
||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
|
||||
FunctionEmitter fe(p, *spirv_function(100));
|
||||
fe.RegisterBasicBlocks();
|
||||
fe.ComputeBlockOrderAndPositions();
|
||||
|
||||
EXPECT_THAT(fe.block_order(), ElementsAre(10, 20, 99));
|
||||
|
@ -194,6 +440,7 @@ TEST_F(SpvParserTest, ComputeBlockOrder_RespectConditionalBranchOrder) {
|
|||
)"));
|
||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
|
||||
FunctionEmitter fe(p, *spirv_function(100));
|
||||
fe.RegisterBasicBlocks();
|
||||
fe.ComputeBlockOrderAndPositions();
|
||||
|
||||
EXPECT_THAT(fe.block_order(), ElementsAre(10, 20, 30, 99));
|
||||
|
@ -217,6 +464,7 @@ TEST_F(SpvParserTest, ComputeBlockOrder_TrueOnlyBranch) {
|
|||
)"));
|
||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
|
||||
FunctionEmitter fe(p, *spirv_function(100));
|
||||
fe.RegisterBasicBlocks();
|
||||
fe.ComputeBlockOrderAndPositions();
|
||||
|
||||
EXPECT_THAT(fe.block_order(), ElementsAre(10, 20, 99));
|
||||
|
@ -240,6 +488,7 @@ TEST_F(SpvParserTest, ComputeBlockOrder_FalseOnlyBranch) {
|
|||
)"));
|
||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
|
||||
FunctionEmitter fe(p, *spirv_function(100));
|
||||
fe.RegisterBasicBlocks();
|
||||
fe.ComputeBlockOrderAndPositions();
|
||||
|
||||
EXPECT_THAT(fe.block_order(), ElementsAre(10, 20, 99));
|
||||
|
@ -266,6 +515,7 @@ TEST_F(SpvParserTest, ComputeBlockOrder_SwitchOrderNaturallyReversed) {
|
|||
)"));
|
||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
|
||||
FunctionEmitter fe(p, *spirv_function(100));
|
||||
fe.RegisterBasicBlocks();
|
||||
fe.ComputeBlockOrderAndPositions();
|
||||
|
||||
EXPECT_THAT(fe.block_order(), ElementsAre(10, 30, 20, 99));
|
||||
|
@ -296,6 +546,7 @@ TEST_F(SpvParserTest,
|
|||
)"));
|
||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
|
||||
FunctionEmitter fe(p, *spirv_function(100));
|
||||
fe.RegisterBasicBlocks();
|
||||
fe.ComputeBlockOrderAndPositions();
|
||||
|
||||
EXPECT_THAT(fe.block_order(), ElementsAre(10, 30, 20, 80, 99));
|
||||
|
@ -326,6 +577,7 @@ TEST_F(SpvParserTest,
|
|||
)"));
|
||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
|
||||
FunctionEmitter fe(p, *spirv_function(100));
|
||||
fe.RegisterBasicBlocks();
|
||||
fe.ComputeBlockOrderAndPositions();
|
||||
|
||||
EXPECT_THAT(fe.block_order(), ElementsAre(10, 40, 20, 30, 99));
|
||||
|
@ -359,6 +611,7 @@ TEST_F(SpvParserTest, ComputeBlockOrder_RespectSwitchCaseFallthrough) {
|
|||
auto* p = parser(test::Assemble(assembly));
|
||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
|
||||
FunctionEmitter fe(p, *spirv_function(100));
|
||||
fe.RegisterBasicBlocks();
|
||||
fe.ComputeBlockOrderAndPositions();
|
||||
|
||||
EXPECT_THAT(fe.block_order(), ElementsAre(10, 30, 50, 20, 40, 99))
|
||||
|
@ -394,6 +647,7 @@ TEST_F(SpvParserTest,
|
|||
auto* p = parser(test::Assemble(assembly));
|
||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
|
||||
FunctionEmitter fe(p, *spirv_function(100));
|
||||
fe.RegisterBasicBlocks();
|
||||
fe.ComputeBlockOrderAndPositions();
|
||||
|
||||
EXPECT_THAT(fe.block_order(), ElementsAre(10, 20, 80, 30, 40, 99))
|
||||
|
@ -426,6 +680,7 @@ TEST_F(SpvParserTest,
|
|||
auto* p = parser(test::Assemble(assembly));
|
||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
|
||||
FunctionEmitter fe(p, *spirv_function(100));
|
||||
fe.RegisterBasicBlocks();
|
||||
fe.ComputeBlockOrderAndPositions();
|
||||
|
||||
EXPECT_THAT(fe.block_order(), ElementsAre(10, 20, 80, 30, 99)) << assembly;
|
||||
|
@ -462,6 +717,7 @@ TEST_F(SpvParserTest,
|
|||
auto* p = parser(test::Assemble(assembly));
|
||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
|
||||
FunctionEmitter fe(p, *spirv_function(100));
|
||||
fe.RegisterBasicBlocks();
|
||||
fe.ComputeBlockOrderAndPositions();
|
||||
|
||||
EXPECT_THAT(fe.block_order(), ElementsAre(10, 50, 40, 20, 30, 99))
|
||||
|
@ -503,6 +759,7 @@ TEST_F(SpvParserTest,
|
|||
auto* p = parser(test::Assemble(assembly));
|
||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
|
||||
FunctionEmitter fe(p, *spirv_function(100));
|
||||
fe.RegisterBasicBlocks();
|
||||
fe.ComputeBlockOrderAndPositions();
|
||||
|
||||
EXPECT_THAT(fe.block_order(), ElementsAre(10, 30, 50, 70, 20, 40, 60, 99))
|
||||
|
@ -552,6 +809,7 @@ TEST_F(SpvParserTest,
|
|||
auto* p = parser(test::Assemble(assembly));
|
||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
|
||||
FunctionEmitter fe(p, *spirv_function(100));
|
||||
fe.RegisterBasicBlocks();
|
||||
fe.ComputeBlockOrderAndPositions();
|
||||
|
||||
EXPECT_THAT(fe.block_order(),
|
||||
|
@ -602,6 +860,7 @@ TEST_F(SpvParserTest,
|
|||
auto* p = parser(test::Assemble(assembly));
|
||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
|
||||
FunctionEmitter fe(p, *spirv_function(100));
|
||||
fe.RegisterBasicBlocks();
|
||||
fe.ComputeBlockOrderAndPositions();
|
||||
|
||||
EXPECT_THAT(fe.block_order(),
|
||||
|
@ -652,6 +911,7 @@ TEST_F(SpvParserTest,
|
|||
auto* p = parser(test::Assemble(assembly));
|
||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
|
||||
FunctionEmitter fe(p, *spirv_function(100));
|
||||
fe.RegisterBasicBlocks();
|
||||
fe.ComputeBlockOrderAndPositions();
|
||||
|
||||
EXPECT_THAT(fe.block_order(),
|
||||
|
@ -696,6 +956,7 @@ TEST_F(SpvParserTest,
|
|||
auto* p = parser(test::Assemble(assembly));
|
||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
|
||||
FunctionEmitter fe(p, *spirv_function(100));
|
||||
fe.RegisterBasicBlocks();
|
||||
fe.ComputeBlockOrderAndPositions();
|
||||
|
||||
EXPECT_THAT(fe.block_order(), ElementsAre(10, 20, 40, 49, 50, 60, 79, 99))
|
||||
|
@ -720,6 +981,7 @@ TEST_F(SpvParserTest, ComputeBlockOrder_Loop_SingleBlock_Simple) {
|
|||
auto* p = parser(test::Assemble(assembly));
|
||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
|
||||
FunctionEmitter fe(p, *spirv_function(100));
|
||||
fe.RegisterBasicBlocks();
|
||||
fe.ComputeBlockOrderAndPositions();
|
||||
|
||||
EXPECT_THAT(fe.block_order(), ElementsAre(10, 20, 99)) << assembly;
|
||||
|
@ -743,6 +1005,7 @@ TEST_F(SpvParserTest, ComputeBlockOrder_Loop_SingleBlock_Infinite) {
|
|||
auto* p = parser(test::Assemble(assembly));
|
||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
|
||||
FunctionEmitter fe(p, *spirv_function(100));
|
||||
fe.RegisterBasicBlocks();
|
||||
fe.ComputeBlockOrderAndPositions();
|
||||
|
||||
EXPECT_THAT(fe.block_order(), ElementsAre(10, 20, 99)) << assembly;
|
||||
|
@ -766,6 +1029,7 @@ TEST_F(SpvParserTest, ComputeBlockOrder_Loop_SingleBlock_DupInfinite) {
|
|||
auto* p = parser(test::Assemble(assembly));
|
||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
|
||||
FunctionEmitter fe(p, *spirv_function(100));
|
||||
fe.RegisterBasicBlocks();
|
||||
fe.ComputeBlockOrderAndPositions();
|
||||
|
||||
EXPECT_THAT(fe.block_order(), ElementsAre(10, 20, 99)) << assembly;
|
||||
|
@ -794,6 +1058,7 @@ TEST_F(SpvParserTest, ComputeBlockOrder_Loop_HeaderHasBreakIf) {
|
|||
auto* p = parser(test::Assemble(assembly));
|
||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
|
||||
FunctionEmitter fe(p, *spirv_function(100));
|
||||
fe.RegisterBasicBlocks();
|
||||
fe.ComputeBlockOrderAndPositions();
|
||||
|
||||
EXPECT_THAT(fe.block_order(), ElementsAre(10, 20, 30, 50, 99)) << assembly;
|
||||
|
@ -822,6 +1087,7 @@ TEST_F(SpvParserTest, ComputeBlockOrder_Loop_HeaderHasBreakUnless) {
|
|||
auto* p = parser(test::Assemble(assembly));
|
||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
|
||||
FunctionEmitter fe(p, *spirv_function(100));
|
||||
fe.RegisterBasicBlocks();
|
||||
fe.ComputeBlockOrderAndPositions();
|
||||
|
||||
EXPECT_THAT(fe.block_order(), ElementsAre(10, 20, 30, 50, 99)) << assembly;
|
||||
|
@ -850,6 +1116,7 @@ TEST_F(SpvParserTest, ComputeBlockOrder_Loop_BodyHasBreak) {
|
|||
auto* p = parser(test::Assemble(assembly));
|
||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
|
||||
FunctionEmitter fe(p, *spirv_function(100));
|
||||
fe.RegisterBasicBlocks();
|
||||
fe.ComputeBlockOrderAndPositions();
|
||||
|
||||
EXPECT_THAT(fe.block_order(), ElementsAre(10, 20, 30, 50, 99)) << assembly;
|
||||
|
@ -881,6 +1148,7 @@ TEST_F(SpvParserTest, ComputeBlockOrder_Loop_BodyHasBreakIf) {
|
|||
auto* p = parser(test::Assemble(assembly));
|
||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
|
||||
FunctionEmitter fe(p, *spirv_function(100));
|
||||
fe.RegisterBasicBlocks();
|
||||
fe.ComputeBlockOrderAndPositions();
|
||||
|
||||
EXPECT_THAT(fe.block_order(), ElementsAre(10, 20, 30, 40, 50, 99))
|
||||
|
@ -913,6 +1181,7 @@ TEST_F(SpvParserTest, ComputeBlockOrder_Loop_BodyHasBreakUnless) {
|
|||
auto* p = parser(test::Assemble(assembly));
|
||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
|
||||
FunctionEmitter fe(p, *spirv_function(100));
|
||||
fe.RegisterBasicBlocks();
|
||||
fe.ComputeBlockOrderAndPositions();
|
||||
|
||||
EXPECT_THAT(fe.block_order(), ElementsAre(10, 20, 30, 40, 50, 99))
|
||||
|
@ -952,6 +1221,7 @@ TEST_F(SpvParserTest, ComputeBlockOrder_Loop_Body_If) {
|
|||
auto* p = parser(test::Assemble(assembly));
|
||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
|
||||
FunctionEmitter fe(p, *spirv_function(100));
|
||||
fe.RegisterBasicBlocks();
|
||||
fe.ComputeBlockOrderAndPositions();
|
||||
|
||||
EXPECT_THAT(fe.block_order(), ElementsAre(10, 20, 30, 40, 45, 49, 50, 99))
|
||||
|
@ -988,6 +1258,7 @@ TEST_F(SpvParserTest, ComputeBlockOrder_Loop_Body_If_Break) {
|
|||
auto* p = parser(test::Assemble(assembly));
|
||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
|
||||
FunctionEmitter fe(p, *spirv_function(100));
|
||||
fe.RegisterBasicBlocks();
|
||||
fe.ComputeBlockOrderAndPositions();
|
||||
|
||||
EXPECT_THAT(fe.block_order(), ElementsAre(10, 20, 30, 40, 49, 50, 99))
|
||||
|
@ -1020,6 +1291,7 @@ TEST_F(SpvParserTest, ComputeBlockOrder_Loop_BodyHasContinueIf) {
|
|||
auto* p = parser(test::Assemble(assembly));
|
||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
|
||||
FunctionEmitter fe(p, *spirv_function(100));
|
||||
fe.RegisterBasicBlocks();
|
||||
fe.ComputeBlockOrderAndPositions();
|
||||
|
||||
EXPECT_THAT(fe.block_order(), ElementsAre(10, 20, 30, 40, 50, 99))
|
||||
|
@ -1052,6 +1324,7 @@ TEST_F(SpvParserTest, ComputeBlockOrder_Loop_BodyHasContinueUnless) {
|
|||
auto* p = parser(test::Assemble(assembly));
|
||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
|
||||
FunctionEmitter fe(p, *spirv_function(100));
|
||||
fe.RegisterBasicBlocks();
|
||||
fe.ComputeBlockOrderAndPositions();
|
||||
|
||||
EXPECT_THAT(fe.block_order(), ElementsAre(10, 20, 30, 40, 50, 99))
|
||||
|
@ -1088,6 +1361,7 @@ TEST_F(SpvParserTest, ComputeBlockOrder_Loop_Body_If_Continue) {
|
|||
auto* p = parser(test::Assemble(assembly));
|
||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
|
||||
FunctionEmitter fe(p, *spirv_function(100));
|
||||
fe.RegisterBasicBlocks();
|
||||
fe.ComputeBlockOrderAndPositions();
|
||||
|
||||
EXPECT_THAT(fe.block_order(), ElementsAre(10, 20, 30, 40, 49, 50, 99))
|
||||
|
@ -1127,6 +1401,7 @@ TEST_F(SpvParserTest, ComputeBlockOrder_Loop_Body_Switch) {
|
|||
auto* p = parser(test::Assemble(assembly));
|
||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
|
||||
FunctionEmitter fe(p, *spirv_function(100));
|
||||
fe.RegisterBasicBlocks();
|
||||
fe.ComputeBlockOrderAndPositions();
|
||||
|
||||
EXPECT_THAT(fe.block_order(), ElementsAre(10, 20, 30, 45, 40, 49, 50, 99))
|
||||
|
@ -1168,6 +1443,7 @@ TEST_F(SpvParserTest, ComputeBlockOrder_Loop_Body_Switch_CaseBreaks) {
|
|||
auto* p = parser(test::Assemble(assembly));
|
||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
|
||||
FunctionEmitter fe(p, *spirv_function(100));
|
||||
fe.RegisterBasicBlocks();
|
||||
fe.ComputeBlockOrderAndPositions();
|
||||
|
||||
EXPECT_THAT(fe.block_order(), ElementsAre(10, 20, 30, 45, 40, 49, 50, 99))
|
||||
|
@ -1207,6 +1483,7 @@ TEST_F(SpvParserTest, ComputeBlockOrder_Loop_Body_Switch_CaseContinues) {
|
|||
auto* p = parser(test::Assemble(assembly));
|
||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
|
||||
FunctionEmitter fe(p, *spirv_function(100));
|
||||
fe.RegisterBasicBlocks();
|
||||
fe.ComputeBlockOrderAndPositions();
|
||||
|
||||
EXPECT_THAT(fe.block_order(), ElementsAre(10, 20, 30, 45, 40, 49, 50, 99))
|
||||
|
@ -1239,6 +1516,7 @@ TEST_F(SpvParserTest, ComputeBlockOrder_Loop_BodyHasSwitchContinueBreak) {
|
|||
auto* p = parser(test::Assemble(assembly));
|
||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
|
||||
FunctionEmitter fe(p, *spirv_function(100));
|
||||
fe.RegisterBasicBlocks();
|
||||
fe.ComputeBlockOrderAndPositions();
|
||||
|
||||
EXPECT_THAT(fe.block_order(), ElementsAre(10, 20, 30, 50, 99));
|
||||
|
@ -1270,6 +1548,7 @@ TEST_F(SpvParserTest, ComputeBlockOrder_Loop_Continue_Sequence) {
|
|||
auto* p = parser(test::Assemble(assembly));
|
||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
|
||||
FunctionEmitter fe(p, *spirv_function(100));
|
||||
fe.RegisterBasicBlocks();
|
||||
fe.ComputeBlockOrderAndPositions();
|
||||
|
||||
EXPECT_THAT(fe.block_order(), ElementsAre(10, 20, 30, 50, 60, 99));
|
||||
|
@ -1308,6 +1587,7 @@ TEST_F(SpvParserTest, ComputeBlockOrder_Loop_Continue_ContainsIf) {
|
|||
auto* p = parser(test::Assemble(assembly));
|
||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
|
||||
FunctionEmitter fe(p, *spirv_function(100));
|
||||
fe.RegisterBasicBlocks();
|
||||
fe.ComputeBlockOrderAndPositions();
|
||||
|
||||
EXPECT_THAT(fe.block_order(), ElementsAre(10, 20, 30, 50, 60, 70, 89, 99));
|
||||
|
@ -1336,6 +1616,7 @@ TEST_F(SpvParserTest, ComputeBlockOrder_Loop_Continue_HasBreakIf) {
|
|||
auto* p = parser(test::Assemble(assembly));
|
||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
|
||||
FunctionEmitter fe(p, *spirv_function(100));
|
||||
fe.RegisterBasicBlocks();
|
||||
fe.ComputeBlockOrderAndPositions();
|
||||
|
||||
EXPECT_THAT(fe.block_order(), ElementsAre(10, 20, 30, 50, 99));
|
||||
|
@ -1364,6 +1645,7 @@ TEST_F(SpvParserTest, ComputeBlockOrder_Loop_Continue_HasBreakUnless) {
|
|||
auto* p = parser(test::Assemble(assembly));
|
||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
|
||||
FunctionEmitter fe(p, *spirv_function(100));
|
||||
fe.RegisterBasicBlocks();
|
||||
fe.ComputeBlockOrderAndPositions();
|
||||
|
||||
EXPECT_THAT(fe.block_order(), ElementsAre(10, 20, 30, 50, 99));
|
||||
|
@ -1392,6 +1674,7 @@ TEST_F(SpvParserTest, ComputeBlockOrder_Loop_Continue_SwitchBreak) {
|
|||
auto* p = parser(test::Assemble(assembly));
|
||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
|
||||
FunctionEmitter fe(p, *spirv_function(100));
|
||||
fe.RegisterBasicBlocks();
|
||||
fe.ComputeBlockOrderAndPositions();
|
||||
|
||||
EXPECT_THAT(fe.block_order(), ElementsAre(10, 20, 30, 50, 99));
|
||||
|
@ -1433,6 +1716,7 @@ TEST_F(SpvParserTest, ComputeBlockOrder_Loop_Loop) {
|
|||
auto* p = parser(test::Assemble(assembly));
|
||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
|
||||
FunctionEmitter fe(p, *spirv_function(100));
|
||||
fe.RegisterBasicBlocks();
|
||||
fe.ComputeBlockOrderAndPositions();
|
||||
|
||||
EXPECT_THAT(fe.block_order(),
|
||||
|
@ -1475,6 +1759,7 @@ TEST_F(SpvParserTest, ComputeBlockOrder_Loop_Loop_InnerBreak) {
|
|||
auto* p = parser(test::Assemble(assembly));
|
||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
|
||||
FunctionEmitter fe(p, *spirv_function(100));
|
||||
fe.RegisterBasicBlocks();
|
||||
fe.ComputeBlockOrderAndPositions();
|
||||
|
||||
EXPECT_THAT(fe.block_order(),
|
||||
|
@ -1517,6 +1802,7 @@ TEST_F(SpvParserTest, ComputeBlockOrder_Loop_Loop_InnerContinue) {
|
|||
auto* p = parser(test::Assemble(assembly));
|
||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
|
||||
FunctionEmitter fe(p, *spirv_function(100));
|
||||
fe.RegisterBasicBlocks();
|
||||
fe.ComputeBlockOrderAndPositions();
|
||||
|
||||
EXPECT_THAT(fe.block_order(),
|
||||
|
@ -1559,6 +1845,7 @@ TEST_F(SpvParserTest, ComputeBlockOrder_Loop_Loop_InnerContinueBreaks) {
|
|||
auto* p = parser(test::Assemble(assembly));
|
||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
|
||||
FunctionEmitter fe(p, *spirv_function(100));
|
||||
fe.RegisterBasicBlocks();
|
||||
fe.ComputeBlockOrderAndPositions();
|
||||
|
||||
EXPECT_THAT(fe.block_order(),
|
||||
|
@ -1601,6 +1888,7 @@ TEST_F(SpvParserTest, ComputeBlockOrder_Loop_Loop_InnerContinueContinues) {
|
|||
auto* p = parser(test::Assemble(assembly));
|
||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
|
||||
FunctionEmitter fe(p, *spirv_function(100));
|
||||
fe.RegisterBasicBlocks();
|
||||
fe.ComputeBlockOrderAndPositions();
|
||||
|
||||
EXPECT_THAT(fe.block_order(),
|
||||
|
@ -1648,6 +1936,7 @@ TEST_F(SpvParserTest, ComputeBlockOrder_Loop_Loop_SwitchBackedgeBreakContinue) {
|
|||
auto* p = parser(test::Assemble(assembly));
|
||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
|
||||
FunctionEmitter fe(p, *spirv_function(100));
|
||||
fe.RegisterBasicBlocks();
|
||||
fe.ComputeBlockOrderAndPositions();
|
||||
|
||||
EXPECT_THAT(fe.block_order(),
|
||||
|
|
Loading…
Reference in New Issue