diff --git a/source/cfa.h b/source/cfa.h index 2743ab40c..9ae3e39a1 100644 --- a/source/cfa.h +++ b/source/cfa.h @@ -275,10 +275,16 @@ std::vector> CFA::CalculateDominators( std::vector> out; for (auto idom : idoms) { + // At this point if there is no dominator for the node, just make it + // reflexive. + auto dominator = std::get<1>(idom).dominator; + if (dominator == undefined_dom) { + dominator = std::get<1>(idom).postorder_index; + } // NOTE: performing a const cast for convenient usage with // UpdateImmediateDominators out.push_back({const_cast(std::get<0>(idom)), - const_cast(postorder[std::get<1>(idom).dominator])}); + const_cast(postorder[dominator])}); } // Sort by postorder index to generate a deterministic ordering of edges. diff --git a/test/val/val_cfg_test.cpp b/test/val/val_cfg_test.cpp index a4d144419..c8dd4a2fd 100644 --- a/test/val/val_cfg_test.cpp +++ b/test/val/val_cfg_test.cpp @@ -4601,6 +4601,33 @@ OpFunctionEnd "does not structurally dominate the back-edge block '8[%8]'")); } +TEST_F(ValidateCFG, BadLoop) { + const std::string text = R"( +OpCapability Shader +OpMemoryModel Logical Simple +OpEntryPoint Fragment %2 " " +OpExecutionMode %2 OriginUpperLeft +OpName %49 "loop" +%void = OpTypeVoid +%12 = OpTypeFunction %void +%2 = OpFunction %void None %12 +%33 = OpLabel +OpBranch %49 +%50 = OpLabel +OpBranch %49 +%49 = OpLabel +OpLoopMerge %33 %50 Unroll +OpBranch %49 +OpFunctionEnd +)"; + + CompileSuccessfully(text); + EXPECT_EQ(SPV_ERROR_INVALID_CFG, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("Loop header '2[%loop]' is targeted by 2 back-edge " + "blocks but the standard requires exactly one")); +} + } // namespace } // namespace val } // namespace spvtools