Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion source/opt/merge_return_pass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -828,7 +828,8 @@ BasicBlock* MergeReturnPass::CreateContinueTarget(uint32_t header_label_id) {

bool MergeReturnPass::CreateSingleCaseSwitch(BasicBlock* merge_target) {
// Insert the switch before any code is run. We have to split the entry
// block to make sure the OpVariable instructions remain in the entry block.
// block to make sure the OpVariable instructions and DebugFunctionDefinition
// instructions remain in the entry block.
BasicBlock* start_block = &*function_->begin();
auto split_pos = start_block->begin();
while (split_pos->opcode() == spv::Op::OpVariable) {
Expand All @@ -838,6 +839,18 @@ bool MergeReturnPass::CreateSingleCaseSwitch(BasicBlock* merge_target) {
BasicBlock* old_block =
start_block->SplitBasicBlock(context(), TakeNextId(), split_pos);

// Find DebugFunctionDefinition inst in the old block, and if we can find it,
// move it to the entry block. Since DebugFunctionDefinition is not necessary
// after OpVariable inst, we have to traverse the whole block to find it.
for (auto pos = old_block->begin(); pos != old_block->end(); ++pos) {
if (pos->GetShader100DebugOpcode() ==
NonSemanticShaderDebugInfo100DebugFunctionDefinition) {
start_block->AddInstruction(MakeUnique<Instruction>(*pos));
pos.Erase();
break;
}
}

// Add the switch to the end of the entry block.
InstructionBuilder builder(
context(), start_block,
Expand Down
64 changes: 64 additions & 0 deletions test/opt/pass_merge_return_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2598,6 +2598,70 @@ TEST_F(MergeReturnPassTest, OverflowTest1) {
EXPECT_EQ(Pass::Status::Failure, std::get<1>(result));
}

TEST_F(MergeReturnPassTest, DebugFunctionDefinitionStillInEntryBlock) {
// Make sure that the DebugFunctionDefinition instruction is still in the
// entry block
const std::string text =
R"(
; CHECK: OpFunction
; CHECK: OpLabel
; CHECK: DebugFunctionDefinition
; CHECK: OpSelectionMerge
; CHECK: OpCompositeExtract
; CHECK: OpUGreaterThan
OpCapability Shader
OpExtension "SPV_KHR_non_semantic_info"
%2 = OpExtInstImport "NonSemantic.Shader.DebugInfo.100"
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %main "main" %entryPointParam_main %gl_GlobalInvocationID
%1 = OpString "test"
OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId
OpDecorate %entryPointParam_main Location 0
%void = OpTypeVoid
%4 = OpExtInst %void %2 DebugSource %1
%uint = OpTypeInt 32 0
%uint_100 = OpConstant %uint 100
%uint_5 = OpConstant %uint 5
%uint_11 = OpConstant %uint 11
%10 = OpExtInst %void %2 DebugCompilationUnit %uint_100 %uint_5 %4 %uint_11
%12 = OpTypeFunction %void
%uint_0 = OpConstant %uint 0
%14 = OpExtInst %void %2 DebugTypeFunction %uint_0 %void
%uint_2 = OpConstant %uint 2
%16 = OpExtInst %void %2 DebugFunction %1 %14 %4 %uint_2 %uint_5 %10 %1 %uint_0 %uint_2
%v3uint = OpTypeVector %uint 3
%_ptr_Input_v3uint = OpTypePointer Input %v3uint
%bool = OpTypeBool
%uint_3 = OpConstant %uint 3
%int = OpTypeInt 32 1
%_ptr_Output_int = OpTypePointer Output %int
%int_1 = OpConstant %int 1
%int_0 = OpConstant %int 0
%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input ; BuiltIn GlobalInvocationId
%entryPointParam_main = OpVariable %_ptr_Output_int Output ; Location 0

; Function main
%main = OpFunction %void None %12
%13 = OpLabel
%20 = OpExtInst %void %2 DebugScope %16
%29 = OpLoad %v3uint %gl_GlobalInvocationID
%37 = OpCompositeExtract %uint %29 0
%39 = OpUGreaterThan %bool %37 %uint_3
%19 = OpExtInst %void %2 DebugFunctionDefinition %16 %main
OpSelectionMerge %21 None
OpBranchConditional %39 %23 %21
%21 = OpLabel
OpStore %entryPointParam_main %int_1
OpReturn
%23 = OpLabel
OpStore %entryPointParam_main %int_0
OpReturn
OpFunctionEnd
)";

SinglePassRunAndMatch<MergeReturnPass>(text, true);
}

} // namespace
} // namespace opt
} // namespace spvtools