mirror of
https://github.com/KhronosGroup/SPIRV-Tools
synced 2024-11-23 12:10:06 +00:00
parent
b1350659b6
commit
6fac705e76
@ -89,6 +89,8 @@ spv_result_t ValidatePhi(ValidationState_t& _, const Instruction* inst) {
|
||||
<< block->predecessors()->size() << ").";
|
||||
}
|
||||
|
||||
std::unordered_set<uint32_t> observed_predecessors;
|
||||
|
||||
for (size_t i = 3; i < inst->words().size(); ++i) {
|
||||
auto inc_id = inst->word(i);
|
||||
if (i % 2 == 1) {
|
||||
@ -115,6 +117,17 @@ spv_result_t ValidatePhi(ValidationState_t& _, const Instruction* inst) {
|
||||
<< " is not a predecessor of <id> " << _.getIdName(block->id())
|
||||
<< ".";
|
||||
}
|
||||
|
||||
// We must not have already seen this predecessor as one of the phi's
|
||||
// operands.
|
||||
if (observed_predecessors.count(inc_id) != 0) {
|
||||
return _.diag(SPV_ERROR_INVALID_ID, inst)
|
||||
<< "OpPhi references incoming basic block <id> "
|
||||
<< _.getIdName(inc_id) << " multiple times.";
|
||||
}
|
||||
|
||||
// Note the fact that we have now observed this predecessor.
|
||||
observed_predecessors.insert(inc_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4565,6 +4565,39 @@ OpFunctionEnd
|
||||
ASSERT_FALSE(b11->reachable());
|
||||
}
|
||||
|
||||
TEST_F(ValidateCFG, PhiInstructionWithDuplicateIncomingEdges) {
|
||||
const std::string text = R"(
|
||||
OpCapability Shader
|
||||
%1 = OpExtInstImport "GLSL.std.450"
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint Fragment %4 "main"
|
||||
OpExecutionMode %4 OriginUpperLeft
|
||||
OpSource ESSL 320
|
||||
%2 = OpTypeVoid
|
||||
%3 = OpTypeFunction %2
|
||||
%6 = OpTypeBool
|
||||
%7 = OpConstantTrue %6
|
||||
%4 = OpFunction %2 None %3
|
||||
%5 = OpLabel
|
||||
OpSelectionMerge %10 None
|
||||
OpBranchConditional %7 %8 %9
|
||||
%8 = OpLabel
|
||||
OpBranch %10
|
||||
%9 = OpLabel
|
||||
OpBranch %10
|
||||
%10 = OpLabel
|
||||
%11 = OpPhi %6 %7 %8 %7 %8
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
|
||||
CompileSuccessfully(text);
|
||||
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
|
||||
EXPECT_THAT(getDiagnosticString(),
|
||||
HasSubstr("OpPhi references incoming basic block <id> "));
|
||||
EXPECT_THAT(getDiagnosticString(), HasSubstr("multiple times."));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace val
|
||||
} // namespace spvtools
|
||||
|
Loading…
Reference in New Issue
Block a user