• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // 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 
21 namespace spvtools {
22 namespace opt {
23 namespace {
24 
25 using DeadInsertElimTest = PassTest<::testing::Test>;
26 
TEST_F(DeadInsertElimTest,InsertAfterInsertElim)27 TEST_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"
52 OpMemoryModel Logical GLSL450
53 OpEntryPoint Fragment %main "main" %In2 %In0 %In1 %OutColor
54 OpExecutionMode %main OriginUpperLeft
55 OpSource GLSL 450
56 OpName %main "main"
57 OpName %In2 "In2"
58 OpName %In0 "In0"
59 OpName %In1 "In1"
60 OpName %OutColor "OutColor"
61 OpName %_Globals_ "_Globals_"
62 OpMemberName %_Globals_ 0 "g_b"
63 OpMemberName %_Globals_ 1 "g_n"
64 OpName %_ ""
65 OpDecorate %In2 Location 2
66 OpDecorate %In0 Location 0
67 OpDecorate %In1 Location 1
68 OpDecorate %OutColor Location 0
69 OpMemberDecorate %_Globals_ 0 Offset 0
70 OpMemberDecorate %_Globals_ 1 Offset 4
71 OpDecorate %_Globals_ Block
72 OpDecorate %_ DescriptorSet 0
73 OpDecorate %_ 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"
99 OpMemoryModel Logical GLSL450
100 OpEntryPoint Fragment %main "main" %In2 %In0 %In1 %OutColor
101 OpExecutionMode %main OriginUpperLeft
102 OpSource GLSL 450
103 OpName %main "main"
104 OpName %In2 "In2"
105 OpName %In0 "In0"
106 OpName %In1 "In1"
107 OpName %OutColor "OutColor"
108 OpName %_Globals_ "_Globals_"
109 OpMemberName %_Globals_ 0 "g_b"
110 OpMemberName %_Globals_ 1 "g_n"
111 OpName %_ ""
112 OpDecorate %In2 Location 2
113 OpDecorate %In0 Location 0
114 OpDecorate %In1 Location 1
115 OpDecorate %OutColor Location 0
116 OpMemberDecorate %_Globals_ 0 Offset 0
117 OpMemberDecorate %_Globals_ 1 Offset 4
118 OpDecorate %_Globals_ Block
119 OpDecorate %_ DescriptorSet 0
120 OpDecorate %_ 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
153 OpStore %OutColor %33
154 OpReturn
155 OpFunctionEnd
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
164 OpStore %OutColor %30
165 OpReturn
166 OpFunctionEnd
167 )";
168 
169   SinglePassRunAndCheck<DeadInsertElimPass>(before_predefs + before,
170                                             after_predefs + after, true, true);
171 }
172 
TEST_F(DeadInsertElimTest,DeadInsertInChainWithPhi)173 TEST_F(DeadInsertElimTest, DeadInsertInChainWithPhi) {
174   // Dead insert eliminated with phi in insertion chain.
175   //
176   // Note: The SPIR-V assembly has had store/load elimination
177   // performed to allow the inserts and extracts to directly
178   // reference each other.
179   //
180   // #version 450
181   //
182   // layout (location=0) in vec4 In0;
183   // layout (location=1) in float In1;
184   // layout (location=2) in float In2;
185   // layout (location=0) out vec4 OutColor;
186   //
187   // layout(std140, binding = 0 ) uniform _Globals_
188   // {
189   //     bool g_b;
190   // };
191   //
192   // void main()
193   // {
194   //     vec4 v = In0;
195   //     v.z = In1 + In2;
196   //     if (g_b) v.w = 1.0;
197   //     OutColor = vec4(v.x,v.y,0.0,v.w);
198   // }
199 
200   const std::string before_predefs =
201       R"(OpCapability Shader
202 %1 = OpExtInstImport "GLSL.std.450"
203 OpMemoryModel Logical GLSL450
204 OpEntryPoint Fragment %main "main" %In0 %In1 %In2 %OutColor
205 OpExecutionMode %main OriginUpperLeft
206 OpSource GLSL 450
207 OpName %main "main"
208 OpName %In0 "In0"
209 OpName %In1 "In1"
210 OpName %In2 "In2"
211 OpName %_Globals_ "_Globals_"
212 OpMemberName %_Globals_ 0 "g_b"
213 OpName %_ ""
214 OpName %OutColor "OutColor"
215 OpDecorate %In0 Location 0
216 OpDecorate %In1 Location 1
217 OpDecorate %In2 Location 2
218 OpMemberDecorate %_Globals_ 0 Offset 0
219 OpDecorate %_Globals_ Block
220 OpDecorate %_ DescriptorSet 0
221 OpDecorate %_ Binding 0
222 OpDecorate %OutColor Location 0
223 %void = OpTypeVoid
224 %11 = OpTypeFunction %void
225 %float = OpTypeFloat 32
226 %v4float = OpTypeVector %float 4
227 %_ptr_Function_v4float = OpTypePointer Function %v4float
228 %_ptr_Input_v4float = OpTypePointer Input %v4float
229 %In0 = OpVariable %_ptr_Input_v4float Input
230 %_ptr_Input_float = OpTypePointer Input %float
231 %In1 = OpVariable %_ptr_Input_float Input
232 %In2 = OpVariable %_ptr_Input_float Input
233 %uint = OpTypeInt 32 0
234 %_ptr_Function_float = OpTypePointer Function %float
235 %_Globals_ = OpTypeStruct %uint
236 %_ptr_Uniform__Globals_ = OpTypePointer Uniform %_Globals_
237 %_ = OpVariable %_ptr_Uniform__Globals_ Uniform
238 %int = OpTypeInt 32 1
239 %int_0 = OpConstant %int 0
240 %_ptr_Uniform_uint = OpTypePointer Uniform %uint
241 %bool = OpTypeBool
242 %uint_0 = OpConstant %uint 0
243 %float_1 = OpConstant %float 1
244 %_ptr_Output_v4float = OpTypePointer Output %v4float
245 %OutColor = OpVariable %_ptr_Output_v4float Output
246 %float_0 = OpConstant %float 0
247 )";
248 
249   const std::string after_predefs =
250       R"(OpCapability Shader
251 %1 = OpExtInstImport "GLSL.std.450"
252 OpMemoryModel Logical GLSL450
253 OpEntryPoint Fragment %main "main" %In0 %In1 %In2 %OutColor
254 OpExecutionMode %main OriginUpperLeft
255 OpSource GLSL 450
256 OpName %main "main"
257 OpName %In0 "In0"
258 OpName %In1 "In1"
259 OpName %In2 "In2"
260 OpName %_Globals_ "_Globals_"
261 OpMemberName %_Globals_ 0 "g_b"
262 OpName %_ ""
263 OpName %OutColor "OutColor"
264 OpDecorate %In0 Location 0
265 OpDecorate %In1 Location 1
266 OpDecorate %In2 Location 2
267 OpMemberDecorate %_Globals_ 0 Offset 0
268 OpDecorate %_Globals_ Block
269 OpDecorate %_ DescriptorSet 0
270 OpDecorate %_ Binding 0
271 OpDecorate %OutColor Location 0
272 %void = OpTypeVoid
273 %10 = OpTypeFunction %void
274 %float = OpTypeFloat 32
275 %v4float = OpTypeVector %float 4
276 %_ptr_Function_v4float = OpTypePointer Function %v4float
277 %_ptr_Input_v4float = OpTypePointer Input %v4float
278 %In0 = OpVariable %_ptr_Input_v4float Input
279 %_ptr_Input_float = OpTypePointer Input %float
280 %In1 = OpVariable %_ptr_Input_float Input
281 %In2 = OpVariable %_ptr_Input_float Input
282 %uint = OpTypeInt 32 0
283 %_ptr_Function_float = OpTypePointer Function %float
284 %_Globals_ = OpTypeStruct %uint
285 %_ptr_Uniform__Globals_ = OpTypePointer Uniform %_Globals_
286 %_ = OpVariable %_ptr_Uniform__Globals_ Uniform
287 %int = OpTypeInt 32 1
288 %int_0 = OpConstant %int 0
289 %_ptr_Uniform_uint = OpTypePointer Uniform %uint
290 %bool = OpTypeBool
291 %uint_0 = OpConstant %uint 0
292 %float_1 = OpConstant %float 1
293 %_ptr_Output_v4float = OpTypePointer Output %v4float
294 %OutColor = OpVariable %_ptr_Output_v4float Output
295 %float_0 = OpConstant %float 0
296 )";
297 
298   const std::string before =
299       R"(%main = OpFunction %void None %11
300 %31 = OpLabel
301 %32 = OpLoad %v4float %In0
302 %33 = OpLoad %float %In1
303 %34 = OpLoad %float %In2
304 %35 = OpFAdd %float %33 %34
305 %51 = OpCompositeInsert %v4float %35 %32 2
306 %37 = OpAccessChain %_ptr_Uniform_uint %_ %int_0
307 %38 = OpLoad %uint %37
308 %39 = OpINotEqual %bool %38 %uint_0
309 OpSelectionMerge %40 None
310 OpBranchConditional %39 %41 %40
311 %41 = OpLabel
312 %53 = OpCompositeInsert %v4float %float_1 %51 3
313 OpBranch %40
314 %40 = OpLabel
315 %60 = OpPhi %v4float %51 %31 %53 %41
316 %55 = OpCompositeExtract %float %60 0
317 %57 = OpCompositeExtract %float %60 1
318 %59 = OpCompositeExtract %float %60 3
319 %49 = OpCompositeConstruct %v4float %55 %57 %float_0 %59
320 OpStore %OutColor %49
321 OpReturn
322 OpFunctionEnd
323 )";
324 
325   const std::string after =
326       R"(%main = OpFunction %void None %10
327 %27 = OpLabel
328 %28 = OpLoad %v4float %In0
329 %33 = OpAccessChain %_ptr_Uniform_uint %_ %int_0
330 %34 = OpLoad %uint %33
331 %35 = OpINotEqual %bool %34 %uint_0
332 OpSelectionMerge %36 None
333 OpBranchConditional %35 %37 %36
334 %37 = OpLabel
335 %38 = OpCompositeInsert %v4float %float_1 %28 3
336 OpBranch %36
337 %36 = OpLabel
338 %39 = OpPhi %v4float %28 %27 %38 %37
339 %40 = OpCompositeExtract %float %39 0
340 %41 = OpCompositeExtract %float %39 1
341 %42 = OpCompositeExtract %float %39 3
342 %43 = OpCompositeConstruct %v4float %40 %41 %float_0 %42
343 OpStore %OutColor %43
344 OpReturn
345 OpFunctionEnd
346 )";
347 
348   SinglePassRunAndCheck<DeadInsertElimPass>(before_predefs + before,
349                                             after_predefs + after, true, true);
350 }
351 
TEST_F(DeadInsertElimTest,DeadInsertTwoPasses)352 TEST_F(DeadInsertElimTest, DeadInsertTwoPasses) {
353   // Dead insert which requires two passes to eliminate
354   //
355   // Note: The SPIR-V assembly has had store/load elimination
356   // performed to allow the inserts and extracts to directly
357   // reference each other.
358   //
359   // #version 450
360   //
361   // layout (location=0) in vec4 In0;
362   // layout (location=1) in float In1;
363   // layout (location=2) in float In2;
364   // layout (location=0) out vec4 OutColor;
365   //
366   // layout(std140, binding = 0 ) uniform _Globals_
367   // {
368   //     bool g_b;
369   //     bool g_b2;
370   // };
371   //
372   // void main()
373   // {
374   //     vec4 v1, v2;
375   //     v1 = In0;
376   //     v1.y = In1 + In2; // dead, second pass
377   //     if (g_b) v1.x = 1.0;
378   //     v2.x = v1.x;
379   //     v2.y = v1.y; // dead, first pass
380   //     if (g_b2) v2.x = 0.0;
381   //     OutColor = vec4(v2.x,v2.x,0.0,1.0);
382   // }
383 
384   const std::string before_predefs =
385       R"(OpCapability Shader
386 %1 = OpExtInstImport "GLSL.std.450"
387 OpMemoryModel Logical GLSL450
388 OpEntryPoint Fragment %main "main" %In0 %In1 %In2 %OutColor
389 OpExecutionMode %main OriginUpperLeft
390 OpSource GLSL 450
391 OpName %main "main"
392 OpName %In0 "In0"
393 OpName %In1 "In1"
394 OpName %In2 "In2"
395 OpName %_Globals_ "_Globals_"
396 OpMemberName %_Globals_ 0 "g_b"
397 OpMemberName %_Globals_ 1 "g_b2"
398 OpName %_ ""
399 OpName %OutColor "OutColor"
400 OpDecorate %In0 Location 0
401 OpDecorate %In1 Location 1
402 OpDecorate %In2 Location 2
403 OpMemberDecorate %_Globals_ 0 Offset 0
404 OpMemberDecorate %_Globals_ 1 Offset 4
405 OpDecorate %_Globals_ Block
406 OpDecorate %_ DescriptorSet 0
407 OpDecorate %_ Binding 0
408 OpDecorate %OutColor Location 0
409 %void = OpTypeVoid
410 %10 = OpTypeFunction %void
411 %float = OpTypeFloat 32
412 %v4float = OpTypeVector %float 4
413 %_ptr_Function_v4float = OpTypePointer Function %v4float
414 %_ptr_Input_v4float = OpTypePointer Input %v4float
415 %In0 = OpVariable %_ptr_Input_v4float Input
416 %_ptr_Input_float = OpTypePointer Input %float
417 %In1 = OpVariable %_ptr_Input_float Input
418 %In2 = OpVariable %_ptr_Input_float Input
419 %uint = OpTypeInt 32 0
420 %_Globals_ = OpTypeStruct %uint %uint
421 %_ptr_Uniform__Globals_ = OpTypePointer Uniform %_Globals_
422 %_ = OpVariable %_ptr_Uniform__Globals_ Uniform
423 %int = OpTypeInt 32 1
424 %int_0 = OpConstant %int 0
425 %_ptr_Uniform_uint = OpTypePointer Uniform %uint
426 %bool = OpTypeBool
427 %uint_0 = OpConstant %uint 0
428 %float_1 = OpConstant %float 1
429 %int_1 = OpConstant %int 1
430 %float_0 = OpConstant %float 0
431 %_ptr_Output_v4float = OpTypePointer Output %v4float
432 %OutColor = OpVariable %_ptr_Output_v4float Output
433 %27 = OpUndef %v4float
434 )";
435 
436   const std::string after_predefs =
437       R"(OpCapability Shader
438 %1 = OpExtInstImport "GLSL.std.450"
439 OpMemoryModel Logical GLSL450
440 OpEntryPoint Fragment %main "main" %In0 %In1 %In2 %OutColor
441 OpExecutionMode %main OriginUpperLeft
442 OpSource GLSL 450
443 OpName %main "main"
444 OpName %In0 "In0"
445 OpName %In1 "In1"
446 OpName %In2 "In2"
447 OpName %_Globals_ "_Globals_"
448 OpMemberName %_Globals_ 0 "g_b"
449 OpMemberName %_Globals_ 1 "g_b2"
450 OpName %_ ""
451 OpName %OutColor "OutColor"
452 OpDecorate %In0 Location 0
453 OpDecorate %In1 Location 1
454 OpDecorate %In2 Location 2
455 OpMemberDecorate %_Globals_ 0 Offset 0
456 OpMemberDecorate %_Globals_ 1 Offset 4
457 OpDecorate %_Globals_ Block
458 OpDecorate %_ DescriptorSet 0
459 OpDecorate %_ Binding 0
460 OpDecorate %OutColor Location 0
461 %void = OpTypeVoid
462 %10 = OpTypeFunction %void
463 %float = OpTypeFloat 32
464 %v4float = OpTypeVector %float 4
465 %_ptr_Function_v4float = OpTypePointer Function %v4float
466 %_ptr_Input_v4float = OpTypePointer Input %v4float
467 %In0 = OpVariable %_ptr_Input_v4float Input
468 %_ptr_Input_float = OpTypePointer Input %float
469 %In1 = OpVariable %_ptr_Input_float Input
470 %In2 = OpVariable %_ptr_Input_float Input
471 %uint = OpTypeInt 32 0
472 %_Globals_ = OpTypeStruct %uint %uint
473 %_ptr_Uniform__Globals_ = OpTypePointer Uniform %_Globals_
474 %_ = OpVariable %_ptr_Uniform__Globals_ Uniform
475 %int = OpTypeInt 32 1
476 %int_0 = OpConstant %int 0
477 %_ptr_Uniform_uint = OpTypePointer Uniform %uint
478 %bool = OpTypeBool
479 %uint_0 = OpConstant %uint 0
480 %float_1 = OpConstant %float 1
481 %int_1 = OpConstant %int 1
482 %float_0 = OpConstant %float 0
483 %_ptr_Output_v4float = OpTypePointer Output %v4float
484 %OutColor = OpVariable %_ptr_Output_v4float Output
485 %27 = OpUndef %v4float
486 )";
487 
488   const std::string before =
489       R"(%main = OpFunction %void None %10
490 %28 = OpLabel
491 %29 = OpLoad %v4float %In0
492 %30 = OpLoad %float %In1
493 %31 = OpLoad %float %In2
494 %32 = OpFAdd %float %30 %31
495 %33 = OpCompositeInsert %v4float %32 %29 1
496 %34 = OpAccessChain %_ptr_Uniform_uint %_ %int_0
497 %35 = OpLoad %uint %34
498 %36 = OpINotEqual %bool %35 %uint_0
499 OpSelectionMerge %37 None
500 OpBranchConditional %36 %38 %37
501 %38 = OpLabel
502 %39 = OpCompositeInsert %v4float %float_1 %33 0
503 OpBranch %37
504 %37 = OpLabel
505 %40 = OpPhi %v4float %33 %28 %39 %38
506 %41 = OpCompositeExtract %float %40 0
507 %42 = OpCompositeInsert %v4float %41 %27 0
508 %43 = OpCompositeExtract %float %40 1
509 %44 = OpCompositeInsert %v4float %43 %42 1
510 %45 = OpAccessChain %_ptr_Uniform_uint %_ %int_1
511 %46 = OpLoad %uint %45
512 %47 = OpINotEqual %bool %46 %uint_0
513 OpSelectionMerge %48 None
514 OpBranchConditional %47 %49 %48
515 %49 = OpLabel
516 %50 = OpCompositeInsert %v4float %float_0 %44 0
517 OpBranch %48
518 %48 = OpLabel
519 %51 = OpPhi %v4float %44 %37 %50 %49
520 %52 = OpCompositeExtract %float %51 0
521 %53 = OpCompositeExtract %float %51 0
522 %54 = OpCompositeConstruct %v4float %52 %53 %float_0 %float_1
523 OpStore %OutColor %54
524 OpReturn
525 OpFunctionEnd
526 )";
527 
528   const std::string after =
529       R"(%main = OpFunction %void None %10
530 %28 = OpLabel
531 %29 = OpLoad %v4float %In0
532 %34 = OpAccessChain %_ptr_Uniform_uint %_ %int_0
533 %35 = OpLoad %uint %34
534 %36 = OpINotEqual %bool %35 %uint_0
535 OpSelectionMerge %37 None
536 OpBranchConditional %36 %38 %37
537 %38 = OpLabel
538 %39 = OpCompositeInsert %v4float %float_1 %29 0
539 OpBranch %37
540 %37 = OpLabel
541 %40 = OpPhi %v4float %29 %28 %39 %38
542 %41 = OpCompositeExtract %float %40 0
543 %42 = OpCompositeInsert %v4float %41 %27 0
544 %45 = OpAccessChain %_ptr_Uniform_uint %_ %int_1
545 %46 = OpLoad %uint %45
546 %47 = OpINotEqual %bool %46 %uint_0
547 OpSelectionMerge %48 None
548 OpBranchConditional %47 %49 %48
549 %49 = OpLabel
550 %50 = OpCompositeInsert %v4float %float_0 %42 0
551 OpBranch %48
552 %48 = OpLabel
553 %51 = OpPhi %v4float %42 %37 %50 %49
554 %52 = OpCompositeExtract %float %51 0
555 %53 = OpCompositeExtract %float %51 0
556 %54 = OpCompositeConstruct %v4float %52 %53 %float_0 %float_1
557 OpStore %OutColor %54
558 OpReturn
559 OpFunctionEnd
560 )";
561 
562   SinglePassRunAndCheck<DeadInsertElimPass>(before_predefs + before,
563                                             after_predefs + after, true, true);
564 }
565 
TEST_F(DeadInsertElimTest,DebugInsertAfterInsertElim)566 TEST_F(DeadInsertElimTest, DebugInsertAfterInsertElim) {
567   // With two insertions to the same offset, the first is dead.
568   //
569   // Note: The SPIR-V assembly has had store/load elimination
570   // performed to allow the inserts and extracts to directly
571   // reference each other.
572   //
573   // #version 450
574   //
575   // layout (location=0) in float In0;
576   // layout (location=1) in float In1;
577   // layout (location=2) in vec2 In2;
578   // layout (location=0) out vec4 OutColor;
579   //
580   // void main()
581   // {
582   //     vec2 v = In2;
583   //     v.x = In0 + In1; // dead
584   //     v.x = 0.0;
585   //     OutColor = v.xyxy;
586   // }
587 
588   const std::string text =
589       R"(OpCapability Shader
590 %1 = OpExtInstImport "GLSL.std.450"
591 %ext = OpExtInstImport "OpenCL.DebugInfo.100"
592 OpMemoryModel Logical GLSL450
593 OpEntryPoint Fragment %main "main" %In2 %In0 %In1 %OutColor
594 OpExecutionMode %main OriginUpperLeft
595 OpSource GLSL 450
596 %file_name = OpString "test"
597 %float_name = OpString "float"
598 %main_name = OpString "main"
599 %f_name = OpString "f"
600 OpName %main "main"
601 OpName %In2 "In2"
602 OpName %In0 "In0"
603 OpName %In1 "In1"
604 OpName %OutColor "OutColor"
605 OpName %_Globals_ "_Globals_"
606 OpMemberName %_Globals_ 0 "g_b"
607 OpMemberName %_Globals_ 1 "g_n"
608 OpName %_ ""
609 OpDecorate %In2 Location 2
610 OpDecorate %In0 Location 0
611 OpDecorate %In1 Location 1
612 OpDecorate %OutColor Location 0
613 OpMemberDecorate %_Globals_ 0 Offset 0
614 OpMemberDecorate %_Globals_ 1 Offset 4
615 OpDecorate %_Globals_ Block
616 OpDecorate %_ DescriptorSet 0
617 OpDecorate %_ Binding 0
618 %void = OpTypeVoid
619 %11 = OpTypeFunction %void
620 %float = OpTypeFloat 32
621 %v2float = OpTypeVector %float 2
622 %_ptr_Function_v2float = OpTypePointer Function %v2float
623 %_ptr_Input_v2float = OpTypePointer Input %v2float
624 %In2 = OpVariable %_ptr_Input_v2float Input
625 %_ptr_Input_float = OpTypePointer Input %float
626 %In0 = OpVariable %_ptr_Input_float Input
627 %In1 = OpVariable %_ptr_Input_float Input
628 %uint = OpTypeInt 32 0
629 %uint_32 = OpConstant %uint 32
630 %_ptr_Function_float = OpTypePointer Function %float
631 %float_0 = OpConstant %float 0
632 %v4float = OpTypeVector %float 4
633 %_ptr_Output_v4float = OpTypePointer Output %v4float
634 %OutColor = OpVariable %_ptr_Output_v4float Output
635 %int = OpTypeInt 32 1
636 %_Globals_ = OpTypeStruct %uint %int
637 %_ptr_Uniform__Globals_ = OpTypePointer Uniform %_Globals_
638 %_ = OpVariable %_ptr_Uniform__Globals_ Uniform
639 
640 %nullexpr = OpExtInst %void %ext DebugExpression
641 %src = OpExtInst %void %ext DebugSource %file_name
642 %cu = OpExtInst %void %ext DebugCompilationUnit 1 4 %src HLSL
643 %dbg_tf = OpExtInst %void %ext DebugTypeBasic %float_name %uint_32 Float
644 %dbg_v2f = OpExtInst %void %ext DebugTypeVector %dbg_tf 2
645 %main_ty = OpExtInst %void %ext DebugTypeFunction FlagIsProtected|FlagIsPrivate %void
646 %dbg_main = OpExtInst %void %ext DebugFunction %main_name %main_ty %src 0 0 %cu %main_name FlagIsProtected|FlagIsPrivate 0 %main
647 %dbg_foo = OpExtInst %void %ext DebugLocalVariable %f_name %dbg_v2f %src 0 0 %dbg_main FlagIsLocal
648 
649 %main = OpFunction %void None %11
650 %25 = OpLabel
651 %26 = OpLoad %v2float %In2
652 %27 = OpLoad %float %In0
653 %28 = OpLoad %float %In1
654 %29 = OpFAdd %float %27 %28
655 
656 ; CHECK:      [[repl:%\w+]] = OpLoad %v2float %In2
657 ; CHECK-NOT:  OpCompositeInsert
658 ; CHECK:      DebugValue {{%\w+}} [[repl:%\w+]]
659 ; CHECK-NEXT: OpCompositeInsert %v2float %float_0 [[repl]] 0
660 %35 = OpCompositeInsert %v2float %29 %26 0
661 %value = OpExtInst %void %ext DebugValue %dbg_foo %35 %nullexpr
662 %37 = OpCompositeInsert %v2float %float_0 %35 0
663 
664 %33 = OpVectorShuffle %v4float %37 %37 0 1 0 1
665 OpStore %OutColor %33
666 OpReturn
667 OpFunctionEnd
668 )";
669 
670   SinglePassRunAndMatch<DeadInsertElimPass>(text, true);
671 }
672 
673 // TODO(greg-lunarg): Add tests to verify handling of these cases:
674 //
675 
676 }  // namespace
677 }  // namespace opt
678 }  // namespace spvtools
679