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