mirror of
https://github.com/KhronosGroup/SPIRV-Tools
synced 2024-10-18 11:10:05 +00:00
Don't merge unreachable blocks (#2375)
Fixes #2374 * Block merging no longer merges unreachable blocks into their successors * added a test
This commit is contained in:
parent
40a7940e05
commit
354205b3dc
@ -86,6 +86,11 @@ bool CanMergeWithSuccessor(IRContext* context, BasicBlock* block) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Don't bother trying to merge unreachable blocks.
|
||||||
|
if (auto dominators = context->GetDominatorAnalysis(block->GetParent())) {
|
||||||
|
if (!dominators->IsReachable(block)) return false;
|
||||||
|
}
|
||||||
|
|
||||||
Instruction* merge_inst = block->GetMergeInst();
|
Instruction* merge_inst = block->GetMergeInst();
|
||||||
const bool pred_is_header = IsHeader(block);
|
const bool pred_is_header = IsHeader(block);
|
||||||
if (pred_is_header && lab_id != merge_inst->GetSingleWordInOperand(0u)) {
|
if (pred_is_header && lab_id != merge_inst->GetSingleWordInOperand(0u)) {
|
||||||
|
@ -483,6 +483,8 @@ TEST_F(BlockMergeTest, RemoveStructuredDeclaration) {
|
|||||||
; CHECK-NOT: OpLoopMerge
|
; CHECK-NOT: OpLoopMerge
|
||||||
; CHECK: OpReturn
|
; CHECK: OpReturn
|
||||||
; CHECK: [[continue:%\w+]] = OpLabel
|
; CHECK: [[continue:%\w+]] = OpLabel
|
||||||
|
; CHECK-NEXT: OpBranch [[block:%\w+]]
|
||||||
|
; CHECK: [[block]] = OpLabel
|
||||||
; CHECK-NEXT: OpBranch [[header]]
|
; CHECK-NEXT: OpBranch [[header]]
|
||||||
OpCapability Shader
|
OpCapability Shader
|
||||||
%1 = OpExtInstImport "GLSL.std.450"
|
%1 = OpExtInstImport "GLSL.std.450"
|
||||||
@ -880,6 +882,47 @@ OpFunctionEnd
|
|||||||
prefix + suffix_after, true, true);
|
prefix + suffix_after, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(BlockMergeTest, UnreachableLoop) {
|
||||||
|
const std::string spirv = R"(OpCapability Shader
|
||||||
|
%1 = OpExtInstImport "GLSL.std.450"
|
||||||
|
OpMemoryModel Logical GLSL450
|
||||||
|
OpEntryPoint Fragment %main "main"
|
||||||
|
OpExecutionMode %main OriginUpperLeft
|
||||||
|
OpSource ESSL 310
|
||||||
|
OpName %main "main"
|
||||||
|
%void = OpTypeVoid
|
||||||
|
%4 = OpTypeFunction %void
|
||||||
|
%int = OpTypeInt 32 1
|
||||||
|
%_ptr_Function_int = OpTypePointer Function %int
|
||||||
|
%bool = OpTypeBool
|
||||||
|
%false = OpConstantFalse %bool
|
||||||
|
%main = OpFunction %void None %4
|
||||||
|
%9 = OpLabel
|
||||||
|
OpBranch %10
|
||||||
|
%11 = OpLabel
|
||||||
|
OpLoopMerge %12 %13 None
|
||||||
|
OpBranchConditional %false %13 %14
|
||||||
|
%13 = OpLabel
|
||||||
|
OpSelectionMerge %15 None
|
||||||
|
OpBranchConditional %false %16 %17
|
||||||
|
%16 = OpLabel
|
||||||
|
OpBranch %15
|
||||||
|
%17 = OpLabel
|
||||||
|
OpBranch %15
|
||||||
|
%15 = OpLabel
|
||||||
|
OpBranch %11
|
||||||
|
%14 = OpLabel
|
||||||
|
OpReturn
|
||||||
|
%12 = OpLabel
|
||||||
|
OpBranch %10
|
||||||
|
%10 = OpLabel
|
||||||
|
OpReturn
|
||||||
|
OpFunctionEnd
|
||||||
|
)";
|
||||||
|
|
||||||
|
SinglePassRunAndCheck<BlockMergePass>(spirv, spirv, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
// TODO(greg-lunarg): Add tests to verify handling of these cases:
|
// TODO(greg-lunarg): Add tests to verify handling of these cases:
|
||||||
//
|
//
|
||||||
// More complex control flow
|
// More complex control flow
|
||||||
|
Loading…
Reference in New Issue
Block a user