1fd4e5da5Sopenharmony_ci// Copyright (c) 2017 Google Inc. 2fd4e5da5Sopenharmony_ci// 3fd4e5da5Sopenharmony_ci// Licensed under the Apache License, Version 2.0 (the "License"); 4fd4e5da5Sopenharmony_ci// you may not use this file except in compliance with the License. 5fd4e5da5Sopenharmony_ci// You may obtain a copy of the License at 6fd4e5da5Sopenharmony_ci// 7fd4e5da5Sopenharmony_ci// http://www.apache.org/licenses/LICENSE-2.0 8fd4e5da5Sopenharmony_ci// 9fd4e5da5Sopenharmony_ci// Unless required by applicable law or agreed to in writing, software 10fd4e5da5Sopenharmony_ci// distributed under the License is distributed on an "AS IS" BASIS, 11fd4e5da5Sopenharmony_ci// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12fd4e5da5Sopenharmony_ci// See the License for the specific language governing permissions and 13fd4e5da5Sopenharmony_ci// limitations under the License. 14fd4e5da5Sopenharmony_ci 15fd4e5da5Sopenharmony_ci#include <string> 16fd4e5da5Sopenharmony_ci#include <vector> 17fd4e5da5Sopenharmony_ci 18fd4e5da5Sopenharmony_ci#include "gmock/gmock.h" 19fd4e5da5Sopenharmony_ci#include "test/opt/assembly_builder.h" 20fd4e5da5Sopenharmony_ci#include "test/opt/pass_fixture.h" 21fd4e5da5Sopenharmony_ci#include "test/opt/pass_utils.h" 22fd4e5da5Sopenharmony_ci 23fd4e5da5Sopenharmony_cinamespace spvtools { 24fd4e5da5Sopenharmony_cinamespace opt { 25fd4e5da5Sopenharmony_cinamespace { 26fd4e5da5Sopenharmony_ci 27fd4e5da5Sopenharmony_ciusing ::testing::HasSubstr; 28fd4e5da5Sopenharmony_ciusing EliminateDeadFunctionsBasicTest = PassTest<::testing::Test>; 29fd4e5da5Sopenharmony_ci 30fd4e5da5Sopenharmony_ciTEST_F(EliminateDeadFunctionsBasicTest, BasicDeleteDeadFunction) { 31fd4e5da5Sopenharmony_ci // The function Dead should be removed because it is never called. 32fd4e5da5Sopenharmony_ci const std::vector<const char*> common_code = { 33fd4e5da5Sopenharmony_ci // clang-format off 34fd4e5da5Sopenharmony_ci "OpCapability Shader", 35fd4e5da5Sopenharmony_ci "OpMemoryModel Logical GLSL450", 36fd4e5da5Sopenharmony_ci "OpEntryPoint Fragment %main \"main\"", 37fd4e5da5Sopenharmony_ci "OpName %main \"main\"", 38fd4e5da5Sopenharmony_ci "OpName %Live \"Live\"", 39fd4e5da5Sopenharmony_ci "%void = OpTypeVoid", 40fd4e5da5Sopenharmony_ci "%7 = OpTypeFunction %void", 41fd4e5da5Sopenharmony_ci "%main = OpFunction %void None %7", 42fd4e5da5Sopenharmony_ci "%15 = OpLabel", 43fd4e5da5Sopenharmony_ci "%16 = OpFunctionCall %void %Live", 44fd4e5da5Sopenharmony_ci "%17 = OpFunctionCall %void %Live", 45fd4e5da5Sopenharmony_ci "OpReturn", 46fd4e5da5Sopenharmony_ci "OpFunctionEnd", 47fd4e5da5Sopenharmony_ci "%Live = OpFunction %void None %7", 48fd4e5da5Sopenharmony_ci "%20 = OpLabel", 49fd4e5da5Sopenharmony_ci "OpReturn", 50fd4e5da5Sopenharmony_ci "OpFunctionEnd" 51fd4e5da5Sopenharmony_ci // clang-format on 52fd4e5da5Sopenharmony_ci }; 53fd4e5da5Sopenharmony_ci 54fd4e5da5Sopenharmony_ci const std::vector<const char*> dead_function = { 55fd4e5da5Sopenharmony_ci // clang-format off 56fd4e5da5Sopenharmony_ci "%Dead = OpFunction %void None %7", 57fd4e5da5Sopenharmony_ci "%19 = OpLabel", 58fd4e5da5Sopenharmony_ci "OpReturn", 59fd4e5da5Sopenharmony_ci "OpFunctionEnd", 60fd4e5da5Sopenharmony_ci // clang-format on 61fd4e5da5Sopenharmony_ci }; 62fd4e5da5Sopenharmony_ci 63fd4e5da5Sopenharmony_ci SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 64fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<EliminateDeadFunctionsPass>( 65fd4e5da5Sopenharmony_ci JoinAllInsts(Concat(common_code, dead_function)), 66fd4e5da5Sopenharmony_ci JoinAllInsts(common_code), /* skip_nop = */ true); 67fd4e5da5Sopenharmony_ci} 68fd4e5da5Sopenharmony_ci 69fd4e5da5Sopenharmony_ciTEST_F(EliminateDeadFunctionsBasicTest, BasicKeepLiveFunction) { 70fd4e5da5Sopenharmony_ci // Everything is reachable from an entry point, so no functions should be 71fd4e5da5Sopenharmony_ci // deleted. 72fd4e5da5Sopenharmony_ci const std::vector<const char*> text = { 73fd4e5da5Sopenharmony_ci // clang-format off 74fd4e5da5Sopenharmony_ci "OpCapability Shader", 75fd4e5da5Sopenharmony_ci "OpMemoryModel Logical GLSL450", 76fd4e5da5Sopenharmony_ci "OpEntryPoint Fragment %main \"main\"", 77fd4e5da5Sopenharmony_ci "OpName %main \"main\"", 78fd4e5da5Sopenharmony_ci "OpName %Live1 \"Live1\"", 79fd4e5da5Sopenharmony_ci "OpName %Live2 \"Live2\"", 80fd4e5da5Sopenharmony_ci "%void = OpTypeVoid", 81fd4e5da5Sopenharmony_ci "%7 = OpTypeFunction %void", 82fd4e5da5Sopenharmony_ci "%main = OpFunction %void None %7", 83fd4e5da5Sopenharmony_ci "%15 = OpLabel", 84fd4e5da5Sopenharmony_ci "%16 = OpFunctionCall %void %Live2", 85fd4e5da5Sopenharmony_ci "%17 = OpFunctionCall %void %Live1", 86fd4e5da5Sopenharmony_ci "OpReturn", 87fd4e5da5Sopenharmony_ci "OpFunctionEnd", 88fd4e5da5Sopenharmony_ci "%Live1 = OpFunction %void None %7", 89fd4e5da5Sopenharmony_ci "%19 = OpLabel", 90fd4e5da5Sopenharmony_ci "OpReturn", 91fd4e5da5Sopenharmony_ci "OpFunctionEnd", 92fd4e5da5Sopenharmony_ci "%Live2 = OpFunction %void None %7", 93fd4e5da5Sopenharmony_ci "%20 = OpLabel", 94fd4e5da5Sopenharmony_ci "OpReturn", 95fd4e5da5Sopenharmony_ci "OpFunctionEnd" 96fd4e5da5Sopenharmony_ci // clang-format on 97fd4e5da5Sopenharmony_ci }; 98fd4e5da5Sopenharmony_ci 99fd4e5da5Sopenharmony_ci SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 100fd4e5da5Sopenharmony_ci std::string assembly = JoinAllInsts(text); 101fd4e5da5Sopenharmony_ci auto result = SinglePassRunAndDisassemble<EliminateDeadFunctionsPass>( 102fd4e5da5Sopenharmony_ci assembly, /* skip_nop = */ true, /* do_validation = */ false); 103fd4e5da5Sopenharmony_ci EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result)); 104fd4e5da5Sopenharmony_ci EXPECT_EQ(assembly, std::get<0>(result)); 105fd4e5da5Sopenharmony_ci} 106fd4e5da5Sopenharmony_ci 107fd4e5da5Sopenharmony_ciTEST_F(EliminateDeadFunctionsBasicTest, BasicKeepExportFunctions) { 108fd4e5da5Sopenharmony_ci // All functions are reachable. In particular, ExportedFunc and Constant are 109fd4e5da5Sopenharmony_ci // reachable because ExportedFunc is exported. Nothing should be removed. 110fd4e5da5Sopenharmony_ci const std::vector<const char*> text = { 111fd4e5da5Sopenharmony_ci // clang-format off 112fd4e5da5Sopenharmony_ci "OpCapability Shader", 113fd4e5da5Sopenharmony_ci "OpCapability Linkage", 114fd4e5da5Sopenharmony_ci "OpMemoryModel Logical GLSL450", 115fd4e5da5Sopenharmony_ci "OpEntryPoint Fragment %main \"main\"", 116fd4e5da5Sopenharmony_ci "OpName %main \"main\"", 117fd4e5da5Sopenharmony_ci "OpName %ExportedFunc \"ExportedFunc\"", 118fd4e5da5Sopenharmony_ci "OpName %Live \"Live\"", 119fd4e5da5Sopenharmony_ci "OpDecorate %ExportedFunc LinkageAttributes \"ExportedFunc\" Export", 120fd4e5da5Sopenharmony_ci "%void = OpTypeVoid", 121fd4e5da5Sopenharmony_ci "%7 = OpTypeFunction %void", 122fd4e5da5Sopenharmony_ci "%main = OpFunction %void None %7", 123fd4e5da5Sopenharmony_ci "%15 = OpLabel", 124fd4e5da5Sopenharmony_ci "OpReturn", 125fd4e5da5Sopenharmony_ci "OpFunctionEnd", 126fd4e5da5Sopenharmony_ci"%ExportedFunc = OpFunction %void None %7", 127fd4e5da5Sopenharmony_ci "%19 = OpLabel", 128fd4e5da5Sopenharmony_ci "%16 = OpFunctionCall %void %Live", 129fd4e5da5Sopenharmony_ci "OpReturn", 130fd4e5da5Sopenharmony_ci "OpFunctionEnd", 131fd4e5da5Sopenharmony_ci "%Live = OpFunction %void None %7", 132fd4e5da5Sopenharmony_ci "%20 = OpLabel", 133fd4e5da5Sopenharmony_ci "OpReturn", 134fd4e5da5Sopenharmony_ci "OpFunctionEnd" 135fd4e5da5Sopenharmony_ci // clang-format on 136fd4e5da5Sopenharmony_ci }; 137fd4e5da5Sopenharmony_ci 138fd4e5da5Sopenharmony_ci SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 139fd4e5da5Sopenharmony_ci std::string assembly = JoinAllInsts(text); 140fd4e5da5Sopenharmony_ci auto result = SinglePassRunAndDisassemble<EliminateDeadFunctionsPass>( 141fd4e5da5Sopenharmony_ci assembly, /* skip_nop = */ true, /* do_validation = */ false); 142fd4e5da5Sopenharmony_ci EXPECT_EQ(Pass::Status::SuccessWithoutChange, std::get<1>(result)); 143fd4e5da5Sopenharmony_ci EXPECT_EQ(assembly, std::get<0>(result)); 144fd4e5da5Sopenharmony_ci} 145fd4e5da5Sopenharmony_ci 146fd4e5da5Sopenharmony_ciTEST_F(EliminateDeadFunctionsBasicTest, BasicRemoveDecorationsAndNames) { 147fd4e5da5Sopenharmony_ci // We want to remove the names and decorations associated with results that 148fd4e5da5Sopenharmony_ci // are removed. This test will check for that. 149fd4e5da5Sopenharmony_ci const std::string text = R"( 150fd4e5da5Sopenharmony_ci OpCapability Shader 151fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 152fd4e5da5Sopenharmony_ci OpEntryPoint Vertex %main "main" 153fd4e5da5Sopenharmony_ci OpName %main "main" 154fd4e5da5Sopenharmony_ci OpName %Dead "Dead" 155fd4e5da5Sopenharmony_ci OpName %x "x" 156fd4e5da5Sopenharmony_ci OpName %y "y" 157fd4e5da5Sopenharmony_ci OpName %z "z" 158fd4e5da5Sopenharmony_ci OpDecorate %x RelaxedPrecision 159fd4e5da5Sopenharmony_ci OpDecorate %y RelaxedPrecision 160fd4e5da5Sopenharmony_ci OpDecorate %z RelaxedPrecision 161fd4e5da5Sopenharmony_ci OpDecorate %6 RelaxedPrecision 162fd4e5da5Sopenharmony_ci OpDecorate %7 RelaxedPrecision 163fd4e5da5Sopenharmony_ci OpDecorate %8 RelaxedPrecision 164fd4e5da5Sopenharmony_ci %void = OpTypeVoid 165fd4e5da5Sopenharmony_ci %10 = OpTypeFunction %void 166fd4e5da5Sopenharmony_ci %float = OpTypeFloat 32 167fd4e5da5Sopenharmony_ci%_ptr_Function_float = OpTypePointer Function %float 168fd4e5da5Sopenharmony_ci %float_1 = OpConstant %float 1 169fd4e5da5Sopenharmony_ci %main = OpFunction %void None %10 170fd4e5da5Sopenharmony_ci %14 = OpLabel 171fd4e5da5Sopenharmony_ci OpReturn 172fd4e5da5Sopenharmony_ci OpFunctionEnd 173fd4e5da5Sopenharmony_ci %Dead = OpFunction %void None %10 174fd4e5da5Sopenharmony_ci %15 = OpLabel 175fd4e5da5Sopenharmony_ci %x = OpVariable %_ptr_Function_float Function 176fd4e5da5Sopenharmony_ci %y = OpVariable %_ptr_Function_float Function 177fd4e5da5Sopenharmony_ci %z = OpVariable %_ptr_Function_float Function 178fd4e5da5Sopenharmony_ci OpStore %x %float_1 179fd4e5da5Sopenharmony_ci OpStore %y %float_1 180fd4e5da5Sopenharmony_ci %6 = OpLoad %float %x 181fd4e5da5Sopenharmony_ci %7 = OpLoad %float %y 182fd4e5da5Sopenharmony_ci %8 = OpFAdd %float %6 %7 183fd4e5da5Sopenharmony_ci OpStore %z %8 184fd4e5da5Sopenharmony_ci OpReturn 185fd4e5da5Sopenharmony_ci OpFunctionEnd)"; 186fd4e5da5Sopenharmony_ci 187fd4e5da5Sopenharmony_ci const std::string expected_output = R"(OpCapability Shader 188fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 189fd4e5da5Sopenharmony_ciOpEntryPoint Vertex %main "main" 190fd4e5da5Sopenharmony_ciOpName %main "main" 191fd4e5da5Sopenharmony_ci%void = OpTypeVoid 192fd4e5da5Sopenharmony_ci%10 = OpTypeFunction %void 193fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 194fd4e5da5Sopenharmony_ci%_ptr_Function_float = OpTypePointer Function %float 195fd4e5da5Sopenharmony_ci%float_1 = OpConstant %float 1 196fd4e5da5Sopenharmony_ci%main = OpFunction %void None %10 197fd4e5da5Sopenharmony_ci%14 = OpLabel 198fd4e5da5Sopenharmony_ciOpReturn 199fd4e5da5Sopenharmony_ciOpFunctionEnd 200fd4e5da5Sopenharmony_ci)"; 201fd4e5da5Sopenharmony_ci 202fd4e5da5Sopenharmony_ci SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); 203fd4e5da5Sopenharmony_ci SinglePassRunAndCheck<EliminateDeadFunctionsPass>(text, expected_output, 204fd4e5da5Sopenharmony_ci /* skip_nop = */ true); 205fd4e5da5Sopenharmony_ci} 206fd4e5da5Sopenharmony_ci 207fd4e5da5Sopenharmony_ciTEST_F(EliminateDeadFunctionsBasicTest, DebugRemoveFunctionFromDebugFunction) { 208fd4e5da5Sopenharmony_ci // We want to remove id of OpFunction from DebugFunction. 209fd4e5da5Sopenharmony_ci const std::string text = R"(OpCapability Shader 210fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "OpenCL.DebugInfo.100" 211fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 212fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %2 "main" %3 %4 213fd4e5da5Sopenharmony_ciOpExecutionMode %2 OriginUpperLeft 214fd4e5da5Sopenharmony_ci%5 = OpString "ps.hlsl" 215fd4e5da5Sopenharmony_ciOpSource HLSL 600 %5 "float4 foo() { 216fd4e5da5Sopenharmony_ci return 1; 217fd4e5da5Sopenharmony_ci} 218fd4e5da5Sopenharmony_cifloat4 main(float4 color : COLOR) : SV_TARGET { 219fd4e5da5Sopenharmony_ci return foo() + color; 220fd4e5da5Sopenharmony_ci} 221fd4e5da5Sopenharmony_ci" 222fd4e5da5Sopenharmony_ci%6 = OpString "float" 223fd4e5da5Sopenharmony_ci%7 = OpString "main" 224fd4e5da5Sopenharmony_ci%8 = OpString "foo" 225fd4e5da5Sopenharmony_ci; CHECK: [[foo:%\d+]] = OpString "foo" 226fd4e5da5Sopenharmony_ciOpDecorate %3 Location 0 227fd4e5da5Sopenharmony_ciOpDecorate %4 Location 0 228fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 229fd4e5da5Sopenharmony_ci%uint_32 = OpConstant %uint 32 230fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 231fd4e5da5Sopenharmony_ci%float_1 = OpConstant %float 1 232fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4 233fd4e5da5Sopenharmony_ci%14 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1 234fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float 235fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float 236fd4e5da5Sopenharmony_ci%void = OpTypeVoid 237fd4e5da5Sopenharmony_ci%18 = OpTypeFunction %void 238fd4e5da5Sopenharmony_ci%19 = OpTypeFunction %v4float 239fd4e5da5Sopenharmony_ci%3 = OpVariable %_ptr_Input_v4float Input 240fd4e5da5Sopenharmony_ci%4 = OpVariable %_ptr_Output_v4float Output 241fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float 242fd4e5da5Sopenharmony_ci; CHECK: [[info_none:%\d+]] = OpExtInst %void %1 DebugInfoNone 243fd4e5da5Sopenharmony_ci%20 = OpExtInst %void %1 DebugSource %5 244fd4e5da5Sopenharmony_ci%21 = OpExtInst %void %1 DebugCompilationUnit 1 4 %20 HLSL 245fd4e5da5Sopenharmony_ci%22 = OpExtInst %void %1 DebugTypeBasic %6 %uint_32 Float 246fd4e5da5Sopenharmony_ci%23 = OpExtInst %void %1 DebugTypeVector %22 4 247fd4e5da5Sopenharmony_ci%24 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %23 %23 248fd4e5da5Sopenharmony_ci%25 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %23 249fd4e5da5Sopenharmony_ci%26 = OpExtInst %void %1 DebugFunction %7 %24 %20 4 1 %21 %7 FlagIsProtected|FlagIsPrivate 4 %2 250fd4e5da5Sopenharmony_ci%27 = OpExtInst %void %1 DebugFunction %8 %25 %20 1 1 %21 %8 FlagIsProtected|FlagIsPrivate 1 %28 251fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpExtInst %void %1 DebugFunction [[foo]] {{%\d+}} {{%\d+}} 1 1 {{%\d+}} {{%\d+}} FlagIsProtected|FlagIsPrivate 1 [[info_none]] 252fd4e5da5Sopenharmony_ci%29 = OpExtInst %void %1 DebugLexicalBlock %20 1 14 %27 253fd4e5da5Sopenharmony_ci%40 = OpExtInst %void %1 DebugInlinedAt 4 %26 254fd4e5da5Sopenharmony_ci%2 = OpFunction %void None %18 255fd4e5da5Sopenharmony_ci%30 = OpLabel 256fd4e5da5Sopenharmony_ci%39 = OpVariable %_ptr_Function_v4float Function 257fd4e5da5Sopenharmony_ci%41 = OpExtInst %void %1 DebugScope %27 %40 258fd4e5da5Sopenharmony_ciOpStore %39 %14 259fd4e5da5Sopenharmony_ci%32 = OpLoad %v4float %39 260fd4e5da5Sopenharmony_ci%42 = OpExtInst %void %1 DebugScope %26 261fd4e5da5Sopenharmony_ci%33 = OpLoad %v4float %3 262fd4e5da5Sopenharmony_ci%34 = OpFAdd %v4float %32 %33 263fd4e5da5Sopenharmony_ciOpStore %4 %34 264fd4e5da5Sopenharmony_ci%43 = OpExtInst %void %1 DebugNoScope 265fd4e5da5Sopenharmony_ciOpReturn 266fd4e5da5Sopenharmony_ciOpFunctionEnd 267fd4e5da5Sopenharmony_ci%28 = OpFunction %v4float None %19 268fd4e5da5Sopenharmony_ci%36 = OpLabel 269fd4e5da5Sopenharmony_ciOpReturnValue %14 270fd4e5da5Sopenharmony_ciOpFunctionEnd 271fd4e5da5Sopenharmony_ci)"; 272fd4e5da5Sopenharmony_ci 273fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<EliminateDeadFunctionsPass>(text, false); 274fd4e5da5Sopenharmony_ci} 275fd4e5da5Sopenharmony_ci 276fd4e5da5Sopenharmony_ciTEST_F(EliminateDeadFunctionsBasicTest, 277fd4e5da5Sopenharmony_ci DebugRemoveFunctionUsingExistingDebugInfoNone) { 278fd4e5da5Sopenharmony_ci // We want to remove id of OpFunction from DebugFunction. 279fd4e5da5Sopenharmony_ci const std::string text = R"(OpCapability Shader 280fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "OpenCL.DebugInfo.100" 281fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 282fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %2 "main" %3 %4 283fd4e5da5Sopenharmony_ciOpExecutionMode %2 OriginUpperLeft 284fd4e5da5Sopenharmony_ci%5 = OpString "ps.hlsl" 285fd4e5da5Sopenharmony_ciOpSource HLSL 600 %5 "float4 foo() { 286fd4e5da5Sopenharmony_ci return 1; 287fd4e5da5Sopenharmony_ci} 288fd4e5da5Sopenharmony_cifloat4 main(float4 color : COLOR) : SV_TARGET { 289fd4e5da5Sopenharmony_ci return foo() + color; 290fd4e5da5Sopenharmony_ci} 291fd4e5da5Sopenharmony_ci" 292fd4e5da5Sopenharmony_ci%6 = OpString "float" 293fd4e5da5Sopenharmony_ci%7 = OpString "main" 294fd4e5da5Sopenharmony_ci%8 = OpString "foo" 295fd4e5da5Sopenharmony_ci; CHECK: [[foo:%\d+]] = OpString "foo" 296fd4e5da5Sopenharmony_ciOpDecorate %3 Location 0 297fd4e5da5Sopenharmony_ciOpDecorate %4 Location 0 298fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 299fd4e5da5Sopenharmony_ci%uint_32 = OpConstant %uint 32 300fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 301fd4e5da5Sopenharmony_ci%float_1 = OpConstant %float 1 302fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4 303fd4e5da5Sopenharmony_ci%14 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1 304fd4e5da5Sopenharmony_ci%_ptr_Input_v4float = OpTypePointer Input %v4float 305fd4e5da5Sopenharmony_ci%_ptr_Output_v4float = OpTypePointer Output %v4float 306fd4e5da5Sopenharmony_ci%void = OpTypeVoid 307fd4e5da5Sopenharmony_ci%18 = OpTypeFunction %void 308fd4e5da5Sopenharmony_ci%19 = OpTypeFunction %v4float 309fd4e5da5Sopenharmony_ci%3 = OpVariable %_ptr_Input_v4float Input 310fd4e5da5Sopenharmony_ci%4 = OpVariable %_ptr_Output_v4float Output 311fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float 312fd4e5da5Sopenharmony_ci; CHECK: [[info_none:%\d+]] = OpExtInst %void %1 DebugInfoNone 313fd4e5da5Sopenharmony_ci%20 = OpExtInst %void %1 DebugSource %5 314fd4e5da5Sopenharmony_ci%21 = OpExtInst %void %1 DebugCompilationUnit 1 4 %20 HLSL 315fd4e5da5Sopenharmony_ci%22 = OpExtInst %void %1 DebugTypeBasic %6 %uint_32 Float 316fd4e5da5Sopenharmony_ci%23 = OpExtInst %void %1 DebugTypeVector %22 4 317fd4e5da5Sopenharmony_ci%24 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %23 %23 318fd4e5da5Sopenharmony_ci%25 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %23 319fd4e5da5Sopenharmony_ci%26 = OpExtInst %void %1 DebugFunction %7 %24 %20 4 1 %21 %7 FlagIsProtected|FlagIsPrivate 4 %2 320fd4e5da5Sopenharmony_ci%27 = OpExtInst %void %1 DebugFunction %8 %25 %20 1 1 %21 %8 FlagIsProtected|FlagIsPrivate 1 %28 321fd4e5da5Sopenharmony_ci; CHECK: {{%\d+}} = OpExtInst %void %1 DebugFunction [[foo]] {{%\d+}} {{%\d+}} 1 1 {{%\d+}} {{%\d+}} FlagIsProtected|FlagIsPrivate 1 [[info_none]] 322fd4e5da5Sopenharmony_ci%29 = OpExtInst %void %1 DebugLexicalBlock %20 1 14 %27 323fd4e5da5Sopenharmony_ci%35 = OpExtInst %void %1 DebugInfoNone 324fd4e5da5Sopenharmony_ci%40 = OpExtInst %void %1 DebugInlinedAt 4 %26 325fd4e5da5Sopenharmony_ci%2 = OpFunction %void None %18 326fd4e5da5Sopenharmony_ci%30 = OpLabel 327fd4e5da5Sopenharmony_ci%39 = OpVariable %_ptr_Function_v4float Function 328fd4e5da5Sopenharmony_ci%41 = OpExtInst %void %1 DebugScope %27 %40 329fd4e5da5Sopenharmony_ciOpStore %39 %14 330fd4e5da5Sopenharmony_ci%32 = OpLoad %v4float %39 331fd4e5da5Sopenharmony_ci%42 = OpExtInst %void %1 DebugScope %26 332fd4e5da5Sopenharmony_ci%33 = OpLoad %v4float %3 333fd4e5da5Sopenharmony_ci%34 = OpFAdd %v4float %32 %33 334fd4e5da5Sopenharmony_ciOpStore %4 %34 335fd4e5da5Sopenharmony_ci%43 = OpExtInst %void %1 DebugNoScope 336fd4e5da5Sopenharmony_ciOpReturn 337fd4e5da5Sopenharmony_ciOpFunctionEnd 338fd4e5da5Sopenharmony_ci%28 = OpFunction %v4float None %19 339fd4e5da5Sopenharmony_ci%36 = OpLabel 340fd4e5da5Sopenharmony_ciOpReturnValue %14 341fd4e5da5Sopenharmony_ciOpFunctionEnd 342fd4e5da5Sopenharmony_ci)"; 343fd4e5da5Sopenharmony_ci 344fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<EliminateDeadFunctionsPass>(text, false); 345fd4e5da5Sopenharmony_ci} 346fd4e5da5Sopenharmony_ci 347fd4e5da5Sopenharmony_ciTEST_F(EliminateDeadFunctionsBasicTest, NonSemanticInfoPersists) { 348fd4e5da5Sopenharmony_ci const std::string text = R"( 349fd4e5da5Sopenharmony_ci; CHECK: [[import:%\w+]] = OpExtInstImport 350fd4e5da5Sopenharmony_ci; CHECK: [[void:%\w+]] = OpTypeVoid 351fd4e5da5Sopenharmony_ci; CHECK-NOT: OpExtInst [[void]] [[import]] 1 352fd4e5da5Sopenharmony_ci; CHECK: OpExtInst [[void]] [[import]] 2 353fd4e5da5Sopenharmony_ciOpCapability Shader 354fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_non_semantic_info" 355fd4e5da5Sopenharmony_ci%ext = OpExtInstImport "NonSemantic.Test" 356fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 357fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %main "main" 358fd4e5da5Sopenharmony_ciOpExecutionMode %main LocalSize 1 1 1 359fd4e5da5Sopenharmony_ci%void = OpTypeVoid 360fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 361fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn 362fd4e5da5Sopenharmony_ci%entry = OpLabel 363fd4e5da5Sopenharmony_ciOpReturn 364fd4e5da5Sopenharmony_ciOpFunctionEnd 365fd4e5da5Sopenharmony_ci%foo = OpFunction %void None %void_fn 366fd4e5da5Sopenharmony_ci%foo_entry = OpLabel 367fd4e5da5Sopenharmony_ci%non_semantic1 = OpExtInst %void %ext 1 368fd4e5da5Sopenharmony_ciOpReturn 369fd4e5da5Sopenharmony_ciOpFunctionEnd 370fd4e5da5Sopenharmony_ci%non_semantic2 = OpExtInst %void %ext 2 371fd4e5da5Sopenharmony_ci)"; 372fd4e5da5Sopenharmony_ci 373fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<EliminateDeadFunctionsPass>(text, true); 374fd4e5da5Sopenharmony_ci} 375fd4e5da5Sopenharmony_ci 376fd4e5da5Sopenharmony_ciTEST_F(EliminateDeadFunctionsBasicTest, NonSemanticInfoRemoveDependent) { 377fd4e5da5Sopenharmony_ci const std::string text = R"( 378fd4e5da5Sopenharmony_ci; CHECK: [[import:%\w+]] = OpExtInstImport 379fd4e5da5Sopenharmony_ci; CHECK: [[void:%\w+]] = OpTypeVoid 380fd4e5da5Sopenharmony_ci; CHECK-NOT: OpExtInst [[void]] [[import]] 1 381fd4e5da5Sopenharmony_ci; CHECK-NOT: OpExtInst [[void]] [[import]] 2 382fd4e5da5Sopenharmony_ci; CHECK: OpExtInst [[void]] [[import]] 3 383fd4e5da5Sopenharmony_ciOpCapability Shader 384fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_non_semantic_info" 385fd4e5da5Sopenharmony_ci%ext = OpExtInstImport "NonSemantic.Test" 386fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 387fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %main "main" 388fd4e5da5Sopenharmony_ciOpExecutionMode %main LocalSize 1 1 1 389fd4e5da5Sopenharmony_ci%void = OpTypeVoid 390fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 391fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn 392fd4e5da5Sopenharmony_ci%entry = OpLabel 393fd4e5da5Sopenharmony_ciOpReturn 394fd4e5da5Sopenharmony_ciOpFunctionEnd 395fd4e5da5Sopenharmony_ci%foo = OpFunction %void None %void_fn 396fd4e5da5Sopenharmony_ci%foo_entry = OpLabel 397fd4e5da5Sopenharmony_ci%non_semantic1 = OpExtInst %void %ext 1 398fd4e5da5Sopenharmony_ciOpReturn 399fd4e5da5Sopenharmony_ciOpFunctionEnd 400fd4e5da5Sopenharmony_ci%non_semantic2 = OpExtInst %void %ext 2 %foo 401fd4e5da5Sopenharmony_ci%non_semantic3 = OpExtInst %void %ext 3 402fd4e5da5Sopenharmony_ci)"; 403fd4e5da5Sopenharmony_ci 404fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<EliminateDeadFunctionsPass>(text, true); 405fd4e5da5Sopenharmony_ci} 406fd4e5da5Sopenharmony_ci 407fd4e5da5Sopenharmony_ciTEST_F(EliminateDeadFunctionsBasicTest, NonSemanticInfoRemoveDependentTree) { 408fd4e5da5Sopenharmony_ci const std::string text = R"( 409fd4e5da5Sopenharmony_ci; CHECK: [[import:%\w+]] = OpExtInstImport 410fd4e5da5Sopenharmony_ci; CHECK: [[void:%\w+]] = OpTypeVoid 411fd4e5da5Sopenharmony_ci; CHECK-NOT: OpExtInst [[void]] [[import]] 1 412fd4e5da5Sopenharmony_ci; CHECK-NOT: OpExtInst [[void]] [[import]] 2 413fd4e5da5Sopenharmony_ci; CHECK: OpExtInst [[void]] [[import]] 3 414fd4e5da5Sopenharmony_ci; CHECK-NOT: OpExtInst [[void]] [[import]] 4 415fd4e5da5Sopenharmony_ci; CHECK-NOT: OpExtInst [[void]] [[import]] 5 416fd4e5da5Sopenharmony_ciOpCapability Shader 417fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_non_semantic_info" 418fd4e5da5Sopenharmony_ci%ext = OpExtInstImport "NonSemantic.Test" 419fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 420fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %main "main" 421fd4e5da5Sopenharmony_ciOpExecutionMode %main LocalSize 1 1 1 422fd4e5da5Sopenharmony_ci%void = OpTypeVoid 423fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 424fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn 425fd4e5da5Sopenharmony_ci%entry = OpLabel 426fd4e5da5Sopenharmony_ciOpReturn 427fd4e5da5Sopenharmony_ciOpFunctionEnd 428fd4e5da5Sopenharmony_ci%foo = OpFunction %void None %void_fn 429fd4e5da5Sopenharmony_ci%foo_entry = OpLabel 430fd4e5da5Sopenharmony_ci%non_semantic1 = OpExtInst %void %ext 1 431fd4e5da5Sopenharmony_ciOpReturn 432fd4e5da5Sopenharmony_ciOpFunctionEnd 433fd4e5da5Sopenharmony_ci%non_semantic2 = OpExtInst %void %ext 2 %foo 434fd4e5da5Sopenharmony_ci%non_semantic3 = OpExtInst %void %ext 3 435fd4e5da5Sopenharmony_ci%non_semantic4 = OpExtInst %void %ext 4 %non_semantic2 436fd4e5da5Sopenharmony_ci%non_semantic5 = OpExtInst %void %ext 5 %non_semantic4 437fd4e5da5Sopenharmony_ci)"; 438fd4e5da5Sopenharmony_ci 439fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<EliminateDeadFunctionsPass>(text, true); 440fd4e5da5Sopenharmony_ci} 441fd4e5da5Sopenharmony_ci 442fd4e5da5Sopenharmony_ciTEST_F(EliminateDeadFunctionsBasicTest, NonSemanticInfoRemoveDebugPrintf) { 443fd4e5da5Sopenharmony_ci const std::string text = R"( 444fd4e5da5Sopenharmony_ci; CHECK-NOT: %foo_ = OpFunction %void None % 3 445fd4e5da5Sopenharmony_ci; CHECK-NOT: % 7 = OpLabel 446fd4e5da5Sopenharmony_ci; CHECK-NOT: %c = OpVariable %_ptr_Function_v4float Function 447fd4e5da5Sopenharmony_ci; CHECK-NOT: % 22 = OpAccessChain %_ptr_UniformConstant_13 %samplers %int_0 448fd4e5da5Sopenharmony_ci; CHECK-NOT: % 23 = OpLoad % 13 % 22 449fd4e5da5Sopenharmony_ci; CHECK-NOT: % 27 = OpImageSampleExplicitLod %v4float % 23 % 26 Lod %float_0 450fd4e5da5Sopenharmony_ci; CHECK-NOT: OpStore %c % 27 451fd4e5da5Sopenharmony_ci; CHECK-NOT: % 31 = OpAccessChain %_ptr_Function_float %c %uint_0 452fd4e5da5Sopenharmony_ci; CHECK-NOT: % 32 = OpLoad %float %31 453fd4e5da5Sopenharmony_ci; CHECK-NOT: % 34 = OpExtInst %void %33 1 % 28 % 32 454fd4e5da5Sopenharmony_ciOpCapability RayTracingKHR 455fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_non_semantic_info" 456fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_ray_tracing" 457fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450" 458fd4e5da5Sopenharmony_ci%33 = OpExtInstImport "NonSemantic.DebugPrintf" 459fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 460fd4e5da5Sopenharmony_ciOpEntryPoint ClosestHitNV %main "main" %samplers 461fd4e5da5Sopenharmony_ci%28 = OpString "%f" 462fd4e5da5Sopenharmony_ciOpSource GLSL 460 463fd4e5da5Sopenharmony_ciOpSourceExtension "GL_EXT_debug_printf" 464fd4e5da5Sopenharmony_ciOpName %main "main" 465fd4e5da5Sopenharmony_ciOpName %foo_ "foo(" 466fd4e5da5Sopenharmony_ciOpName %c "c" 467fd4e5da5Sopenharmony_ciOpName %samplers "samplers" 468fd4e5da5Sopenharmony_ciOpDecorate %samplers DescriptorSet 0 469fd4e5da5Sopenharmony_ciOpDecorate %samplers Binding 0 470fd4e5da5Sopenharmony_ci%void = OpTypeVoid 471fd4e5da5Sopenharmony_ci%3 = OpTypeFunction %void 472fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32 473fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4 474fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float 475fd4e5da5Sopenharmony_ci%12 = OpTypeImage %float 3D 0 0 0 1 Unknown 476fd4e5da5Sopenharmony_ci%13 = OpTypeSampledImage %12 477fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0 478fd4e5da5Sopenharmony_ci%uint_1 = OpConstant %uint 1 479fd4e5da5Sopenharmony_ci%_arr_13_uint_1 = OpTypeArray %13 %uint_1 480fd4e5da5Sopenharmony_ci%_ptr_UniformConstant__arr_13_uint_1 = OpTypePointer UniformConstant %_arr_13_uint_1 481fd4e5da5Sopenharmony_ci%samplers = OpVariable %_ptr_UniformConstant__arr_13_uint_1 UniformConstant 482fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 1 483fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0 484fd4e5da5Sopenharmony_ci%_ptr_UniformConstant_13 = OpTypePointer UniformConstant %13 485fd4e5da5Sopenharmony_ci%v3float = OpTypeVector %float 3 486fd4e5da5Sopenharmony_ci%float_0 = OpConstant %float 0 487fd4e5da5Sopenharmony_ci%26 = OpConstantComposite %v3float %float_0 %float_0 %float_0 488fd4e5da5Sopenharmony_ci%uint_0 = OpConstant %uint 0 489fd4e5da5Sopenharmony_ci%_ptr_Function_float = OpTypePointer Function %float 490fd4e5da5Sopenharmony_ci%main = OpFunction %void None %3 491fd4e5da5Sopenharmony_ci%5 = OpLabel 492fd4e5da5Sopenharmony_ci%36 = OpVariable %_ptr_Function_v4float Function 493fd4e5da5Sopenharmony_ci%38 = OpAccessChain %_ptr_UniformConstant_13 %samplers %int_0 494fd4e5da5Sopenharmony_ci%39 = OpLoad %13 %38 495fd4e5da5Sopenharmony_ci%40 = OpImageSampleExplicitLod %v4float %39 %26 Lod %float_0 496fd4e5da5Sopenharmony_ciOpStore %36 %40 497fd4e5da5Sopenharmony_ci%41 = OpAccessChain %_ptr_Function_float %36 %uint_0 498fd4e5da5Sopenharmony_ci%42 = OpLoad %float %41 499fd4e5da5Sopenharmony_ci%43 = OpExtInst %void %33 1 %28 %42 500fd4e5da5Sopenharmony_ciOpReturn 501fd4e5da5Sopenharmony_ciOpFunctionEnd 502fd4e5da5Sopenharmony_ci%foo_ = OpFunction %void None %3 503fd4e5da5Sopenharmony_ci%7 = OpLabel 504fd4e5da5Sopenharmony_ci%c = OpVariable %_ptr_Function_v4float Function 505fd4e5da5Sopenharmony_ci%22 = OpAccessChain %_ptr_UniformConstant_13 %samplers %int_0 506fd4e5da5Sopenharmony_ci%23 = OpLoad %13 %22 507fd4e5da5Sopenharmony_ci%27 = OpImageSampleExplicitLod %v4float %23 %26 Lod %float_0 508fd4e5da5Sopenharmony_ciOpStore %c %27 509fd4e5da5Sopenharmony_ci%31 = OpAccessChain %_ptr_Function_float %c %uint_0 510fd4e5da5Sopenharmony_ci%32 = OpLoad %float %31 511fd4e5da5Sopenharmony_ci%34 = OpExtInst %void %33 1 %28 %32 512fd4e5da5Sopenharmony_ciOpReturn 513fd4e5da5Sopenharmony_ciOpFunctionEnd 514fd4e5da5Sopenharmony_ci)"; 515fd4e5da5Sopenharmony_ci 516fd4e5da5Sopenharmony_ci SetTargetEnv(SPV_ENV_VULKAN_1_2); 517fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<EliminateDeadFunctionsPass>(text, true); 518fd4e5da5Sopenharmony_ci} 519fd4e5da5Sopenharmony_ci 520fd4e5da5Sopenharmony_ciTEST_F(EliminateDeadFunctionsBasicTest, DependentNonSemanticChain) { 521fd4e5da5Sopenharmony_ci const std::string text = R"( 522fd4e5da5Sopenharmony_ci; CHECK: OpEntryPoint GLCompute [[main:%\w+]] 523fd4e5da5Sopenharmony_ci; CHECK: [[main]] = OpFunction 524fd4e5da5Sopenharmony_ci; CHECK-NOT: = OpFunction 525fd4e5da5Sopenharmony_ci; CHECK: [[ext1:%\w+]] = OpExtInst %void {{%\w+}} 1 [[main]] 526fd4e5da5Sopenharmony_ci; CHECK: [[ext2:%\w+]] = OpExtInst %void {{%\w+}} 2 [[ext1]] 527fd4e5da5Sopenharmony_ci; CHECK: [[ext3:%\w+]] = OpExtInst %void {{%\w+}} 3 [[ext1]] [[ext2]] 528fd4e5da5Sopenharmony_ciOpCapability Shader 529fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_non_semantic_info" 530fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "NonSemantic.Test" 531fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450 532fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %main "main" 533fd4e5da5Sopenharmony_ciOpExecutionMode %main LocalSize 1 1 1 534fd4e5da5Sopenharmony_ci%void = OpTypeVoid 535fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void 536fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn 537fd4e5da5Sopenharmony_ci%main_entry = OpLabel 538fd4e5da5Sopenharmony_ciOpReturn 539fd4e5da5Sopenharmony_ciOpFunctionEnd 540fd4e5da5Sopenharmony_ci%dead = OpFunction %void None %void_fn 541fd4e5da5Sopenharmony_ci%dead_entry = OpLabel 542fd4e5da5Sopenharmony_ciOpReturn 543fd4e5da5Sopenharmony_ciOpFunctionEnd 544fd4e5da5Sopenharmony_ci%2 = OpExtInst %void %1 1 %main 545fd4e5da5Sopenharmony_ci%3 = OpExtInst %void %1 2 %2 546fd4e5da5Sopenharmony_ci%4 = OpExtInst %void %1 3 %2 %3 547fd4e5da5Sopenharmony_ci)"; 548fd4e5da5Sopenharmony_ci 549fd4e5da5Sopenharmony_ci SetTargetEnv(SPV_ENV_VULKAN_1_0); 550fd4e5da5Sopenharmony_ci SinglePassRunAndMatch<EliminateDeadFunctionsPass>(text, true); 551fd4e5da5Sopenharmony_ci} 552fd4e5da5Sopenharmony_ci 553fd4e5da5Sopenharmony_ci} // namespace 554fd4e5da5Sopenharmony_ci} // namespace opt 555fd4e5da5Sopenharmony_ci} // namespace spvtools 556