blob: 268e659063dc18122aee2b9f556ea77cbfe2049b [file] [log] [blame]
Chris Forbescc5697f2019-01-30 11:54:08 -08001// Copyright (c) 2017 Valve Corporation
2// Copyright (c) 2017 LunarG Inc.
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16#include <string>
17
18#include "test/opt/pass_fixture.h"
19#include "test/opt/pass_utils.h"
20
21namespace spvtools {
22namespace opt {
23namespace {
24
25using DeadInsertElimTest = PassTest<::testing::Test>;
26
27TEST_F(DeadInsertElimTest, InsertAfterInsertElim) {
28 // With two insertions to the same offset, the first is dead.
29 //
30 // Note: The SPIR-V assembly has had store/load elimination
31 // performed to allow the inserts and extracts to directly
32 // reference each other.
33 //
34 // #version 450
35 //
36 // layout (location=0) in float In0;
37 // layout (location=1) in float In1;
38 // layout (location=2) in vec2 In2;
39 // layout (location=0) out vec4 OutColor;
40 //
41 // void main()
42 // {
43 // vec2 v = In2;
44 // v.x = In0 + In1; // dead
45 // v.x = 0.0;
46 // OutColor = v.xyxy;
47 // }
48
49 const std::string before_predefs =
50 R"(OpCapability Shader
51%1 = OpExtInstImport "GLSL.std.450"
52OpMemoryModel Logical GLSL450
53OpEntryPoint Fragment %main "main" %In2 %In0 %In1 %OutColor
54OpExecutionMode %main OriginUpperLeft
55OpSource GLSL 450
56OpName %main "main"
57OpName %In2 "In2"
58OpName %In0 "In0"
59OpName %In1 "In1"
60OpName %OutColor "OutColor"
61OpName %_Globals_ "_Globals_"
62OpMemberName %_Globals_ 0 "g_b"
63OpMemberName %_Globals_ 1 "g_n"
64OpName %_ ""
65OpDecorate %In2 Location 2
66OpDecorate %In0 Location 0
67OpDecorate %In1 Location 1
68OpDecorate %OutColor Location 0
69OpMemberDecorate %_Globals_ 0 Offset 0
70OpMemberDecorate %_Globals_ 1 Offset 4
71OpDecorate %_Globals_ Block
72OpDecorate %_ DescriptorSet 0
73OpDecorate %_ Binding 0
74%void = OpTypeVoid
75%11 = OpTypeFunction %void
76%float = OpTypeFloat 32
77%v2float = OpTypeVector %float 2
78%_ptr_Function_v2float = OpTypePointer Function %v2float
79%_ptr_Input_v2float = OpTypePointer Input %v2float
80%In2 = OpVariable %_ptr_Input_v2float Input
81%_ptr_Input_float = OpTypePointer Input %float
82%In0 = OpVariable %_ptr_Input_float Input
83%In1 = OpVariable %_ptr_Input_float Input
84%uint = OpTypeInt 32 0
85%_ptr_Function_float = OpTypePointer Function %float
86%float_0 = OpConstant %float 0
87%v4float = OpTypeVector %float 4
88%_ptr_Output_v4float = OpTypePointer Output %v4float
89%OutColor = OpVariable %_ptr_Output_v4float Output
90%int = OpTypeInt 32 1
91%_Globals_ = OpTypeStruct %uint %int
92%_ptr_Uniform__Globals_ = OpTypePointer Uniform %_Globals_
93%_ = OpVariable %_ptr_Uniform__Globals_ Uniform
94)";
95
96 const std::string after_predefs =
97 R"(OpCapability Shader
98%1 = OpExtInstImport "GLSL.std.450"
99OpMemoryModel Logical GLSL450
100OpEntryPoint Fragment %main "main" %In2 %In0 %In1 %OutColor
101OpExecutionMode %main OriginUpperLeft
102OpSource GLSL 450
103OpName %main "main"
104OpName %In2 "In2"
105OpName %In0 "In0"
106OpName %In1 "In1"
107OpName %OutColor "OutColor"
108OpName %_Globals_ "_Globals_"
109OpMemberName %_Globals_ 0 "g_b"
110OpMemberName %_Globals_ 1 "g_n"
111OpName %_ ""
112OpDecorate %In2 Location 2
113OpDecorate %In0 Location 0
114OpDecorate %In1 Location 1
115OpDecorate %OutColor Location 0
116OpMemberDecorate %_Globals_ 0 Offset 0
117OpMemberDecorate %_Globals_ 1 Offset 4
118OpDecorate %_Globals_ Block
119OpDecorate %_ DescriptorSet 0
120OpDecorate %_ Binding 0
121%void = OpTypeVoid
122%10 = OpTypeFunction %void
123%float = OpTypeFloat 32
124%v2float = OpTypeVector %float 2
125%_ptr_Function_v2float = OpTypePointer Function %v2float
126%_ptr_Input_v2float = OpTypePointer Input %v2float
127%In2 = OpVariable %_ptr_Input_v2float Input
128%_ptr_Input_float = OpTypePointer Input %float
129%In0 = OpVariable %_ptr_Input_float Input
130%In1 = OpVariable %_ptr_Input_float Input
131%uint = OpTypeInt 32 0
132%_ptr_Function_float = OpTypePointer Function %float
133%float_0 = OpConstant %float 0
134%v4float = OpTypeVector %float 4
135%_ptr_Output_v4float = OpTypePointer Output %v4float
136%OutColor = OpVariable %_ptr_Output_v4float Output
137%int = OpTypeInt 32 1
138%_Globals_ = OpTypeStruct %uint %int
139%_ptr_Uniform__Globals_ = OpTypePointer Uniform %_Globals_
140%_ = OpVariable %_ptr_Uniform__Globals_ Uniform
141)";
142
143 const std::string before =
144 R"(%main = OpFunction %void None %11
145%25 = OpLabel
146%26 = OpLoad %v2float %In2
147%27 = OpLoad %float %In0
148%28 = OpLoad %float %In1
149%29 = OpFAdd %float %27 %28
150%35 = OpCompositeInsert %v2float %29 %26 0
151%37 = OpCompositeInsert %v2float %float_0 %35 0
152%33 = OpVectorShuffle %v4float %37 %37 0 1 0 1
153OpStore %OutColor %33
154OpReturn
155OpFunctionEnd
156)";
157
158 const std::string after =
159 R"(%main = OpFunction %void None %10
160%23 = OpLabel
161%24 = OpLoad %v2float %In2
162%29 = OpCompositeInsert %v2float %float_0 %24 0
163%30 = OpVectorShuffle %v4float %29 %29 0 1 0 1
164OpStore %OutColor %30
165OpReturn
166OpFunctionEnd
167)";
168
169 SinglePassRunAndCheck<DeadInsertElimPass>(before_predefs + before,
170 after_predefs + after, true, true);
171}
172
Alexis Hetu00e0af12021-11-08 08:57:46 -0500173TEST_F(DeadInsertElimTest, DeadInsertForLinkage) {
174 const std::string before =
175 R"(OpCapability Shader
176OpCapability Linkage
177OpMemoryModel Logical GLSL450
178OpSource HLSL 630
179OpName %main "main"
180OpName %BaseColor "BaseColor"
181OpName %bb_entry "bb.entry"
182OpName %v "v"
183OpDecorate %main LinkageAttributes "main" Export
184%int = OpTypeInt 32 1
185%int_1 = OpConstant %int 1
186%uint = OpTypeInt 32 0
187%uint_0 = OpConstant %uint 0
188%int_0 = OpConstant %int 0
189%float = OpTypeFloat 32
190%float_0 = OpConstant %float 0
191%v2float = OpTypeVector %float 2
192%_ptr_Function_v2float = OpTypePointer Function %v2float
193%14 = OpTypeFunction %v2float %_ptr_Function_v2float
194%_ptr_Function_float = OpTypePointer Function %float
195%main = OpFunction %v2float None %14
196%BaseColor = OpFunctionParameter %_ptr_Function_v2float
197%bb_entry = OpLabel
198%v = OpVariable %_ptr_Function_v2float Function
199%16 = OpLoad %v2float %v
200%17 = OpAccessChain %_ptr_Function_float %BaseColor %int_1
201%18 = OpLoad %float %17
202%19 = OpCompositeInsert %v2float %18 %16 0
203%20 = OpCompositeInsert %v2float %float_0 %19 0
204OpReturnValue %20
205OpFunctionEnd
206)";
207 const std::string after =
208 R"(OpCapability Shader
209OpCapability Linkage
210OpMemoryModel Logical GLSL450
211OpSource HLSL 630
212OpName %main "main"
213OpName %BaseColor "BaseColor"
214OpName %bb_entry "bb.entry"
215OpName %v "v"
216OpDecorate %main LinkageAttributes "main" Export
217%int = OpTypeInt 32 1
218%uint = OpTypeInt 32 0
219%uint_0 = OpConstant %uint 0
220%int_0 = OpConstant %int 0
221%float = OpTypeFloat 32
222%float_0 = OpConstant %float 0
223%v2float = OpTypeVector %float 2
224%_ptr_Function_v2float = OpTypePointer Function %v2float
225%14 = OpTypeFunction %v2float %_ptr_Function_v2float
226%_ptr_Function_float = OpTypePointer Function %float
227%main = OpFunction %v2float None %14
228%BaseColor = OpFunctionParameter %_ptr_Function_v2float
229%bb_entry = OpLabel
230%v = OpVariable %_ptr_Function_v2float Function
231%16 = OpLoad %v2float %v
232%20 = OpCompositeInsert %v2float %float_0 %16 0
233OpReturnValue %20
234OpFunctionEnd
235)";
236 SinglePassRunAndCheck<DeadInsertElimPass>(before, after, true, true);
237}
238
Chris Forbescc5697f2019-01-30 11:54:08 -0800239TEST_F(DeadInsertElimTest, DeadInsertInChainWithPhi) {
240 // Dead insert eliminated with phi in insertion chain.
241 //
242 // Note: The SPIR-V assembly has had store/load elimination
243 // performed to allow the inserts and extracts to directly
244 // reference each other.
245 //
246 // #version 450
247 //
248 // layout (location=0) in vec4 In0;
249 // layout (location=1) in float In1;
250 // layout (location=2) in float In2;
251 // layout (location=0) out vec4 OutColor;
252 //
253 // layout(std140, binding = 0 ) uniform _Globals_
254 // {
255 // bool g_b;
256 // };
257 //
258 // void main()
259 // {
260 // vec4 v = In0;
261 // v.z = In1 + In2;
262 // if (g_b) v.w = 1.0;
263 // OutColor = vec4(v.x,v.y,0.0,v.w);
264 // }
265
266 const std::string before_predefs =
267 R"(OpCapability Shader
268%1 = OpExtInstImport "GLSL.std.450"
269OpMemoryModel Logical GLSL450
270OpEntryPoint Fragment %main "main" %In0 %In1 %In2 %OutColor
271OpExecutionMode %main OriginUpperLeft
272OpSource GLSL 450
273OpName %main "main"
274OpName %In0 "In0"
275OpName %In1 "In1"
276OpName %In2 "In2"
277OpName %_Globals_ "_Globals_"
278OpMemberName %_Globals_ 0 "g_b"
279OpName %_ ""
280OpName %OutColor "OutColor"
281OpDecorate %In0 Location 0
282OpDecorate %In1 Location 1
283OpDecorate %In2 Location 2
284OpMemberDecorate %_Globals_ 0 Offset 0
285OpDecorate %_Globals_ Block
286OpDecorate %_ DescriptorSet 0
287OpDecorate %_ Binding 0
288OpDecorate %OutColor Location 0
289%void = OpTypeVoid
290%11 = OpTypeFunction %void
291%float = OpTypeFloat 32
292%v4float = OpTypeVector %float 4
293%_ptr_Function_v4float = OpTypePointer Function %v4float
294%_ptr_Input_v4float = OpTypePointer Input %v4float
295%In0 = OpVariable %_ptr_Input_v4float Input
296%_ptr_Input_float = OpTypePointer Input %float
297%In1 = OpVariable %_ptr_Input_float Input
298%In2 = OpVariable %_ptr_Input_float Input
299%uint = OpTypeInt 32 0
300%_ptr_Function_float = OpTypePointer Function %float
301%_Globals_ = OpTypeStruct %uint
302%_ptr_Uniform__Globals_ = OpTypePointer Uniform %_Globals_
303%_ = OpVariable %_ptr_Uniform__Globals_ Uniform
304%int = OpTypeInt 32 1
305%int_0 = OpConstant %int 0
306%_ptr_Uniform_uint = OpTypePointer Uniform %uint
307%bool = OpTypeBool
308%uint_0 = OpConstant %uint 0
309%float_1 = OpConstant %float 1
310%_ptr_Output_v4float = OpTypePointer Output %v4float
311%OutColor = OpVariable %_ptr_Output_v4float Output
312%float_0 = OpConstant %float 0
313)";
314
315 const std::string after_predefs =
316 R"(OpCapability Shader
317%1 = OpExtInstImport "GLSL.std.450"
318OpMemoryModel Logical GLSL450
319OpEntryPoint Fragment %main "main" %In0 %In1 %In2 %OutColor
320OpExecutionMode %main OriginUpperLeft
321OpSource GLSL 450
322OpName %main "main"
323OpName %In0 "In0"
324OpName %In1 "In1"
325OpName %In2 "In2"
326OpName %_Globals_ "_Globals_"
327OpMemberName %_Globals_ 0 "g_b"
328OpName %_ ""
329OpName %OutColor "OutColor"
330OpDecorate %In0 Location 0
331OpDecorate %In1 Location 1
332OpDecorate %In2 Location 2
333OpMemberDecorate %_Globals_ 0 Offset 0
334OpDecorate %_Globals_ Block
335OpDecorate %_ DescriptorSet 0
336OpDecorate %_ Binding 0
337OpDecorate %OutColor Location 0
338%void = OpTypeVoid
339%10 = OpTypeFunction %void
340%float = OpTypeFloat 32
341%v4float = OpTypeVector %float 4
342%_ptr_Function_v4float = OpTypePointer Function %v4float
343%_ptr_Input_v4float = OpTypePointer Input %v4float
344%In0 = OpVariable %_ptr_Input_v4float Input
345%_ptr_Input_float = OpTypePointer Input %float
346%In1 = OpVariable %_ptr_Input_float Input
347%In2 = OpVariable %_ptr_Input_float Input
348%uint = OpTypeInt 32 0
349%_ptr_Function_float = OpTypePointer Function %float
350%_Globals_ = OpTypeStruct %uint
351%_ptr_Uniform__Globals_ = OpTypePointer Uniform %_Globals_
352%_ = OpVariable %_ptr_Uniform__Globals_ Uniform
353%int = OpTypeInt 32 1
354%int_0 = OpConstant %int 0
355%_ptr_Uniform_uint = OpTypePointer Uniform %uint
356%bool = OpTypeBool
357%uint_0 = OpConstant %uint 0
358%float_1 = OpConstant %float 1
359%_ptr_Output_v4float = OpTypePointer Output %v4float
360%OutColor = OpVariable %_ptr_Output_v4float Output
361%float_0 = OpConstant %float 0
362)";
363
364 const std::string before =
365 R"(%main = OpFunction %void None %11
366%31 = OpLabel
367%32 = OpLoad %v4float %In0
368%33 = OpLoad %float %In1
369%34 = OpLoad %float %In2
370%35 = OpFAdd %float %33 %34
371%51 = OpCompositeInsert %v4float %35 %32 2
372%37 = OpAccessChain %_ptr_Uniform_uint %_ %int_0
373%38 = OpLoad %uint %37
374%39 = OpINotEqual %bool %38 %uint_0
375OpSelectionMerge %40 None
376OpBranchConditional %39 %41 %40
377%41 = OpLabel
378%53 = OpCompositeInsert %v4float %float_1 %51 3
379OpBranch %40
380%40 = OpLabel
381%60 = OpPhi %v4float %51 %31 %53 %41
382%55 = OpCompositeExtract %float %60 0
383%57 = OpCompositeExtract %float %60 1
384%59 = OpCompositeExtract %float %60 3
385%49 = OpCompositeConstruct %v4float %55 %57 %float_0 %59
386OpStore %OutColor %49
387OpReturn
388OpFunctionEnd
389)";
390
391 const std::string after =
392 R"(%main = OpFunction %void None %10
393%27 = OpLabel
394%28 = OpLoad %v4float %In0
395%33 = OpAccessChain %_ptr_Uniform_uint %_ %int_0
396%34 = OpLoad %uint %33
397%35 = OpINotEqual %bool %34 %uint_0
398OpSelectionMerge %36 None
399OpBranchConditional %35 %37 %36
400%37 = OpLabel
401%38 = OpCompositeInsert %v4float %float_1 %28 3
402OpBranch %36
403%36 = OpLabel
404%39 = OpPhi %v4float %28 %27 %38 %37
405%40 = OpCompositeExtract %float %39 0
406%41 = OpCompositeExtract %float %39 1
407%42 = OpCompositeExtract %float %39 3
408%43 = OpCompositeConstruct %v4float %40 %41 %float_0 %42
409OpStore %OutColor %43
410OpReturn
411OpFunctionEnd
412)";
413
414 SinglePassRunAndCheck<DeadInsertElimPass>(before_predefs + before,
415 after_predefs + after, true, true);
416}
417
418TEST_F(DeadInsertElimTest, DeadInsertTwoPasses) {
419 // Dead insert which requires two passes to eliminate
420 //
421 // Note: The SPIR-V assembly has had store/load elimination
422 // performed to allow the inserts and extracts to directly
423 // reference each other.
424 //
425 // #version 450
426 //
427 // layout (location=0) in vec4 In0;
428 // layout (location=1) in float In1;
429 // layout (location=2) in float In2;
430 // layout (location=0) out vec4 OutColor;
431 //
432 // layout(std140, binding = 0 ) uniform _Globals_
433 // {
434 // bool g_b;
435 // bool g_b2;
436 // };
437 //
438 // void main()
439 // {
440 // vec4 v1, v2;
441 // v1 = In0;
442 // v1.y = In1 + In2; // dead, second pass
443 // if (g_b) v1.x = 1.0;
444 // v2.x = v1.x;
445 // v2.y = v1.y; // dead, first pass
446 // if (g_b2) v2.x = 0.0;
447 // OutColor = vec4(v2.x,v2.x,0.0,1.0);
448 // }
449
450 const std::string before_predefs =
451 R"(OpCapability Shader
452%1 = OpExtInstImport "GLSL.std.450"
453OpMemoryModel Logical GLSL450
454OpEntryPoint Fragment %main "main" %In0 %In1 %In2 %OutColor
455OpExecutionMode %main OriginUpperLeft
456OpSource GLSL 450
457OpName %main "main"
458OpName %In0 "In0"
459OpName %In1 "In1"
460OpName %In2 "In2"
461OpName %_Globals_ "_Globals_"
462OpMemberName %_Globals_ 0 "g_b"
463OpMemberName %_Globals_ 1 "g_b2"
464OpName %_ ""
465OpName %OutColor "OutColor"
466OpDecorate %In0 Location 0
467OpDecorate %In1 Location 1
468OpDecorate %In2 Location 2
469OpMemberDecorate %_Globals_ 0 Offset 0
470OpMemberDecorate %_Globals_ 1 Offset 4
471OpDecorate %_Globals_ Block
472OpDecorate %_ DescriptorSet 0
473OpDecorate %_ Binding 0
474OpDecorate %OutColor Location 0
475%void = OpTypeVoid
476%10 = OpTypeFunction %void
477%float = OpTypeFloat 32
478%v4float = OpTypeVector %float 4
479%_ptr_Function_v4float = OpTypePointer Function %v4float
480%_ptr_Input_v4float = OpTypePointer Input %v4float
481%In0 = OpVariable %_ptr_Input_v4float Input
482%_ptr_Input_float = OpTypePointer Input %float
483%In1 = OpVariable %_ptr_Input_float Input
484%In2 = OpVariable %_ptr_Input_float Input
485%uint = OpTypeInt 32 0
486%_Globals_ = OpTypeStruct %uint %uint
487%_ptr_Uniform__Globals_ = OpTypePointer Uniform %_Globals_
488%_ = OpVariable %_ptr_Uniform__Globals_ Uniform
489%int = OpTypeInt 32 1
490%int_0 = OpConstant %int 0
491%_ptr_Uniform_uint = OpTypePointer Uniform %uint
492%bool = OpTypeBool
493%uint_0 = OpConstant %uint 0
494%float_1 = OpConstant %float 1
495%int_1 = OpConstant %int 1
496%float_0 = OpConstant %float 0
497%_ptr_Output_v4float = OpTypePointer Output %v4float
498%OutColor = OpVariable %_ptr_Output_v4float Output
499%27 = OpUndef %v4float
500)";
501
502 const std::string after_predefs =
503 R"(OpCapability Shader
504%1 = OpExtInstImport "GLSL.std.450"
505OpMemoryModel Logical GLSL450
506OpEntryPoint Fragment %main "main" %In0 %In1 %In2 %OutColor
507OpExecutionMode %main OriginUpperLeft
508OpSource GLSL 450
509OpName %main "main"
510OpName %In0 "In0"
511OpName %In1 "In1"
512OpName %In2 "In2"
513OpName %_Globals_ "_Globals_"
514OpMemberName %_Globals_ 0 "g_b"
515OpMemberName %_Globals_ 1 "g_b2"
516OpName %_ ""
517OpName %OutColor "OutColor"
518OpDecorate %In0 Location 0
519OpDecorate %In1 Location 1
520OpDecorate %In2 Location 2
521OpMemberDecorate %_Globals_ 0 Offset 0
522OpMemberDecorate %_Globals_ 1 Offset 4
523OpDecorate %_Globals_ Block
524OpDecorate %_ DescriptorSet 0
525OpDecorate %_ Binding 0
526OpDecorate %OutColor Location 0
527%void = OpTypeVoid
528%10 = OpTypeFunction %void
529%float = OpTypeFloat 32
530%v4float = OpTypeVector %float 4
531%_ptr_Function_v4float = OpTypePointer Function %v4float
532%_ptr_Input_v4float = OpTypePointer Input %v4float
533%In0 = OpVariable %_ptr_Input_v4float Input
534%_ptr_Input_float = OpTypePointer Input %float
535%In1 = OpVariable %_ptr_Input_float Input
536%In2 = OpVariable %_ptr_Input_float Input
537%uint = OpTypeInt 32 0
538%_Globals_ = OpTypeStruct %uint %uint
539%_ptr_Uniform__Globals_ = OpTypePointer Uniform %_Globals_
540%_ = OpVariable %_ptr_Uniform__Globals_ Uniform
541%int = OpTypeInt 32 1
542%int_0 = OpConstant %int 0
543%_ptr_Uniform_uint = OpTypePointer Uniform %uint
544%bool = OpTypeBool
545%uint_0 = OpConstant %uint 0
546%float_1 = OpConstant %float 1
547%int_1 = OpConstant %int 1
548%float_0 = OpConstant %float 0
549%_ptr_Output_v4float = OpTypePointer Output %v4float
550%OutColor = OpVariable %_ptr_Output_v4float Output
551%27 = OpUndef %v4float
552)";
553
554 const std::string before =
555 R"(%main = OpFunction %void None %10
556%28 = OpLabel
557%29 = OpLoad %v4float %In0
558%30 = OpLoad %float %In1
559%31 = OpLoad %float %In2
560%32 = OpFAdd %float %30 %31
561%33 = OpCompositeInsert %v4float %32 %29 1
562%34 = OpAccessChain %_ptr_Uniform_uint %_ %int_0
563%35 = OpLoad %uint %34
564%36 = OpINotEqual %bool %35 %uint_0
565OpSelectionMerge %37 None
566OpBranchConditional %36 %38 %37
567%38 = OpLabel
568%39 = OpCompositeInsert %v4float %float_1 %33 0
569OpBranch %37
570%37 = OpLabel
571%40 = OpPhi %v4float %33 %28 %39 %38
572%41 = OpCompositeExtract %float %40 0
573%42 = OpCompositeInsert %v4float %41 %27 0
574%43 = OpCompositeExtract %float %40 1
575%44 = OpCompositeInsert %v4float %43 %42 1
576%45 = OpAccessChain %_ptr_Uniform_uint %_ %int_1
577%46 = OpLoad %uint %45
578%47 = OpINotEqual %bool %46 %uint_0
579OpSelectionMerge %48 None
580OpBranchConditional %47 %49 %48
581%49 = OpLabel
582%50 = OpCompositeInsert %v4float %float_0 %44 0
583OpBranch %48
584%48 = OpLabel
585%51 = OpPhi %v4float %44 %37 %50 %49
586%52 = OpCompositeExtract %float %51 0
587%53 = OpCompositeExtract %float %51 0
588%54 = OpCompositeConstruct %v4float %52 %53 %float_0 %float_1
589OpStore %OutColor %54
590OpReturn
591OpFunctionEnd
592)";
593
594 const std::string after =
595 R"(%main = OpFunction %void None %10
596%28 = OpLabel
597%29 = OpLoad %v4float %In0
598%34 = OpAccessChain %_ptr_Uniform_uint %_ %int_0
599%35 = OpLoad %uint %34
600%36 = OpINotEqual %bool %35 %uint_0
601OpSelectionMerge %37 None
602OpBranchConditional %36 %38 %37
603%38 = OpLabel
604%39 = OpCompositeInsert %v4float %float_1 %29 0
605OpBranch %37
606%37 = OpLabel
607%40 = OpPhi %v4float %29 %28 %39 %38
608%41 = OpCompositeExtract %float %40 0
609%42 = OpCompositeInsert %v4float %41 %27 0
610%45 = OpAccessChain %_ptr_Uniform_uint %_ %int_1
611%46 = OpLoad %uint %45
612%47 = OpINotEqual %bool %46 %uint_0
613OpSelectionMerge %48 None
614OpBranchConditional %47 %49 %48
615%49 = OpLabel
616%50 = OpCompositeInsert %v4float %float_0 %42 0
617OpBranch %48
618%48 = OpLabel
619%51 = OpPhi %v4float %42 %37 %50 %49
620%52 = OpCompositeExtract %float %51 0
621%53 = OpCompositeExtract %float %51 0
622%54 = OpCompositeConstruct %v4float %52 %53 %float_0 %float_1
623OpStore %OutColor %54
624OpReturn
625OpFunctionEnd
626)";
627
628 SinglePassRunAndCheck<DeadInsertElimPass>(before_predefs + before,
629 after_predefs + after, true, true);
630}
631
Alexis Hetu3eb4dd82020-10-29 21:37:20 -0400632TEST_F(DeadInsertElimTest, DebugInsertAfterInsertElim) {
633 // With two insertions to the same offset, the first is dead.
634 //
635 // Note: The SPIR-V assembly has had store/load elimination
636 // performed to allow the inserts and extracts to directly
637 // reference each other.
638 //
639 // #version 450
640 //
641 // layout (location=0) in float In0;
642 // layout (location=1) in float In1;
643 // layout (location=2) in vec2 In2;
644 // layout (location=0) out vec4 OutColor;
645 //
646 // void main()
647 // {
648 // vec2 v = In2;
649 // v.x = In0 + In1; // dead
650 // v.x = 0.0;
651 // OutColor = v.xyxy;
652 // }
653
654 const std::string text =
655 R"(OpCapability Shader
656%1 = OpExtInstImport "GLSL.std.450"
657%ext = OpExtInstImport "OpenCL.DebugInfo.100"
658OpMemoryModel Logical GLSL450
659OpEntryPoint Fragment %main "main" %In2 %In0 %In1 %OutColor
660OpExecutionMode %main OriginUpperLeft
661OpSource GLSL 450
662%file_name = OpString "test"
663%float_name = OpString "float"
664%main_name = OpString "main"
665%f_name = OpString "f"
666OpName %main "main"
667OpName %In2 "In2"
668OpName %In0 "In0"
669OpName %In1 "In1"
670OpName %OutColor "OutColor"
671OpName %_Globals_ "_Globals_"
672OpMemberName %_Globals_ 0 "g_b"
673OpMemberName %_Globals_ 1 "g_n"
674OpName %_ ""
675OpDecorate %In2 Location 2
676OpDecorate %In0 Location 0
677OpDecorate %In1 Location 1
678OpDecorate %OutColor Location 0
679OpMemberDecorate %_Globals_ 0 Offset 0
680OpMemberDecorate %_Globals_ 1 Offset 4
681OpDecorate %_Globals_ Block
682OpDecorate %_ DescriptorSet 0
683OpDecorate %_ Binding 0
684%void = OpTypeVoid
685%11 = OpTypeFunction %void
686%float = OpTypeFloat 32
687%v2float = OpTypeVector %float 2
688%_ptr_Function_v2float = OpTypePointer Function %v2float
689%_ptr_Input_v2float = OpTypePointer Input %v2float
690%In2 = OpVariable %_ptr_Input_v2float Input
691%_ptr_Input_float = OpTypePointer Input %float
692%In0 = OpVariable %_ptr_Input_float Input
693%In1 = OpVariable %_ptr_Input_float Input
694%uint = OpTypeInt 32 0
695%uint_32 = OpConstant %uint 32
696%_ptr_Function_float = OpTypePointer Function %float
697%float_0 = OpConstant %float 0
698%v4float = OpTypeVector %float 4
699%_ptr_Output_v4float = OpTypePointer Output %v4float
700%OutColor = OpVariable %_ptr_Output_v4float Output
701%int = OpTypeInt 32 1
702%_Globals_ = OpTypeStruct %uint %int
703%_ptr_Uniform__Globals_ = OpTypePointer Uniform %_Globals_
704%_ = OpVariable %_ptr_Uniform__Globals_ Uniform
705
706%nullexpr = OpExtInst %void %ext DebugExpression
707%src = OpExtInst %void %ext DebugSource %file_name
708%cu = OpExtInst %void %ext DebugCompilationUnit 1 4 %src HLSL
709%dbg_tf = OpExtInst %void %ext DebugTypeBasic %float_name %uint_32 Float
710%dbg_v2f = OpExtInst %void %ext DebugTypeVector %dbg_tf 2
711%main_ty = OpExtInst %void %ext DebugTypeFunction FlagIsProtected|FlagIsPrivate %void
712%dbg_main = OpExtInst %void %ext DebugFunction %main_name %main_ty %src 0 0 %cu %main_name FlagIsProtected|FlagIsPrivate 0 %main
713%dbg_foo = OpExtInst %void %ext DebugLocalVariable %f_name %dbg_v2f %src 0 0 %dbg_main FlagIsLocal
714
715%main = OpFunction %void None %11
716%25 = OpLabel
717%26 = OpLoad %v2float %In2
718%27 = OpLoad %float %In0
719%28 = OpLoad %float %In1
720%29 = OpFAdd %float %27 %28
721
722; CHECK: [[repl:%\w+]] = OpLoad %v2float %In2
723; CHECK-NOT: OpCompositeInsert
724; CHECK: DebugValue {{%\w+}} [[repl:%\w+]]
725; CHECK-NEXT: OpCompositeInsert %v2float %float_0 [[repl]] 0
726%35 = OpCompositeInsert %v2float %29 %26 0
727%value = OpExtInst %void %ext DebugValue %dbg_foo %35 %nullexpr
728%37 = OpCompositeInsert %v2float %float_0 %35 0
729
730%33 = OpVectorShuffle %v4float %37 %37 0 1 0 1
731OpStore %OutColor %33
732OpReturn
733OpFunctionEnd
734)";
735
736 SinglePassRunAndMatch<DeadInsertElimPass>(text, true);
737}
738
Chris Forbescc5697f2019-01-30 11:54:08 -0800739// TODO(greg-lunarg): Add tests to verify handling of these cases:
740//
741
742} // namespace
743} // namespace opt
744} // namespace spvtools