Skip to content

Commit 7dda3c0

Browse files
authored
Keep DebugBuildIdentifier during dce (KhronosGroup#6166)
It is expected that no other instructions should refer to the DebugBuildIdentifier instruction, but this causes it to be removed during dead code elimination. Instead keep the instruction if it is found.
1 parent 2e743e9 commit 7dda3c0

File tree

2 files changed

+70
-0
lines changed

2 files changed

+70
-0
lines changed

source/opt/aggressive_dead_code_elim_pass.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -914,6 +914,10 @@ bool AggressiveDCEPass::ProcessGlobalValues() {
914914
context()->AnalyzeUses(&dbg);
915915
continue;
916916
}
917+
// Save debug build identifier even if no other instructions refer to it.
918+
if (dbg.GetShader100DebugOpcode() ==
919+
NonSemanticShaderDebugInfo100DebugBuildIdentifier)
920+
continue;
917921
to_kill_.push_back(&dbg);
918922
modified = true;
919923
}

test/opt/optimizer_test.cpp

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,72 @@ OpFunctionEnd)";
506506
EXPECT_EQ(test_disassembly, default_disassembly);
507507
}
508508

509+
TEST(Optimizer, KeepDebugBuildIdentifierAfterDCE) {
510+
// Test that DebugBuildIdentifier is not removed after DCE.
511+
const std::string before = R"(
512+
OpCapability Shader
513+
OpExtension "SPV_KHR_non_semantic_info"
514+
%1 = OpExtInstImport "NonSemantic.Shader.DebugInfo.100"
515+
OpMemoryModel Logical GLSL450
516+
OpEntryPoint GLCompute %main "main"
517+
OpExecutionMode %main LocalSize 8 8 1
518+
%4 = OpString "8937d8f571cf7b58d86d9d66196024f5d04e3186"
519+
%7 = OpString ""
520+
%9 = OpString ""
521+
OpSource Slang 1
522+
%19 = OpString ""
523+
%24 = OpString ""
524+
%25 = OpString ""
525+
OpName %main "main"
526+
%void = OpTypeVoid
527+
%uint = OpTypeInt 32 0
528+
%uint_0 = OpConstant %uint 0
529+
%uint_11 = OpConstant %uint 11
530+
%uint_5 = OpConstant %uint 5
531+
%uint_100 = OpConstant %uint 100
532+
%15 = OpTypeFunction %void
533+
%uint_6 = OpConstant %uint 6
534+
%uint_7 = OpConstant %uint 7
535+
%uint_1 = OpConstant %uint 1
536+
%uint_2 = OpConstant %uint 2
537+
%3 = OpExtInst %void %1 DebugBuildIdentifier %4 %uint_0
538+
%8 = OpExtInst %void %1 DebugSource %9 %7
539+
%13 = OpExtInst %void %1 DebugCompilationUnit %uint_100 %uint_5 %8 %uint_11
540+
%17 = OpExtInst %void %1 DebugTypeFunction %uint_0 %void
541+
%18 = OpExtInst %void %1 DebugFunction %19 %17 %8 %uint_5 %uint_6 %13 %19 %uint_0 %uint_5
542+
%23 = OpExtInst %void %1 DebugEntryPoint %18 %13 %24 %25
543+
%main = OpFunction %void None %15
544+
%16 = OpLabel
545+
%21 = OpExtInst %void %1 DebugFunctionDefinition %18 %main
546+
%32 = OpExtInst %void %1 DebugScope %18
547+
%26 = OpExtInst %void %1 DebugLine %8 %uint_7 %uint_7 %uint_1 %uint_2
548+
OpReturn
549+
%33 = OpExtInst %void %1 DebugNoScope
550+
OpFunctionEnd
551+
)";
552+
553+
std::vector<uint32_t> binary;
554+
SpirvTools tools(SPV_ENV_VULKAN_1_3);
555+
tools.Assemble(before, &binary,
556+
SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
557+
558+
Optimizer opt(SPV_ENV_VULKAN_1_3);
559+
opt.RegisterPerformancePasses().RegisterPass(CreateAggressiveDCEPass());
560+
561+
std::vector<uint32_t> optimized;
562+
ASSERT_TRUE(opt.Run(binary.data(), binary.size(), &optimized))
563+
<< before << "\n";
564+
565+
std::string after;
566+
tools.Disassemble(optimized.data(), optimized.size(), &after,
567+
SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
568+
569+
// Test that the DebugBuildIdentifier is not removed after DCE.
570+
bool found = after.find("DebugBuildIdentifier") != std::string::npos;
571+
EXPECT_TRUE(found)
572+
<< "Was expecting the DebugBuildIdentifier to have been kept.";
573+
}
574+
509575
} // namespace
510576
} // namespace opt
511577
} // namespace spvtools

0 commit comments

Comments
 (0)