1 // Copyright (c) 2018 Google LLC
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
17 #include "test/opt/pass_fixture.h"
18 #include "test/opt/pass_utils.h"
19
20 namespace spvtools {
21 namespace opt {
22 namespace {
23
24 using VectorDCETest = PassTest<::testing::Test>;
25
TEST_F(VectorDCETest,InsertAfterInsertElim)26 TEST_F(VectorDCETest, InsertAfterInsertElim) {
27 // With two insertions to the same offset, the first is dead.
28 //
29 // Note: The SPIR-V assembly has had store/load elimination
30 // performed to allow the inserts and extracts to directly
31 // reference each other.
32 //
33 // #version 450
34 //
35 // layout (location=0) in float In0;
36 // layout (location=1) in float In1;
37 // layout (location=2) in vec2 In2;
38 // layout (location=0) out vec4 OutColor;
39 //
40 // void main()
41 // {
42 // vec2 v = In2;
43 // v.x = In0 + In1; // dead
44 // v.x = 0.0;
45 // OutColor = v.xyxy;
46 // }
47
48 const std::string before_predefs =
49 R"(OpCapability Shader
50 %1 = OpExtInstImport "GLSL.std.450"
51 OpMemoryModel Logical GLSL450
52 OpEntryPoint Fragment %main "main" %In2 %In0 %In1 %OutColor
53 OpExecutionMode %main OriginUpperLeft
54 OpSource GLSL 450
55 OpName %main "main"
56 OpName %In2 "In2"
57 OpName %In0 "In0"
58 OpName %In1 "In1"
59 OpName %OutColor "OutColor"
60 OpName %_Globals_ "_Globals_"
61 OpMemberName %_Globals_ 0 "g_b"
62 OpMemberName %_Globals_ 1 "g_n"
63 OpName %_ ""
64 OpDecorate %In2 Location 2
65 OpDecorate %In0 Location 0
66 OpDecorate %In1 Location 1
67 OpDecorate %OutColor Location 0
68 OpMemberDecorate %_Globals_ 0 Offset 0
69 OpMemberDecorate %_Globals_ 1 Offset 4
70 OpDecorate %_Globals_ Block
71 OpDecorate %_ DescriptorSet 0
72 OpDecorate %_ Binding 0
73 %void = OpTypeVoid
74 %11 = OpTypeFunction %void
75 %float = OpTypeFloat 32
76 %v2float = OpTypeVector %float 2
77 %_ptr_Function_v2float = OpTypePointer Function %v2float
78 %_ptr_Input_v2float = OpTypePointer Input %v2float
79 %In2 = OpVariable %_ptr_Input_v2float Input
80 %_ptr_Input_float = OpTypePointer Input %float
81 %In0 = OpVariable %_ptr_Input_float Input
82 %In1 = OpVariable %_ptr_Input_float Input
83 %uint = OpTypeInt 32 0
84 %_ptr_Function_float = OpTypePointer Function %float
85 %float_0 = OpConstant %float 0
86 %v4float = OpTypeVector %float 4
87 %_ptr_Output_v4float = OpTypePointer Output %v4float
88 %OutColor = OpVariable %_ptr_Output_v4float Output
89 %int = OpTypeInt 32 1
90 %_Globals_ = OpTypeStruct %uint %int
91 %_ptr_Uniform__Globals_ = OpTypePointer Uniform %_Globals_
92 %_ = OpVariable %_ptr_Uniform__Globals_ Uniform
93 )";
94
95 const std::string after_predefs =
96 R"(OpCapability Shader
97 %1 = OpExtInstImport "GLSL.std.450"
98 OpMemoryModel Logical GLSL450
99 OpEntryPoint Fragment %main "main" %In2 %In0 %In1 %OutColor
100 OpExecutionMode %main OriginUpperLeft
101 OpSource GLSL 450
102 OpName %main "main"
103 OpName %In2 "In2"
104 OpName %In0 "In0"
105 OpName %In1 "In1"
106 OpName %OutColor "OutColor"
107 OpName %_Globals_ "_Globals_"
108 OpMemberName %_Globals_ 0 "g_b"
109 OpMemberName %_Globals_ 1 "g_n"
110 OpName %_ ""
111 OpDecorate %In2 Location 2
112 OpDecorate %In0 Location 0
113 OpDecorate %In1 Location 1
114 OpDecorate %OutColor Location 0
115 OpMemberDecorate %_Globals_ 0 Offset 0
116 OpMemberDecorate %_Globals_ 1 Offset 4
117 OpDecorate %_Globals_ Block
118 OpDecorate %_ DescriptorSet 0
119 OpDecorate %_ Binding 0
120 %void = OpTypeVoid
121 %10 = OpTypeFunction %void
122 %float = OpTypeFloat 32
123 %v2float = OpTypeVector %float 2
124 %_ptr_Function_v2float = OpTypePointer Function %v2float
125 %_ptr_Input_v2float = OpTypePointer Input %v2float
126 %In2 = OpVariable %_ptr_Input_v2float Input
127 %_ptr_Input_float = OpTypePointer Input %float
128 %In0 = OpVariable %_ptr_Input_float Input
129 %In1 = OpVariable %_ptr_Input_float Input
130 %uint = OpTypeInt 32 0
131 %_ptr_Function_float = OpTypePointer Function %float
132 %float_0 = OpConstant %float 0
133 %v4float = OpTypeVector %float 4
134 %_ptr_Output_v4float = OpTypePointer Output %v4float
135 %OutColor = OpVariable %_ptr_Output_v4float Output
136 %int = OpTypeInt 32 1
137 %_Globals_ = OpTypeStruct %uint %int
138 %_ptr_Uniform__Globals_ = OpTypePointer Uniform %_Globals_
139 %_ = OpVariable %_ptr_Uniform__Globals_ Uniform
140 )";
141
142 const std::string before =
143 R"(%main = OpFunction %void None %11
144 %25 = OpLabel
145 %26 = OpLoad %v2float %In2
146 %27 = OpLoad %float %In0
147 %28 = OpLoad %float %In1
148 %29 = OpFAdd %float %27 %28
149 %35 = OpCompositeInsert %v2float %29 %26 0
150 %37 = OpCompositeInsert %v2float %float_0 %35 0
151 %33 = OpVectorShuffle %v4float %37 %37 0 1 0 1
152 OpStore %OutColor %33
153 OpReturn
154 OpFunctionEnd
155 )";
156
157 const std::string after =
158 R"(%main = OpFunction %void None %10
159 %23 = OpLabel
160 %24 = OpLoad %v2float %In2
161 %25 = OpLoad %float %In0
162 %26 = OpLoad %float %In1
163 %27 = OpFAdd %float %25 %26
164 %28 = OpCompositeInsert %v2float %27 %24 0
165 %29 = OpCompositeInsert %v2float %float_0 %24 0
166 %30 = OpVectorShuffle %v4float %29 %29 0 1 0 1
167 OpStore %OutColor %30
168 OpReturn
169 OpFunctionEnd
170 )";
171
172 SinglePassRunAndCheck<VectorDCE>(before_predefs + before,
173 after_predefs + after, true, true);
174 }
175
TEST_F(VectorDCETest,DeadInsertInChainWithPhi)176 TEST_F(VectorDCETest, DeadInsertInChainWithPhi) {
177 // Dead insert eliminated with phi in insertion chain.
178 //
179 // Note: The SPIR-V assembly has had store/load elimination
180 // performed to allow the inserts and extracts to directly
181 // reference each other.
182 //
183 // #version 450
184 //
185 // layout (location=0) in vec4 In0;
186 // layout (location=1) in float In1;
187 // layout (location=2) in float In2;
188 // layout (location=0) out vec4 OutColor;
189 //
190 // layout(std140, binding = 0 ) uniform _Globals_
191 // {
192 // bool g_b;
193 // };
194 //
195 // void main()
196 // {
197 // vec4 v = In0;
198 // v.z = In1 + In2;
199 // if (g_b) v.w = 1.0;
200 // OutColor = vec4(v.x,v.y,0.0,v.w);
201 // }
202
203 const std::string before_predefs =
204 R"(OpCapability Shader
205 %1 = OpExtInstImport "GLSL.std.450"
206 OpMemoryModel Logical GLSL450
207 OpEntryPoint Fragment %main "main" %In0 %In1 %In2 %OutColor
208 OpExecutionMode %main OriginUpperLeft
209 OpSource GLSL 450
210 OpName %main "main"
211 OpName %In0 "In0"
212 OpName %In1 "In1"
213 OpName %In2 "In2"
214 OpName %_Globals_ "_Globals_"
215 OpMemberName %_Globals_ 0 "g_b"
216 OpName %_ ""
217 OpName %OutColor "OutColor"
218 OpDecorate %In0 Location 0
219 OpDecorate %In1 Location 1
220 OpDecorate %In2 Location 2
221 OpMemberDecorate %_Globals_ 0 Offset 0
222 OpDecorate %_Globals_ Block
223 OpDecorate %_ DescriptorSet 0
224 OpDecorate %_ Binding 0
225 OpDecorate %OutColor Location 0
226 %void = OpTypeVoid
227 %11 = OpTypeFunction %void
228 %float = OpTypeFloat 32
229 %v4float = OpTypeVector %float 4
230 %_ptr_Function_v4float = OpTypePointer Function %v4float
231 %_ptr_Input_v4float = OpTypePointer Input %v4float
232 %In0 = OpVariable %_ptr_Input_v4float Input
233 %_ptr_Input_float = OpTypePointer Input %float
234 %In1 = OpVariable %_ptr_Input_float Input
235 %In2 = OpVariable %_ptr_Input_float Input
236 %uint = OpTypeInt 32 0
237 %_ptr_Function_float = OpTypePointer Function %float
238 %_Globals_ = OpTypeStruct %uint
239 %_ptr_Uniform__Globals_ = OpTypePointer Uniform %_Globals_
240 %_ = OpVariable %_ptr_Uniform__Globals_ Uniform
241 %int = OpTypeInt 32 1
242 %int_0 = OpConstant %int 0
243 %_ptr_Uniform_uint = OpTypePointer Uniform %uint
244 %bool = OpTypeBool
245 %uint_0 = OpConstant %uint 0
246 %float_1 = OpConstant %float 1
247 %_ptr_Output_v4float = OpTypePointer Output %v4float
248 %OutColor = OpVariable %_ptr_Output_v4float Output
249 %float_0 = OpConstant %float 0
250 )";
251
252 const std::string after_predefs =
253 R"(OpCapability Shader
254 %1 = OpExtInstImport "GLSL.std.450"
255 OpMemoryModel Logical GLSL450
256 OpEntryPoint Fragment %main "main" %In0 %In1 %In2 %OutColor
257 OpExecutionMode %main OriginUpperLeft
258 OpSource GLSL 450
259 OpName %main "main"
260 OpName %In0 "In0"
261 OpName %In1 "In1"
262 OpName %In2 "In2"
263 OpName %_Globals_ "_Globals_"
264 OpMemberName %_Globals_ 0 "g_b"
265 OpName %_ ""
266 OpName %OutColor "OutColor"
267 OpDecorate %In0 Location 0
268 OpDecorate %In1 Location 1
269 OpDecorate %In2 Location 2
270 OpMemberDecorate %_Globals_ 0 Offset 0
271 OpDecorate %_Globals_ Block
272 OpDecorate %_ DescriptorSet 0
273 OpDecorate %_ Binding 0
274 OpDecorate %OutColor Location 0
275 %void = OpTypeVoid
276 %10 = OpTypeFunction %void
277 %float = OpTypeFloat 32
278 %v4float = OpTypeVector %float 4
279 %_ptr_Function_v4float = OpTypePointer Function %v4float
280 %_ptr_Input_v4float = OpTypePointer Input %v4float
281 %In0 = OpVariable %_ptr_Input_v4float Input
282 %_ptr_Input_float = OpTypePointer Input %float
283 %In1 = OpVariable %_ptr_Input_float Input
284 %In2 = OpVariable %_ptr_Input_float Input
285 %uint = OpTypeInt 32 0
286 %_ptr_Function_float = OpTypePointer Function %float
287 %_Globals_ = OpTypeStruct %uint
288 %_ptr_Uniform__Globals_ = OpTypePointer Uniform %_Globals_
289 %_ = OpVariable %_ptr_Uniform__Globals_ Uniform
290 %int = OpTypeInt 32 1
291 %int_0 = OpConstant %int 0
292 %_ptr_Uniform_uint = OpTypePointer Uniform %uint
293 %bool = OpTypeBool
294 %uint_0 = OpConstant %uint 0
295 %float_1 = OpConstant %float 1
296 %_ptr_Output_v4float = OpTypePointer Output %v4float
297 %OutColor = OpVariable %_ptr_Output_v4float Output
298 %float_0 = OpConstant %float 0
299 )";
300
301 const std::string before =
302 R"(%main = OpFunction %void None %11
303 %31 = OpLabel
304 %32 = OpLoad %v4float %In0
305 %33 = OpLoad %float %In1
306 %34 = OpLoad %float %In2
307 %35 = OpFAdd %float %33 %34
308 %51 = OpCompositeInsert %v4float %35 %32 2
309 %37 = OpAccessChain %_ptr_Uniform_uint %_ %int_0
310 %38 = OpLoad %uint %37
311 %39 = OpINotEqual %bool %38 %uint_0
312 OpSelectionMerge %40 None
313 OpBranchConditional %39 %41 %40
314 %41 = OpLabel
315 %53 = OpCompositeInsert %v4float %float_1 %51 3
316 OpBranch %40
317 %40 = OpLabel
318 %60 = OpPhi %v4float %51 %31 %53 %41
319 %55 = OpCompositeExtract %float %60 0
320 %57 = OpCompositeExtract %float %60 1
321 %59 = OpCompositeExtract %float %60 3
322 %49 = OpCompositeConstruct %v4float %55 %57 %float_0 %59
323 OpStore %OutColor %49
324 OpReturn
325 OpFunctionEnd
326 )";
327
328 const std::string after =
329 R"(%main = OpFunction %void None %10
330 %27 = OpLabel
331 %28 = OpLoad %v4float %In0
332 %29 = OpLoad %float %In1
333 %30 = OpLoad %float %In2
334 %31 = OpFAdd %float %29 %30
335 %32 = OpCompositeInsert %v4float %31 %28 2
336 %33 = OpAccessChain %_ptr_Uniform_uint %_ %int_0
337 %34 = OpLoad %uint %33
338 %35 = OpINotEqual %bool %34 %uint_0
339 OpSelectionMerge %36 None
340 OpBranchConditional %35 %37 %36
341 %37 = OpLabel
342 %38 = OpCompositeInsert %v4float %float_1 %28 3
343 OpBranch %36
344 %36 = OpLabel
345 %39 = OpPhi %v4float %28 %27 %38 %37
346 %40 = OpCompositeExtract %float %39 0
347 %41 = OpCompositeExtract %float %39 1
348 %42 = OpCompositeExtract %float %39 3
349 %43 = OpCompositeConstruct %v4float %40 %41 %float_0 %42
350 OpStore %OutColor %43
351 OpReturn
352 OpFunctionEnd
353 )";
354
355 SinglePassRunAndCheck<VectorDCE>(before_predefs + before,
356 after_predefs + after, true, true);
357 }
358
TEST_F(VectorDCETest,DeadInsertWithScalars)359 TEST_F(VectorDCETest, DeadInsertWithScalars) {
360 // Dead insert which requires two passes to eliminate
361 //
362 // Note: The SPIR-V assembly has had store/load elimination
363 // performed to allow the inserts and extracts to directly
364 // reference each other.
365 //
366 // #version 450
367 //
368 // layout (location=0) in vec4 In0;
369 // layout (location=1) in float In1;
370 // layout (location=2) in float In2;
371 // layout (location=0) out vec4 OutColor;
372 //
373 // layout(std140, binding = 0 ) uniform _Globals_
374 // {
375 // bool g_b;
376 // bool g_b2;
377 // };
378 //
379 // void main()
380 // {
381 // vec4 v1, v2;
382 // v1 = In0;
383 // v1.y = In1 + In2; // dead, second pass
384 // if (g_b) v1.x = 1.0;
385 // v2.x = v1.x;
386 // v2.y = v1.y; // dead, first pass
387 // if (g_b2) v2.x = 0.0;
388 // OutColor = vec4(v2.x,v2.x,0.0,1.0);
389 // }
390
391 const std::string before_predefs =
392 R"(OpCapability Shader
393 %1 = OpExtInstImport "GLSL.std.450"
394 OpMemoryModel Logical GLSL450
395 OpEntryPoint Fragment %main "main" %In0 %In1 %In2 %OutColor
396 OpExecutionMode %main OriginUpperLeft
397 OpSource GLSL 450
398 OpName %main "main"
399 OpName %In0 "In0"
400 OpName %In1 "In1"
401 OpName %In2 "In2"
402 OpName %_Globals_ "_Globals_"
403 OpMemberName %_Globals_ 0 "g_b"
404 OpMemberName %_Globals_ 1 "g_b2"
405 OpName %_ ""
406 OpName %OutColor "OutColor"
407 OpDecorate %In0 Location 0
408 OpDecorate %In1 Location 1
409 OpDecorate %In2 Location 2
410 OpMemberDecorate %_Globals_ 0 Offset 0
411 OpMemberDecorate %_Globals_ 1 Offset 4
412 OpDecorate %_Globals_ Block
413 OpDecorate %_ DescriptorSet 0
414 OpDecorate %_ Binding 0
415 OpDecorate %OutColor Location 0
416 %void = OpTypeVoid
417 %10 = OpTypeFunction %void
418 %float = OpTypeFloat 32
419 %v4float = OpTypeVector %float 4
420 %_ptr_Function_v4float = OpTypePointer Function %v4float
421 %_ptr_Input_v4float = OpTypePointer Input %v4float
422 %In0 = OpVariable %_ptr_Input_v4float Input
423 %_ptr_Input_float = OpTypePointer Input %float
424 %In1 = OpVariable %_ptr_Input_float Input
425 %In2 = OpVariable %_ptr_Input_float Input
426 %uint = OpTypeInt 32 0
427 %_Globals_ = OpTypeStruct %uint %uint
428 %_ptr_Uniform__Globals_ = OpTypePointer Uniform %_Globals_
429 %_ = OpVariable %_ptr_Uniform__Globals_ Uniform
430 %int = OpTypeInt 32 1
431 %int_0 = OpConstant %int 0
432 %_ptr_Uniform_uint = OpTypePointer Uniform %uint
433 %bool = OpTypeBool
434 %uint_0 = OpConstant %uint 0
435 %float_1 = OpConstant %float 1
436 %int_1 = OpConstant %int 1
437 %float_0 = OpConstant %float 0
438 %_ptr_Output_v4float = OpTypePointer Output %v4float
439 %OutColor = OpVariable %_ptr_Output_v4float Output
440 %27 = OpUndef %v4float
441 )";
442
443 const std::string after_predefs =
444 R"(OpCapability Shader
445 %1 = OpExtInstImport "GLSL.std.450"
446 OpMemoryModel Logical GLSL450
447 OpEntryPoint Fragment %main "main" %In0 %In1 %In2 %OutColor
448 OpExecutionMode %main OriginUpperLeft
449 OpSource GLSL 450
450 OpName %main "main"
451 OpName %In0 "In0"
452 OpName %In1 "In1"
453 OpName %In2 "In2"
454 OpName %_Globals_ "_Globals_"
455 OpMemberName %_Globals_ 0 "g_b"
456 OpMemberName %_Globals_ 1 "g_b2"
457 OpName %_ ""
458 OpName %OutColor "OutColor"
459 OpDecorate %In0 Location 0
460 OpDecorate %In1 Location 1
461 OpDecorate %In2 Location 2
462 OpMemberDecorate %_Globals_ 0 Offset 0
463 OpMemberDecorate %_Globals_ 1 Offset 4
464 OpDecorate %_Globals_ Block
465 OpDecorate %_ DescriptorSet 0
466 OpDecorate %_ Binding 0
467 OpDecorate %OutColor Location 0
468 %void = OpTypeVoid
469 %10 = OpTypeFunction %void
470 %float = OpTypeFloat 32
471 %v4float = OpTypeVector %float 4
472 %_ptr_Function_v4float = OpTypePointer Function %v4float
473 %_ptr_Input_v4float = OpTypePointer Input %v4float
474 %In0 = OpVariable %_ptr_Input_v4float Input
475 %_ptr_Input_float = OpTypePointer Input %float
476 %In1 = OpVariable %_ptr_Input_float Input
477 %In2 = OpVariable %_ptr_Input_float Input
478 %uint = OpTypeInt 32 0
479 %_Globals_ = OpTypeStruct %uint %uint
480 %_ptr_Uniform__Globals_ = OpTypePointer Uniform %_Globals_
481 %_ = OpVariable %_ptr_Uniform__Globals_ Uniform
482 %int = OpTypeInt 32 1
483 %int_0 = OpConstant %int 0
484 %_ptr_Uniform_uint = OpTypePointer Uniform %uint
485 %bool = OpTypeBool
486 %uint_0 = OpConstant %uint 0
487 %float_1 = OpConstant %float 1
488 %int_1 = OpConstant %int 1
489 %float_0 = OpConstant %float 0
490 %_ptr_Output_v4float = OpTypePointer Output %v4float
491 %OutColor = OpVariable %_ptr_Output_v4float Output
492 %27 = OpUndef %v4float
493 )";
494
495 const std::string before =
496 R"(%main = OpFunction %void None %10
497 %28 = OpLabel
498 %29 = OpLoad %v4float %In0
499 %30 = OpLoad %float %In1
500 %31 = OpLoad %float %In2
501 %32 = OpFAdd %float %30 %31
502 %33 = OpCompositeInsert %v4float %32 %29 1
503 %34 = OpAccessChain %_ptr_Uniform_uint %_ %int_0
504 %35 = OpLoad %uint %34
505 %36 = OpINotEqual %bool %35 %uint_0
506 OpSelectionMerge %37 None
507 OpBranchConditional %36 %38 %37
508 %38 = OpLabel
509 %39 = OpCompositeInsert %v4float %float_1 %33 0
510 OpBranch %37
511 %37 = OpLabel
512 %40 = OpPhi %v4float %33 %28 %39 %38
513 %41 = OpCompositeExtract %float %40 0
514 %42 = OpCompositeInsert %v4float %41 %27 0
515 %43 = OpCompositeExtract %float %40 1
516 %44 = OpCompositeInsert %v4float %43 %42 1
517 %45 = OpAccessChain %_ptr_Uniform_uint %_ %int_1
518 %46 = OpLoad %uint %45
519 %47 = OpINotEqual %bool %46 %uint_0
520 OpSelectionMerge %48 None
521 OpBranchConditional %47 %49 %48
522 %49 = OpLabel
523 %50 = OpCompositeInsert %v4float %float_0 %44 0
524 OpBranch %48
525 %48 = OpLabel
526 %51 = OpPhi %v4float %44 %37 %50 %49
527 %52 = OpCompositeExtract %float %51 0
528 %53 = OpCompositeExtract %float %51 0
529 %54 = OpCompositeConstruct %v4float %52 %53 %float_0 %float_1
530 OpStore %OutColor %54
531 OpReturn
532 OpFunctionEnd
533 )";
534
535 const std::string after =
536 R"(%main = OpFunction %void None %10
537 %28 = OpLabel
538 %29 = OpLoad %v4float %In0
539 %34 = OpAccessChain %_ptr_Uniform_uint %_ %int_0
540 %35 = OpLoad %uint %34
541 %36 = OpINotEqual %bool %35 %uint_0
542 OpSelectionMerge %37 None
543 OpBranchConditional %36 %38 %37
544 %38 = OpLabel
545 %39 = OpCompositeInsert %v4float %float_1 %29 0
546 OpBranch %37
547 %37 = OpLabel
548 %40 = OpPhi %v4float %29 %28 %39 %38
549 %41 = OpCompositeExtract %float %40 0
550 %42 = OpCompositeInsert %v4float %41 %27 0
551 %45 = OpAccessChain %_ptr_Uniform_uint %_ %int_1
552 %46 = OpLoad %uint %45
553 %47 = OpINotEqual %bool %46 %uint_0
554 OpSelectionMerge %48 None
555 OpBranchConditional %47 %49 %48
556 %49 = OpLabel
557 %50 = OpCompositeInsert %v4float %float_0 %42 0
558 OpBranch %48
559 %48 = OpLabel
560 %51 = OpPhi %v4float %42 %37 %50 %49
561 %52 = OpCompositeExtract %float %51 0
562 %53 = OpCompositeExtract %float %51 0
563 %54 = OpCompositeConstruct %v4float %52 %53 %float_0 %float_1
564 OpStore %OutColor %54
565 OpReturn
566 OpFunctionEnd
567 )";
568
569 SinglePassRunAndCheck<DeadInsertElimPass>(before_predefs + before,
570 after_predefs + after, true, true);
571 }
572
TEST_F(VectorDCETest,InsertObjectLive)573 TEST_F(VectorDCETest, InsertObjectLive) {
574 // Make sure that the object being inserted in an OpCompositeInsert
575 // is not removed when it is uses later on.
576 const std::string before =
577 R"(OpCapability Shader
578 %1 = OpExtInstImport "GLSL.std.450"
579 OpMemoryModel Logical GLSL450
580 OpEntryPoint Fragment %main "main" %In0 %In1 %OutColor
581 OpExecutionMode %main OriginUpperLeft
582 OpSource GLSL 450
583 OpName %main "main"
584 OpName %In0 "In0"
585 OpName %In1 "In1"
586 OpName %OutColor "OutColor"
587 OpDecorate %In0 Location 0
588 OpDecorate %In1 Location 1
589 OpDecorate %OutColor Location 0
590 %void = OpTypeVoid
591 %10 = OpTypeFunction %void
592 %float = OpTypeFloat 32
593 %v4float = OpTypeVector %float 4
594 %_ptr_Input_v4float = OpTypePointer Input %v4float
595 %In0 = OpVariable %_ptr_Input_v4float Input
596 %_ptr_Input_float = OpTypePointer Input %float
597 %In1 = OpVariable %_ptr_Input_float Input
598 %_ptr_Output_v4float = OpTypePointer Output %v4float
599 %OutColor = OpVariable %_ptr_Output_v4float Output
600 %main = OpFunction %void None %10
601 %28 = OpLabel
602 %29 = OpLoad %v4float %In0
603 %30 = OpLoad %float %In1
604 %33 = OpCompositeInsert %v4float %30 %29 1
605 OpStore %OutColor %33
606 OpReturn
607 OpFunctionEnd
608 )";
609
610 SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
611 SinglePassRunAndCheck<DeadInsertElimPass>(before, before, true, true);
612 }
613
TEST_F(VectorDCETest,DeadInsertInCycle)614 TEST_F(VectorDCETest, DeadInsertInCycle) {
615 // Dead insert in chain with cycle. Demonstrates analysis can handle
616 // cycles in chains going through scalars intermediate values.
617 //
618 // Note: The SPIR-V assembly has had store/load elimination
619 // performed to allow the inserts and extracts to directly
620 // reference each other.
621 //
622 // #version 450
623 //
624 // layout (location=0) in vec4 In0;
625 // layout (location=1) in float In1;
626 // layout (location=2) in float In2;
627 // layout (location=0) out vec4 OutColor;
628 //
629 // layout(std140, binding = 0 ) uniform _Globals_
630 // {
631 // int g_n ;
632 // };
633 //
634 // void main()
635 // {
636 // vec2 v = vec2(0.0, 1.0);
637 // for (int i = 0; i < g_n; i++) {
638 // v.x = v.x + 1;
639 // v.y = v.y * 0.9; // dead
640 // }
641 // OutColor = vec4(v.x);
642 // }
643
644 const std::string assembly =
645 R"(
646 ; CHECK: [[init_val:%\w+]] = OpConstantComposite %v2float %float_0 %float_1
647 ; CHECK: [[undef:%\w+]] = OpUndef %v2float
648 ; CHECK: OpFunction
649 ; CHECK: [[entry_lab:%\w+]] = OpLabel
650 ; CHECK: [[loop_header:%\w+]] = OpLabel
651 ; CHECK: OpPhi %v2float [[init_val]] [[entry_lab]] [[x_insert:%\w+]] {{%\w+}}
652 ; CHECK: [[x_insert:%\w+]] = OpCompositeInsert %v2float %43 [[undef]] 0
653 OpCapability Shader
654 %1 = OpExtInstImport "GLSL.std.450"
655 OpMemoryModel Logical GLSL450
656 OpEntryPoint Fragment %main "main" %OutColor %In0 %In1 %In2
657 OpExecutionMode %main OriginUpperLeft
658 OpSource GLSL 450
659 OpName %main "main"
660 OpName %_Globals_ "_Globals_"
661 OpMemberName %_Globals_ 0 "g_n"
662 OpName %_ ""
663 OpName %OutColor "OutColor"
664 OpName %In0 "In0"
665 OpName %In1 "In1"
666 OpName %In2 "In2"
667 OpMemberDecorate %_Globals_ 0 Offset 0
668 OpDecorate %_Globals_ Block
669 OpDecorate %_ DescriptorSet 0
670 OpDecorate %_ Binding 0
671 OpDecorate %OutColor Location 0
672 OpDecorate %In0 Location 0
673 OpDecorate %In1 Location 1
674 OpDecorate %In2 Location 2
675 %void = OpTypeVoid
676 %10 = OpTypeFunction %void
677 %float = OpTypeFloat 32
678 %v2float = OpTypeVector %float 2
679 %_ptr_Function_v2float = OpTypePointer Function %v2float
680 %float_0 = OpConstant %float 0
681 %float_1 = OpConstant %float 1
682 %16 = OpConstantComposite %v2float %float_0 %float_1
683 %int = OpTypeInt 32 1
684 %_ptr_Function_int = OpTypePointer Function %int
685 %int_0 = OpConstant %int 0
686 %_Globals_ = OpTypeStruct %int
687 %_ptr_Uniform__Globals_ = OpTypePointer Uniform %_Globals_
688 %_ = OpVariable %_ptr_Uniform__Globals_ Uniform
689 %_ptr_Uniform_int = OpTypePointer Uniform %int
690 %bool = OpTypeBool
691 %float_0_75 = OpConstant %float 0.75
692 %int_1 = OpConstant %int 1
693 %v4float = OpTypeVector %float 4
694 %_ptr_Output_v4float = OpTypePointer Output %v4float
695 %OutColor = OpVariable %_ptr_Output_v4float Output
696 %_ptr_Input_v4float = OpTypePointer Input %v4float
697 %In0 = OpVariable %_ptr_Input_v4float Input
698 %_ptr_Input_float = OpTypePointer Input %float
699 %In1 = OpVariable %_ptr_Input_float Input
700 %In2 = OpVariable %_ptr_Input_float Input
701 %main = OpFunction %void None %10
702 %29 = OpLabel
703 OpBranch %30
704 %30 = OpLabel
705 %31 = OpPhi %v2float %16 %29 %32 %33
706 %34 = OpPhi %int %int_0 %29 %35 %33
707 OpLoopMerge %36 %33 None
708 OpBranch %37
709 %37 = OpLabel
710 %38 = OpAccessChain %_ptr_Uniform_int %_ %int_0
711 %39 = OpLoad %int %38
712 %40 = OpSLessThan %bool %34 %39
713 OpBranchConditional %40 %41 %36
714 %41 = OpLabel
715 %42 = OpCompositeExtract %float %31 0
716 %43 = OpFAdd %float %42 %float_1
717 %44 = OpCompositeInsert %v2float %43 %31 0
718 %45 = OpCompositeExtract %float %44 1
719 %46 = OpFMul %float %45 %float_0_75
720 %32 = OpCompositeInsert %v2float %46 %44 1
721 OpBranch %33
722 %33 = OpLabel
723 %35 = OpIAdd %int %34 %int_1
724 OpBranch %30
725 %36 = OpLabel
726 %47 = OpCompositeExtract %float %31 0
727 %48 = OpCompositeConstruct %v4float %47 %47 %47 %47
728 OpStore %OutColor %48
729 OpReturn
730 OpFunctionEnd
731 )";
732
733 SinglePassRunAndMatch<VectorDCE>(assembly, true);
734 }
735
TEST_F(VectorDCETest,DeadLoadFeedingCompositeConstruct)736 TEST_F(VectorDCETest, DeadLoadFeedingCompositeConstruct) {
737 // Detach the loads feeding the CompositeConstruct for the unused elements.
738 // TODO: Implement the rewrite for CompositeConstruct.
739
740 const std::string assembly =
741 R"(
742 ; CHECK: [[undef:%\w+]] = OpUndef %float
743 ; CHECK: [[ac:%\w+]] = OpAccessChain %_ptr_Input_float %In0 %uint_2
744 ; CHECK: [[load:%\w+]] = OpLoad %float [[ac]]
745 ; CHECK: OpCompositeConstruct %v3float [[load]] [[undef]] [[undef]]
746 OpCapability Shader
747 %1 = OpExtInstImport "GLSL.std.450"
748 OpMemoryModel Logical GLSL450
749 OpEntryPoint Fragment %main "main" %In0 %OutColor
750 OpExecutionMode %main OriginUpperLeft
751 OpSource GLSL 450
752 OpSourceExtension "GL_GOOGLE_cpp_style_line_directive"
753 OpSourceExtension "GL_GOOGLE_include_directive"
754 OpName %main "main"
755 OpName %In0 "In0"
756 OpName %OutColor "OutColor"
757 OpDecorate %In0 Location 0
758 OpDecorate %OutColor Location 0
759 %void = OpTypeVoid
760 %6 = OpTypeFunction %void
761 %float = OpTypeFloat 32
762 %v4float = OpTypeVector %float 4
763 %_ptr_Input_v4float = OpTypePointer Input %v4float
764 %In0 = OpVariable %_ptr_Input_v4float Input
765 %uint = OpTypeInt 32 0
766 %uint_0 = OpConstant %uint 0
767 %_ptr_Input_float = OpTypePointer Input %float
768 %uint_1 = OpConstant %uint 1
769 %uint_2 = OpConstant %uint 2
770 %v3float = OpTypeVector %float 3
771 %int = OpTypeInt 32 1
772 %int_0 = OpConstant %int 0
773 %int_20 = OpConstant %int 20
774 %bool = OpTypeBool
775 %float_1 = OpConstant %float 1
776 %int_1 = OpConstant %int 1
777 %_ptr_Output_v4float = OpTypePointer Output %v4float
778 %OutColor = OpVariable %_ptr_Output_v4float Output
779 %23 = OpUndef %v3float
780 %main = OpFunction %void None %6
781 %24 = OpLabel
782 %25 = OpAccessChain %_ptr_Input_float %In0 %uint_0
783 %26 = OpLoad %float %25
784 %27 = OpAccessChain %_ptr_Input_float %In0 %uint_1
785 %28 = OpLoad %float %27
786 %29 = OpAccessChain %_ptr_Input_float %In0 %uint_2
787 %30 = OpLoad %float %29
788 %31 = OpCompositeConstruct %v3float %30 %28 %26
789 OpBranch %32
790 %32 = OpLabel
791 %33 = OpPhi %v3float %31 %24 %34 %35
792 %36 = OpPhi %int %int_0 %24 %37 %35
793 OpLoopMerge %38 %35 None
794 OpBranch %39
795 %39 = OpLabel
796 %40 = OpSLessThan %bool %36 %int_20
797 OpBranchConditional %40 %41 %38
798 %41 = OpLabel
799 %42 = OpCompositeExtract %float %33 0
800 %43 = OpFAdd %float %42 %float_1
801 %34 = OpCompositeInsert %v3float %43 %33 0
802 OpBranch %35
803 %35 = OpLabel
804 %37 = OpIAdd %int %36 %int_1
805 OpBranch %32
806 %38 = OpLabel
807 %44 = OpCompositeExtract %float %33 0
808 %45 = OpCompositeConstruct %v4float %44 %44 %44 %44
809 OpStore %OutColor %45
810 OpReturn
811 OpFunctionEnd
812 )";
813
814 SinglePassRunAndMatch<VectorDCE>(assembly, true);
815 }
816
TEST_F(VectorDCETest,DeadLoadFeedingVectorShuffle)817 TEST_F(VectorDCETest, DeadLoadFeedingVectorShuffle) {
818 // Detach the loads feeding the CompositeConstruct for the unused elements.
819 // TODO: Implement the rewrite for CompositeConstruct.
820
821 const std::string assembly =
822 R"(
823 ; MemPass Type2Undef does not reuse and already existing undef.
824 ; CHECK: {{%\w+}} = OpUndef %v3float
825 ; CHECK: [[undef:%\w+]] = OpUndef %v3float
826 ; CHECK: OpFunction
827 ; CHECK: OpVectorShuffle %v3float {{%\w+}} [[undef]] 0 4 5
828 OpCapability Shader
829 %1 = OpExtInstImport "GLSL.std.450"
830 OpMemoryModel Logical GLSL450
831 OpEntryPoint Fragment %main "main" %In0 %OutColor
832 OpExecutionMode %main OriginUpperLeft
833 OpSource GLSL 450
834 OpSourceExtension "GL_GOOGLE_cpp_style_line_directive"
835 OpSourceExtension "GL_GOOGLE_include_directive"
836 OpName %main "main"
837 OpName %In0 "In0"
838 OpName %OutColor "OutColor"
839 OpDecorate %In0 Location 0
840 OpDecorate %OutColor Location 0
841 %void = OpTypeVoid
842 %6 = OpTypeFunction %void
843 %float = OpTypeFloat 32
844 %v4float = OpTypeVector %float 4
845 %_ptr_Input_v4float = OpTypePointer Input %v4float
846 %In0 = OpVariable %_ptr_Input_v4float Input
847 %uint = OpTypeInt 32 0
848 %uint_0 = OpConstant %uint 0
849 %_ptr_Input_float = OpTypePointer Input %float
850 %uint_1 = OpConstant %uint 1
851 %uint_2 = OpConstant %uint 2
852 %v3float = OpTypeVector %float 3
853 %int = OpTypeInt 32 1
854 %int_0 = OpConstant %int 0
855 %int_20 = OpConstant %int 20
856 %bool = OpTypeBool
857 %float_1 = OpConstant %float 1
858 %vec_const = OpConstantComposite %v3float %float_1 %float_1 %float_1
859 %int_1 = OpConstant %int 1
860 %_ptr_Output_v4float = OpTypePointer Output %v4float
861 %OutColor = OpVariable %_ptr_Output_v4float Output
862 %23 = OpUndef %v3float
863 %main = OpFunction %void None %6
864 %24 = OpLabel
865 %25 = OpAccessChain %_ptr_Input_float %In0 %uint_0
866 %26 = OpLoad %float %25
867 %27 = OpAccessChain %_ptr_Input_float %In0 %uint_1
868 %28 = OpLoad %float %27
869 %29 = OpAccessChain %_ptr_Input_float %In0 %uint_2
870 %30 = OpLoad %float %29
871 %31 = OpCompositeConstruct %v3float %30 %28 %26
872 %sh = OpVectorShuffle %v3float %vec_const %31 0 4 5
873 OpBranch %32
874 %32 = OpLabel
875 %33 = OpPhi %v3float %sh %24 %34 %35
876 %36 = OpPhi %int %int_0 %24 %37 %35
877 OpLoopMerge %38 %35 None
878 OpBranch %39
879 %39 = OpLabel
880 %40 = OpSLessThan %bool %36 %int_20
881 OpBranchConditional %40 %41 %38
882 %41 = OpLabel
883 %42 = OpCompositeExtract %float %33 0
884 %43 = OpFAdd %float %42 %float_1
885 %34 = OpCompositeInsert %v3float %43 %33 0
886 OpBranch %35
887 %35 = OpLabel
888 %37 = OpIAdd %int %36 %int_1
889 OpBranch %32
890 %38 = OpLabel
891 %44 = OpCompositeExtract %float %33 0
892 %45 = OpCompositeConstruct %v4float %44 %44 %44 %44
893 OpStore %OutColor %45
894 OpReturn
895 OpFunctionEnd
896 )";
897
898 SinglePassRunAndMatch<VectorDCE>(assembly, true);
899 }
900
TEST_F(VectorDCETest,DeadInstThroughShuffle)901 TEST_F(VectorDCETest, DeadInstThroughShuffle) {
902 // Dead insert in chain with cycle. Demonstrates analysis can handle
903 // cycles in chains.
904 //
905 // Note: The SPIR-V assembly has had store/load elimination
906 // performed to allow the inserts and extracts to directly
907 // reference each other.
908 //
909 // #version 450
910 //
911 // layout (location=0) out vec4 OutColor;
912 //
913 // void main()
914 // {
915 // vec2 v;
916 // v.x = 0.0;
917 // v.y = 0.1; // dead
918 // for (int i = 0; i < 20; i++) {
919 // v.x = v.x + 1;
920 // v = v * 0.9;
921 // }
922 // OutColor = vec4(v.x);
923 // }
924
925 const std::string assembly =
926 R"(
927 ; CHECK: OpFunction
928 ; CHECK-NOT: OpCompositeInsert %v2float {{%\w+}} 1
929 ; CHECK: OpFunctionEnd
930 OpCapability Shader
931 %1 = OpExtInstImport "GLSL.std.450"
932 OpMemoryModel Logical GLSL450
933 OpEntryPoint Fragment %main "main" %OutColor
934 OpExecutionMode %main OriginUpperLeft
935 OpSource GLSL 450
936 OpSourceExtension "GL_GOOGLE_cpp_style_line_directive"
937 OpSourceExtension "GL_GOOGLE_include_directive"
938 OpName %main "main"
939 OpName %OutColor "OutColor"
940 OpDecorate %OutColor Location 0
941 %void = OpTypeVoid
942 %3 = OpTypeFunction %void
943 %float = OpTypeFloat 32
944 %v2float = OpTypeVector %float 2
945 %float_0 = OpConstant %float 0
946 %float_0_100000001 = OpConstant %float 0.100000001
947 %int = OpTypeInt 32 1
948 %int_0 = OpConstant %int 0
949 %int_20 = OpConstant %int 20
950 %bool = OpTypeBool
951 %float_1 = OpConstant %float 1
952 %float_0_899999976 = OpConstant %float 0.899999976
953 %int_1 = OpConstant %int 1
954 %v4float = OpTypeVector %float 4
955 %_ptr_Output_v4float = OpTypePointer Output %v4float
956 %OutColor = OpVariable %_ptr_Output_v4float Output
957 %58 = OpUndef %v2float
958 %main = OpFunction %void None %3
959 %5 = OpLabel
960 %49 = OpCompositeInsert %v2float %float_0 %58 0
961 %51 = OpCompositeInsert %v2float %float_0_100000001 %49 1
962 OpBranch %22
963 %22 = OpLabel
964 %60 = OpPhi %v2float %51 %5 %38 %25
965 %59 = OpPhi %int %int_0 %5 %41 %25
966 OpLoopMerge %24 %25 None
967 OpBranch %26
968 %26 = OpLabel
969 %30 = OpSLessThan %bool %59 %int_20
970 OpBranchConditional %30 %23 %24
971 %23 = OpLabel
972 %53 = OpCompositeExtract %float %60 0
973 %34 = OpFAdd %float %53 %float_1
974 %55 = OpCompositeInsert %v2float %34 %60 0
975 %38 = OpVectorTimesScalar %v2float %55 %float_0_899999976
976 OpBranch %25
977 %25 = OpLabel
978 %41 = OpIAdd %int %59 %int_1
979 OpBranch %22
980 %24 = OpLabel
981 %57 = OpCompositeExtract %float %60 0
982 %47 = OpCompositeConstruct %v4float %57 %57 %57 %57
983 OpStore %OutColor %47
984 OpReturn
985 OpFunctionEnd
986 )";
987
988 SinglePassRunAndMatch<VectorDCE>(assembly, true);
989 }
990
TEST_F(VectorDCETest,DeadInsertThroughOtherInst)991 TEST_F(VectorDCETest, DeadInsertThroughOtherInst) {
992 // Dead insert in chain with cycle. Demonstrates analysis can handle
993 // cycles in chains.
994 //
995 // Note: The SPIR-V assembly has had store/load elimination
996 // performed to allow the inserts and extracts to directly
997 // reference each other.
998 //
999 // #version 450
1000 //
1001 // layout (location=0) out vec4 OutColor;
1002 //
1003 // void main()
1004 // {
1005 // vec2 v;
1006 // v.x = 0.0;
1007 // v.y = 0.1; // dead
1008 // for (int i = 0; i < 20; i++) {
1009 // v.x = v.x + 1;
1010 // v = v * 0.9;
1011 // }
1012 // OutColor = vec4(v.x);
1013 // }
1014
1015 const std::string assembly =
1016 R"(
1017 ; CHECK: OpFunction
1018 ; CHECK-NOT: OpCompositeInsert %v2float {{%\w+}} 1
1019 ; CHECK: OpFunctionEnd
1020 OpCapability Shader
1021 %1 = OpExtInstImport "GLSL.std.450"
1022 OpMemoryModel Logical GLSL450
1023 OpEntryPoint Fragment %main "main" %OutColor
1024 OpExecutionMode %main OriginUpperLeft
1025 OpSource GLSL 450
1026 OpSourceExtension "GL_GOOGLE_cpp_style_line_directive"
1027 OpSourceExtension "GL_GOOGLE_include_directive"
1028 OpName %main "main"
1029 OpName %OutColor "OutColor"
1030 OpDecorate %OutColor Location 0
1031 %void = OpTypeVoid
1032 %3 = OpTypeFunction %void
1033 %float = OpTypeFloat 32
1034 %v2float = OpTypeVector %float 2
1035 %float_0 = OpConstant %float 0
1036 %float_0_100000001 = OpConstant %float 0.100000001
1037 %int = OpTypeInt 32 1
1038 %int_0 = OpConstant %int 0
1039 %int_20 = OpConstant %int 20
1040 %bool = OpTypeBool
1041 %float_1 = OpConstant %float 1
1042 %float_0_899999976 = OpConstant %float 0.899999976
1043 %int_1 = OpConstant %int 1
1044 %v4float = OpTypeVector %float 4
1045 %_ptr_Output_v4float = OpTypePointer Output %v4float
1046 %OutColor = OpVariable %_ptr_Output_v4float Output
1047 %58 = OpUndef %v2float
1048 %main = OpFunction %void None %3
1049 %5 = OpLabel
1050 %49 = OpCompositeInsert %v2float %float_0 %58 0
1051 %51 = OpCompositeInsert %v2float %float_0_100000001 %49 1
1052 OpBranch %22
1053 %22 = OpLabel
1054 %60 = OpPhi %v2float %51 %5 %38 %25
1055 %59 = OpPhi %int %int_0 %5 %41 %25
1056 OpLoopMerge %24 %25 None
1057 OpBranch %26
1058 %26 = OpLabel
1059 %30 = OpSLessThan %bool %59 %int_20
1060 OpBranchConditional %30 %23 %24
1061 %23 = OpLabel
1062 %53 = OpCompositeExtract %float %60 0
1063 %34 = OpFAdd %float %53 %float_1
1064 %55 = OpCompositeInsert %v2float %34 %60 0
1065 %38 = OpVectorTimesScalar %v2float %55 %float_0_899999976
1066 OpBranch %25
1067 %25 = OpLabel
1068 %41 = OpIAdd %int %59 %int_1
1069 OpBranch %22
1070 %24 = OpLabel
1071 %57 = OpCompositeExtract %float %60 0
1072 %47 = OpCompositeConstruct %v4float %57 %57 %57 %57
1073 OpStore %OutColor %47
1074 OpReturn
1075 OpFunctionEnd
1076 )";
1077
1078 SinglePassRunAndMatch<VectorDCE>(assembly, true);
1079 }
1080
TEST_F(VectorDCETest,VectorIntoCompositeConstruct)1081 TEST_F(VectorDCETest, VectorIntoCompositeConstruct) {
1082 const std::string text = R"(OpCapability Linkage
1083 OpCapability Shader
1084 OpMemoryModel Logical GLSL450
1085 OpEntryPoint Fragment %1 "EntryPoint_Main" %2 %3
1086 OpExecutionMode %1 OriginUpperLeft
1087 OpDecorate %2 Location 0
1088 OpDecorate %_struct_4 Block
1089 OpDecorate %3 Location 0
1090 %float = OpTypeFloat 32
1091 %v2float = OpTypeVector %float 2
1092 %_ptr_Function_v2float = OpTypePointer Function %v2float
1093 %v4float = OpTypeVector %float 4
1094 %_ptr_Function_v4float = OpTypePointer Function %v4float
1095 %mat4v4float = OpTypeMatrix %v4float 4
1096 %_ptr_Function_mat4v4float = OpTypePointer Function %mat4v4float
1097 %v3float = OpTypeVector %float 3
1098 %_ptr_Function_v3float = OpTypePointer Function %v3float
1099 %_struct_14 = OpTypeStruct %v2float %mat4v4float %v3float %v2float %v4float
1100 %_ptr_Function__struct_14 = OpTypePointer Function %_struct_14
1101 %void = OpTypeVoid
1102 %int = OpTypeInt 32 1
1103 %int_2 = OpConstant %int 2
1104 %int_1 = OpConstant %int 1
1105 %int_4 = OpConstant %int 4
1106 %int_0 = OpConstant %int 0
1107 %int_3 = OpConstant %int 3
1108 %float_0 = OpConstant %float 0
1109 %float_1 = OpConstant %float 1
1110 %_ptr_Input_v2float = OpTypePointer Input %v2float
1111 %2 = OpVariable %_ptr_Input_v2float Input
1112 %_ptr_Output_v2float = OpTypePointer Output %v2float
1113 %_struct_4 = OpTypeStruct %v2float
1114 %_ptr_Output__struct_4 = OpTypePointer Output %_struct_4
1115 %3 = OpVariable %_ptr_Output__struct_4 Output
1116 %28 = OpTypeFunction %void
1117 %29 = OpConstantComposite %v2float %float_0 %float_0
1118 %30 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
1119 %31 = OpConstantComposite %mat4v4float %30 %30 %30 %30
1120 %32 = OpConstantComposite %v3float %float_0 %float_0 %float_0
1121 %1 = OpFunction %void None %28
1122 %33 = OpLabel
1123 %34 = OpVariable %_ptr_Function_v4float Function
1124 %35 = OpVariable %_ptr_Function__struct_14 Function
1125 %36 = OpAccessChain %_ptr_Function_v2float %35 %int_0
1126 OpStore %36 %29
1127 %37 = OpAccessChain %_ptr_Function_mat4v4float %35 %int_1
1128 OpStore %37 %31
1129 %38 = OpAccessChain %_ptr_Function_v3float %35 %int_2
1130 OpStore %38 %32
1131 %39 = OpAccessChain %_ptr_Function_v2float %35 %int_3
1132 OpStore %39 %29
1133 %40 = OpAccessChain %_ptr_Function_v4float %35 %int_4
1134 OpStore %40 %30
1135 %41 = OpLoad %v2float %2
1136 OpStore %36 %41
1137 %42 = OpLoad %v3float %38
1138 %43 = OpCompositeConstruct %v4float %42 %float_1
1139 %44 = OpLoad %mat4v4float %37
1140 %45 = OpVectorTimesMatrix %v4float %43 %44
1141 OpStore %34 %45
1142 OpCopyMemory %40 %34
1143 OpCopyMemory %36 %39
1144 %46 = OpAccessChain %_ptr_Output_v2float %3 %int_0
1145 %47 = OpLoad %v2float %36
1146 OpStore %46 %47
1147 OpReturn
1148 OpFunctionEnd
1149 )";
1150
1151 SinglePassRunAndCheck<DeadInsertElimPass>(text, text, true, true);
1152 }
1153
1154 } // namespace
1155 } // namespace opt
1156 } // namespace spvtools
1157