diff options
Diffstat (limited to 'test/val/val_cfg_test.cpp')
-rw-r--r-- | test/val/val_cfg_test.cpp | 191 |
1 files changed, 76 insertions, 115 deletions
diff --git a/test/val/val_cfg_test.cpp b/test/val/val_cfg_test.cpp index 76477468..ede51a9e 100644 --- a/test/val/val_cfg_test.cpp +++ b/test/val/val_cfg_test.cpp @@ -637,41 +637,6 @@ TEST_P(ValidateCFG, BranchToBlockInOtherFunctionBad) { " %Main = OpFunction %void None %9\n")); } -TEST_P(ValidateCFG, HeaderDoesntDominatesMergeBad) { - bool is_shader = GetParam() == SpvCapabilityShader; - Block entry("entry"); - Block head("head", SpvOpBranchConditional); - Block f("f"); - Block merge("merge", SpvOpReturn); - - head.SetBody("%cond = OpSLessThan %boolt %one %two\n"); - - if (is_shader) head.AppendBody("OpSelectionMerge %merge None\n"); - - std::string str = GetDefaultHeader(GetParam()) + - nameOps("head", "merge", std::make_pair("func", "Main")) + - types_consts() + - "%func = OpFunction %voidt None %funct\n"; - - str += entry >> merge; - str += head >> std::vector<Block>({merge, f}); - str += f >> merge; - str += merge; - str += "OpFunctionEnd\n"; - - CompileSuccessfully(str); - if (is_shader) { - ASSERT_EQ(SPV_ERROR_INVALID_CFG, ValidateInstructions()); - EXPECT_THAT( - getDiagnosticString(), - MatchesRegex("The selection construct with the selection header " - ".\\[%head\\] does not dominate the merge block " - ".\\[%merge\\]\n %merge = OpLabel\n")); - } else { - ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); - } -} - TEST_P(ValidateCFG, HeaderDoesntStrictlyDominateMergeBad) { // If a merge block is reachable, then it must be strictly dominated by // its header block. @@ -698,7 +663,8 @@ TEST_P(ValidateCFG, HeaderDoesntStrictlyDominateMergeBad) { EXPECT_THAT( getDiagnosticString(), MatchesRegex("The selection construct with the selection header " - ".\\[%head\\] does not strictly dominate the merge block " + ".\\[%head\\] does not strictly structurally dominate the " + "merge block " ".\\[%head\\]\n %head = OpLabel\n")); } else { ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()) << str; @@ -907,16 +873,7 @@ std::string GetUnreachableContinueUnreachableLoopInst(SpvCapability cap) { TEST_P(ValidateCFG, UnreachableContinueUnreachableLoopInst) { CompileSuccessfully(GetUnreachableContinueUnreachableLoopInst(GetParam())); - if (GetParam() == SpvCapabilityShader) { - // Shader causes additional structured CFG checks that cause a failure. - ASSERT_EQ(SPV_ERROR_INVALID_CFG, ValidateInstructions()); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("Back-edges (1[%branch] -> 3[%target]) can only be " - "formed between a block and a loop header.")); - - } else { - ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); - } + ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } std::string GetUnreachableMergeWithComplexBody(SpvCapability cap) { @@ -1070,12 +1027,10 @@ std::string GetUnreachableContinueWithBranchUse(SpvCapability cap) { std::string header = GetDefaultHeader(cap); Block entry("entry"); - Block foo("foo", SpvOpBranch); Block branch("branch", SpvOpBranch); Block merge("merge", SpvOpReturn); Block target("target", SpvOpBranch); - foo >> target; target >> branch; entry.AppendBody("%placeholder = OpVariable %intptrt Function\n"); @@ -1092,7 +1047,6 @@ std::string GetUnreachableContinueWithBranchUse(SpvCapability cap) { str += branch >> std::vector<Block>({merge}); str += merge; str += target; - str += foo; str += "OpFunctionEnd\n"; return str; @@ -1156,6 +1110,7 @@ std::string GetUnreachableMergeAndContinue(SpvCapability cap) { Block body("body", SpvOpBranchConditional); Block t("t", SpvOpReturn); Block f("f", SpvOpReturn); + Block pre_target("pre_target", SpvOpBranch); target >> branch; body.SetBody("%cond = OpSLessThan %boolt %one %two\n"); @@ -1163,10 +1118,10 @@ std::string GetUnreachableMergeAndContinue(SpvCapability cap) { std::string str = header; if (cap == SpvCapabilityShader) { branch.AppendBody("OpLoopMerge %merge %target None\n"); - body.AppendBody("OpSelectionMerge %target None\n"); + body.AppendBody("OpSelectionMerge %pre_target None\n"); } - str += nameOps("branch", "merge", "target", "body", "t", "f", + str += nameOps("branch", "merge", "pre_target", "target", "body", "t", "f", std::make_pair("func", "Main")); str += types_consts(); str += "%func = OpFunction %voidt None %funct\n"; @@ -1176,6 +1131,7 @@ std::string GetUnreachableMergeAndContinue(SpvCapability cap) { str += t; str += f; str += merge; + str += pre_target >> target; str += target; str += "OpFunctionEnd\n"; @@ -1296,9 +1252,10 @@ TEST_P(ValidateCFG, NestedLoops) { loop2.SetBody("OpLoopMerge %loop2_merge %loop2 None\n"); } - std::string str = GetDefaultHeader(GetParam()) + - nameOps("loop2", "loop2_merge") + types_consts() + - "%func = OpFunction %voidt None %funct\n"; + std::string str = + GetDefaultHeader(GetParam()) + + nameOps("loop1", "loop1_cont_break_block", "loop2", "loop2_merge") + + types_consts() + "%func = OpFunction %voidt None %funct\n"; str += entry >> loop1; str += loop1 >> loop1_cont_break_block; @@ -1389,11 +1346,13 @@ TEST_P(ValidateCFG, BackEdgeBlockDoesntPostDominateContinueTargetBad) { CompileSuccessfully(str); if (GetParam() == SpvCapabilityShader) { ASSERT_EQ(SPV_ERROR_INVALID_CFG, ValidateInstructions()); - EXPECT_THAT(getDiagnosticString(), - MatchesRegex("The continue construct with the continue target " - ".\\[%loop1_cont\\] is not post dominated by the " - "back-edge block .\\[%be_block\\]\n" - " %be_block = OpLabel\n")); + EXPECT_THAT( + getDiagnosticString(), + MatchesRegex( + "The continue construct with the continue target " + ".\\[%loop1_cont\\] is not structurally post dominated by the " + "back-edge block .\\[%be_block\\]\n" + " %be_block = OpLabel\n")); } else { ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } @@ -1529,10 +1488,11 @@ TEST_P(ValidateCFG, ContinueTargetMustBePostDominatedByBackEdge) { if (is_shader) { ASSERT_EQ(SPV_ERROR_INVALID_CFG, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), - MatchesRegex("The continue construct with the continue target " - ".\\[%cheader\\] is not post dominated by the " - "back-edge block .\\[%be_block\\]\n" - " %be_block = OpLabel\n")); + MatchesRegex( + "The continue construct with the continue target " + ".\\[%cheader\\] is not structurally post dominated by the " + "back-edge block .\\[%be_block\\]\n" + " %be_block = OpLabel\n")); } else { ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } @@ -1561,11 +1521,12 @@ TEST_P(ValidateCFG, BranchOutOfConstructToMergeBad) { CompileSuccessfully(str); if (is_shader) { ASSERT_EQ(SPV_ERROR_INVALID_CFG, ValidateInstructions()); - EXPECT_THAT(getDiagnosticString(), - MatchesRegex("The continue construct with the continue target " - ".\\[%loop\\] is not post dominated by the " - "back-edge block .\\[%cont\\]\n" - " %cont = OpLabel\n")) + EXPECT_THAT( + getDiagnosticString(), + MatchesRegex("The continue construct with the continue target " + ".\\[%loop\\] is not structurally post dominated by the " + "back-edge block .\\[%cont\\]\n" + " %cont = OpLabel\n")) << str; } else { ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); @@ -1597,11 +1558,12 @@ TEST_P(ValidateCFG, BranchOutOfConstructBad) { CompileSuccessfully(str); if (is_shader) { ASSERT_EQ(SPV_ERROR_INVALID_CFG, ValidateInstructions()); - EXPECT_THAT(getDiagnosticString(), - MatchesRegex("The continue construct with the continue target " - ".\\[%loop\\] is not post dominated by the " - "back-edge block .\\[%cont\\]\n" - " %cont = OpLabel\n")); + EXPECT_THAT( + getDiagnosticString(), + MatchesRegex("The continue construct with the continue target " + ".\\[%loop\\] is not structurally post dominated by the " + "back-edge block .\\[%cont\\]\n" + " %cont = OpLabel\n")); } else { ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } @@ -1824,40 +1786,6 @@ TEST_P(ValidateCFG, SingleLatchBlockMultipleBranchesToLoopHeader) { << str << getDiagnosticString(); } -TEST_P(ValidateCFG, SingleLatchBlockHeaderContinueTargetIsItselfGood) { - // This test case ensures we don't count a Continue Target from a loop - // header to itself as a self-loop when computing back edges. - // Also, it detects that there is an edge from %latch to the pseudo-exit - // node, rather than from %loop. In particular, it detects that we - // have used the *reverse* textual order of blocks when computing - // predecessor traversal roots. - bool is_shader = GetParam() == SpvCapabilityShader; - Block entry("entry"); - Block loop("loop"); - Block latch("latch"); - Block merge("merge", SpvOpReturn); - - entry.SetBody("%cond = OpSLessThan %boolt %one %two\n"); - if (is_shader) { - loop.SetBody("OpLoopMerge %merge %loop None\n"); - } - - std::string str = GetDefaultHeader(GetParam()) + - nameOps("entry", "loop", "latch", "merge") + - types_consts() + - "%func = OpFunction %voidt None %funct\n"; - - str += entry >> loop; - str += loop >> latch; - str += latch >> loop; - str += merge; - str += "OpFunctionEnd"; - - CompileSuccessfully(str); - EXPECT_EQ(SPV_SUCCESS, ValidateInstructions()) - << str << getDiagnosticString(); -} - // Unit test to check the case where a basic block is the entry block of 2 // different constructs. In this case, the basic block is the entry block of a // continue construct as well as a selection construct. See issue# 517 for more @@ -2872,8 +2800,8 @@ OpFunctionEnd CompileSuccessfully(text); EXPECT_EQ(SPV_ERROR_INVALID_CFG, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), - HasSubstr("block <ID> 9 branches to the loop construct, but not " - "to the loop header <ID> 7")); + HasSubstr("Back-edges (10[%10] -> 9[%9]) can only be formed " + "between a block and a loop header")); } TEST_F(ValidateCFG, LoopMergeMergeBlockNotLabel) { @@ -3275,9 +3203,10 @@ OpFunctionEnd CompileSuccessfully(text); EXPECT_EQ(SPV_ERROR_INVALID_CFG, ValidateInstructions()); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("block <ID> 13[%13] exits the selection headed by <ID> " - "9[%9], but not via a structured exit")); + EXPECT_THAT( + getDiagnosticString(), + HasSubstr("The continue construct with the continue target 9[%9] is not " + "structurally post dominated by the back-edge block 13[%13]")); } TEST_F(ValidateCFG, BreakFromSwitch) { @@ -4285,9 +4214,11 @@ TEST_F(ValidateCFG, StructuredSelections_RegisterBothTrueAndFalse) { CompileSuccessfully(text); EXPECT_NE(SPV_SUCCESS, ValidateInstructions()); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("The selection construct with the selection header " - "8[%8] does not dominate the merge block 10[%10]\n")); + EXPECT_THAT( + getDiagnosticString(), + HasSubstr( + "The selection construct with the selection header " + "8[%8] does not structurally dominate the merge block 10[%10]\n")); } TEST_F(ValidateCFG, UnreachableIsStaticallyReachable) { @@ -4624,6 +4555,36 @@ OpFunctionEnd "must be different labels")); } +TEST_F(ValidateCFG, BadBackEdgeUnreachableContinue) { + const std::string text = R"( +OpCapability Shader +OpCapability Linkage +OpMemoryModel Logical GLSL450 +%1 = OpTypeVoid +%2 = OpTypeFunction %1 +%3 = OpFunction %1 None %2 +%4 = OpLabel +OpBranch %5 +%5 = OpLabel +OpLoopMerge %6 %7 None +OpBranch %8 +%8 = OpLabel +OpBranch %5 +%7 = OpLabel +OpUnreachable +%6 = OpLabel +OpUnreachable +OpFunctionEnd +)"; + + CompileSuccessfully(text); + EXPECT_EQ(SPV_ERROR_INVALID_CFG, ValidateInstructions()); + EXPECT_THAT( + getDiagnosticString(), + HasSubstr("The continue construct with the continue target 7[%7] " + "does not structurally dominate the back-edge block 8[%8]")); +} + } // namespace } // namespace val } // namespace spvtools |