Fix dereference of possibly nullptr

* If the dead branch elim is performed on a module without structured
control flow, the OpSelectionMerge may not be present
 * Add a check for pointer validity before dereferencing
* Added a test to catch the bug
This commit is contained in:
Alan Baker 2018-01-30 10:15:43 -05:00
parent f28b106173
commit 6704233d39
2 changed files with 27 additions and 1 deletions

View File

@ -153,7 +153,7 @@ bool DeadBranchElimPass::MarkLiveBlocks(
AddBranch(live_lab_id, block);
context()->KillInst(terminator);
ir::Instruction* mergeInst = block->GetMergeInst();
if (mergeInst->opcode() == SpvOpSelectionMerge) {
if (mergeInst && mergeInst->opcode() == SpvOpSelectionMerge) {
context()->KillInst(mergeInst);
}
stack.push_back(GetParentBlock(live_lab_id));

View File

@ -1907,6 +1907,32 @@ TEST_F(DeadBranchElimTest, UnreachableContinuePhiInMerge) {
SinglePassRunAndMatch<opt::DeadBranchElimPass>(text, true);
}
TEST_F(DeadBranchElimTest, NonStructuredIf) {
const std::string text = R"(
; CHECK-NOT: OpBranchConditional
OpCapability Kernel
OpCapability Linkage
OpMemoryModel Logical OpenCL
OpDecorate %func LinkageAttributes "func" Export
%void = OpTypeVoid
%bool = OpTypeBool
%true = OpConstantTrue %bool
%functy = OpTypeFunction %void
%func = OpFunction %void None %functy
%entry = OpLabel
OpBranchConditional %true %then %else
%then = OpLabel
OpBranch %final
%else = OpLabel
OpBranch %final
%final = OpLabel
OpReturn
OpFunctionEnd
)";
SinglePassRunAndMatch<opt::DeadBranchElimPass>(text, true);
}
#endif
// TODO(greg-lunarg): Add tests to verify handling of these cases: