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