Fix merge-block assertions with debugInfo (#4563)

Fixes DefUse assertions and invalid DebugScope instruction
between OpLoopMerge and OpBranch for included test shader.
This commit is contained in:
Greg Fischer 2021-10-13 11:42:40 -06:00 committed by GitHub
parent e4349dd8f4
commit 6dd73728e9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 117 additions and 6 deletions

View File

@ -171,12 +171,17 @@ void MergeWithSuccessor(IRContext* context, Function* func,
// and OpBranchConditional.
auto terminator = bi->terminator();
auto& vec = terminator->dbg_line_insts();
auto& new_vec = merge_inst->dbg_line_insts();
new_vec.insert(new_vec.end(), vec.begin(), vec.end());
terminator->ClearDbgLineInsts();
for (auto& l_inst : new_vec)
context->get_def_use_mgr()->AnalyzeInstDefUse(&l_inst);
if (vec.size() > 0) {
merge_inst->ClearDbgLineInsts();
auto& new_vec = merge_inst->dbg_line_insts();
new_vec.insert(new_vec.end(), vec.begin(), vec.end());
terminator->ClearDbgLineInsts();
for (auto& l_inst : new_vec)
context->get_def_use_mgr()->AnalyzeInstDefUse(&l_inst);
}
// Clear debug scope of terminator to avoid DebugScope
// emitted between terminator and merge.
terminator->SetDebugScope(DebugScope(kNoDebugScope, kNoInlinedAt));
// Move the merge instruction to just before the terminator.
merge_inst->InsertBefore(terminator);
}

View File

@ -1038,6 +1038,112 @@ OpFunctionEnd
SinglePassRunAndCheck<BlockMergePass>(spirv, spirv, true, true);
}
TEST_F(BlockMergeTest, DebugMerge) {
// Verify merge can be done completely, cleanly and validly in presence of
// NonSemantic.Shader.DebugInfo.100 instructions
const std::string text = R"(
; CHECK: OpLoopMerge
; CHECK-NEXT: OpBranch
; CHECK-NOT: OpBranch
OpCapability Shader
OpExtension "SPV_KHR_non_semantic_info"
%1 = OpExtInstImport "NonSemantic.Shader.DebugInfo.100"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %main "main" %in_var_COLOR %out_var_SV_TARGET
OpExecutionMode %main OriginUpperLeft
%5 = OpString "lexblock.hlsl"
%20 = OpString "float"
%32 = OpString "main"
%33 = OpString ""
%46 = OpString "b"
%49 = OpString "a"
%58 = OpString "c"
%63 = OpString "color"
OpName %in_var_COLOR "in.var.COLOR"
OpName %out_var_SV_TARGET "out.var.SV_TARGET"
OpName %main "main"
OpDecorate %in_var_COLOR Location 0
OpDecorate %out_var_SV_TARGET Location 0
%float = OpTypeFloat 32
%float_0 = OpConstant %float 0
%v4float = OpTypeVector %float 4
%9 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
%float_1 = OpConstant %float 1
%13 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
%uint = OpTypeInt 32 0
%uint_32 = OpConstant %uint 32
%_ptr_Input_v4float = OpTypePointer Input %v4float
%_ptr_Output_v4float = OpTypePointer Output %v4float
%void = OpTypeVoid
%uint_3 = OpConstant %uint 3
%uint_0 = OpConstant %uint 0
%uint_4 = OpConstant %uint 4
%uint_1 = OpConstant %uint 1
%uint_5 = OpConstant %uint 5
%uint_12 = OpConstant %uint 12
%uint_13 = OpConstant %uint 13
%uint_20 = OpConstant %uint 20
%uint_15 = OpConstant %uint 15
%uint_17 = OpConstant %uint 17
%uint_16 = OpConstant %uint 16
%uint_14 = OpConstant %uint 14
%uint_10 = OpConstant %uint 10
%65 = OpTypeFunction %void
%in_var_COLOR = OpVariable %_ptr_Input_v4float Input
%out_var_SV_TARGET = OpVariable %_ptr_Output_v4float Output
%62 = OpExtInst %void %1 DebugExpression
%22 = OpExtInst %void %1 DebugTypeBasic %20 %uint_32 %uint_3 %uint_0
%25 = OpExtInst %void %1 DebugTypeVector %22 %uint_4
%27 = OpExtInst %void %1 DebugTypeFunction %uint_3 %25 %25
%28 = OpExtInst %void %1 DebugSource %5
%29 = OpExtInst %void %1 DebugCompilationUnit %uint_1 %uint_4 %28 %uint_5
%34 = OpExtInst %void %1 DebugFunction %32 %27 %28 %uint_12 %uint_1 %29 %33 %uint_3 %uint_13
%37 = OpExtInst %void %1 DebugLexicalBlock %28 %uint_13 %uint_1 %34
%52 = OpExtInst %void %1 DebugLexicalBlock %28 %uint_15 %uint_12 %37
%54 = OpExtInst %void %1 DebugLocalVariable %46 %25 %28 %uint_17 %uint_12 %52 %uint_4
%56 = OpExtInst %void %1 DebugLocalVariable %49 %25 %28 %uint_16 %uint_12 %52 %uint_4
%59 = OpExtInst %void %1 DebugLocalVariable %58 %25 %28 %uint_14 %uint_10 %37 %uint_4
%64 = OpExtInst %void %1 DebugLocalVariable %63 %25 %28 %uint_12 %uint_20 %34 %uint_4 %uint_1
%main = OpFunction %void None %65
%66 = OpLabel
%69 = OpLoad %v4float %in_var_COLOR
%168 = OpExtInst %void %1 DebugValue %64 %69 %62
%169 = OpExtInst %void %1 DebugScope %37
OpLine %5 14 10
%164 = OpExtInst %void %1 DebugValue %59 %9 %62
OpLine %5 15 3
OpBranch %150
%150 = OpLabel
%165 = OpPhi %v4float %9 %66 %158 %159
%167 = OpExtInst %void %1 DebugValue %59 %165 %62
%170 = OpExtInst %void %1 DebugScope %37
OpLine %5 15 12
%171 = OpExtInst %void %1 DebugNoScope
OpLoopMerge %160 %159 None
OpBranch %151
%151 = OpLabel
OpLine %5 16 12
%162 = OpExtInst %void %1 DebugValue %56 %9 %62
OpLine %5 17 12
%163 = OpExtInst %void %1 DebugValue %54 %13 %62
OpLine %5 18 15
%158 = OpFAdd %v4float %165 %13
OpLine %5 18 5
%166 = OpExtInst %void %1 DebugValue %59 %158 %62
%172 = OpExtInst %void %1 DebugScope %37
OpLine %5 19 3
OpBranch %159
%159 = OpLabel
OpLine %5 19 3
OpBranch %150
%160 = OpLabel
OpUnreachable
OpFunctionEnd
)";
SinglePassRunAndMatch<BlockMergePass>(text, true);
}
// TODO(greg-lunarg): Add tests to verify handling of these cases:
//
// More complex control flow