diff --git a/source/opt/aggressive_dead_code_elim_pass.cpp b/source/opt/aggressive_dead_code_elim_pass.cpp index 7eb158d5e..6e86c378b 100644 --- a/source/opt/aggressive_dead_code_elim_pass.cpp +++ b/source/opt/aggressive_dead_code_elim_pass.cpp @@ -267,6 +267,7 @@ void AggressiveDCEPass::AddBreaksAndContinuesToWorklist( } bool AggressiveDCEPass::AggressiveDCE(Function* func) { + if (func->IsDeclaration()) return false; std::list structured_order; cfg()->ComputeStructuredOrder(func, &*func->begin(), &structured_order); live_local_vars_.clear(); diff --git a/source/opt/mem_pass.cpp b/source/opt/mem_pass.cpp index 80ec8da18..65f45ec3b 100644 --- a/source/opt/mem_pass.cpp +++ b/source/opt/mem_pass.cpp @@ -415,6 +415,7 @@ void MemPass::RemoveBlock(Function::iterator* bi) { } bool MemPass::RemoveUnreachableBlocks(Function* func) { + if (func->IsDeclaration()) return false; bool modified = false; // Mark reachable all blocks reachable from the function's entry block. diff --git a/test/opt/aggressive_dead_code_elim_test.cpp b/test/opt/aggressive_dead_code_elim_test.cpp index d837099fe..a4353b1b8 100644 --- a/test/opt/aggressive_dead_code_elim_test.cpp +++ b/test/opt/aggressive_dead_code_elim_test.cpp @@ -8070,6 +8070,42 @@ TEST_F(AggressiveDCETest, StoringAPointer) { SinglePassRunAndMatch(text, true); } +TEST_F(AggressiveDCETest, FunctionDeclaration) { + // Ensure the optimizer can handle traversing over a function declaration + // 'myfunc' which has no blocks + + const std::string text = R"(OpCapability Linkage +OpCapability Shader +OpMemoryModel Logical GLSL450 +OpEntryPoint Fragment %PSMain "main" %entryPointParam_PSMain +OpExecutionMode %PSMain OriginUpperLeft +OpSource Slang 1 +OpName %myfunc "myfunc" +OpName %entryPointParam_PSMain "entryPointParam_PSMain" +OpName %PSMain "PSMain" +OpDecorate %myfunc LinkageAttributes "_S6myfuncp0pv4f" Import +OpDecorate %entryPointParam_PSMain Location 0 +%void = OpTypeVoid +%5 = OpTypeFunction %void +%float = OpTypeFloat 32 +%v4float = OpTypeVector %float 4 +%8 = OpTypeFunction %v4float +%_ptr_Output_v4float = OpTypePointer Output %v4float +%entryPointParam_PSMain = OpVariable %_ptr_Output_v4float Output +%myfunc = OpFunction %v4float None %8 +OpFunctionEnd +%PSMain = OpFunction %void None %5 +%10 = OpLabel +%11 = OpFunctionCall %v4float %myfunc +OpStore %entryPointParam_PSMain %11 +OpReturn +OpFunctionEnd +)"; + + SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); + SinglePassRunAndCheck(text, text, true, true); +} + } // namespace } // namespace opt } // namespace spvtools