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 <memory>
17 #include <string>
18 
19 #include "test/opt/pass_fixture.h"
20 #include "test/opt/pass_utils.h"
21 
22 namespace spvtools {
23 namespace opt {
24 namespace {
25 
26 using LocalSSAElimTest = PassTest<::testing::Test>;
27 
TEST_F(LocalSSAElimTest,ForLoop)28 TEST_F(LocalSSAElimTest, ForLoop) {
29   // #version 140
30   //
31   // in vec4 BC;
32   // out float fo;
33   //
34   // void main()
35   // {
36   //     float f = 0.0;
37   //     for (int i=0; i<4; i++) {
38   //       f = f + BC[i];
39   //     }
40   //     fo = f;
41   // }
42 
43   const std::string predefs =
44       R"(OpCapability Shader
45 %1 = OpExtInstImport "GLSL.std.450"
46 OpMemoryModel Logical GLSL450
47 OpEntryPoint Fragment %main "main" %BC %fo
48 OpExecutionMode %main OriginUpperLeft
49 OpSource GLSL 140
50 OpName %main "main"
51 OpName %f "f"
52 OpName %i "i"
53 OpName %BC "BC"
54 OpName %fo "fo"
55 %void = OpTypeVoid
56 %8 = OpTypeFunction %void
57 %float = OpTypeFloat 32
58 %_ptr_Function_float = OpTypePointer Function %float
59 %float_0 = OpConstant %float 0
60 %int = OpTypeInt 32 1
61 %_ptr_Function_int = OpTypePointer Function %int
62 %int_0 = OpConstant %int 0
63 %int_4 = OpConstant %int 4
64 %bool = OpTypeBool
65 %v4float = OpTypeVector %float 4
66 %_ptr_Input_v4float = OpTypePointer Input %v4float
67 %BC = OpVariable %_ptr_Input_v4float Input
68 %_ptr_Input_float = OpTypePointer Input %float
69 %int_1 = OpConstant %int 1
70 %_ptr_Output_float = OpTypePointer Output %float
71 %fo = OpVariable %_ptr_Output_float Output
72 )";
73 
74   const std::string before =
75       R"(%main = OpFunction %void None %8
76 %22 = OpLabel
77 %f = OpVariable %_ptr_Function_float Function
78 %i = OpVariable %_ptr_Function_int Function
79 OpStore %f %float_0
80 OpStore %i %int_0
81 OpBranch %23
82 %23 = OpLabel
83 OpLoopMerge %24 %25 None
84 OpBranch %26
85 %26 = OpLabel
86 %27 = OpLoad %int %i
87 %28 = OpSLessThan %bool %27 %int_4
88 OpBranchConditional %28 %29 %24
89 %29 = OpLabel
90 %30 = OpLoad %float %f
91 %31 = OpLoad %int %i
92 %32 = OpAccessChain %_ptr_Input_float %BC %31
93 %33 = OpLoad %float %32
94 %34 = OpFAdd %float %30 %33
95 OpStore %f %34
96 OpBranch %25
97 %25 = OpLabel
98 %35 = OpLoad %int %i
99 %36 = OpIAdd %int %35 %int_1
100 OpStore %i %36
101 OpBranch %23
102 %24 = OpLabel
103 %37 = OpLoad %float %f
104 OpStore %fo %37
105 OpReturn
106 OpFunctionEnd
107 )";
108 
109   const std::string after =
110       R"(%main = OpFunction %void None %8
111 %22 = OpLabel
112 %f = OpVariable %_ptr_Function_float Function
113 %i = OpVariable %_ptr_Function_int Function
114 OpStore %f %float_0
115 OpStore %i %int_0
116 OpBranch %23
117 %23 = OpLabel
118 %39 = OpPhi %float %float_0 %22 %34 %25
119 %38 = OpPhi %int %int_0 %22 %36 %25
120 OpLoopMerge %24 %25 None
121 OpBranch %26
122 %26 = OpLabel
123 %28 = OpSLessThan %bool %38 %int_4
124 OpBranchConditional %28 %29 %24
125 %29 = OpLabel
126 %32 = OpAccessChain %_ptr_Input_float %BC %38
127 %33 = OpLoad %float %32
128 %34 = OpFAdd %float %39 %33
129 OpStore %f %34
130 OpBranch %25
131 %25 = OpLabel
132 %36 = OpIAdd %int %38 %int_1
133 OpStore %i %36
134 OpBranch %23
135 %24 = OpLabel
136 OpStore %fo %39
137 OpReturn
138 OpFunctionEnd
139 )";
140 
141   SinglePassRunAndCheck<SSARewritePass>(predefs + before, predefs + after, true,
142                                         true);
143 }
144 
TEST_F(LocalSSAElimTest,NestedForLoop)145 TEST_F(LocalSSAElimTest, NestedForLoop) {
146   // #version 450
147   //
148   // layout (location=0) in mat4 BC;
149   // layout (location=0) out float fo;
150   //
151   // void main()
152   // {
153   //     float f = 0.0;
154   //     for (int i=0; i<4; i++)
155   //       for (int j=0; j<4; j++)
156   //         f = f + BC[i][j];
157   //     fo = f;
158   // }
159 
160   const std::string predefs =
161       R"(OpCapability Shader
162 %1 = OpExtInstImport "GLSL.std.450"
163 OpMemoryModel Logical GLSL450
164 OpEntryPoint Fragment %main "main" %BC %fo
165 OpExecutionMode %main OriginUpperLeft
166 OpSource GLSL 450
167 OpName %main "main"
168 OpName %f "f"
169 OpName %i "i"
170 OpName %j "j"
171 OpName %BC "BC"
172 OpName %fo "fo"
173 OpDecorate %BC Location 0
174 OpDecorate %fo Location 0
175 %void = OpTypeVoid
176 %9 = OpTypeFunction %void
177 %float = OpTypeFloat 32
178 %_ptr_Function_float = OpTypePointer Function %float
179 %float_0 = OpConstant %float 0
180 %int = OpTypeInt 32 1
181 %_ptr_Function_int = OpTypePointer Function %int
182 %int_0 = OpConstant %int 0
183 %int_4 = OpConstant %int 4
184 %bool = OpTypeBool
185 %v4float = OpTypeVector %float 4
186 %mat4v4float = OpTypeMatrix %v4float 4
187 %_ptr_Input_mat4v4float = OpTypePointer Input %mat4v4float
188 %BC = OpVariable %_ptr_Input_mat4v4float Input
189 %_ptr_Input_float = OpTypePointer Input %float
190 %int_1 = OpConstant %int 1
191 %_ptr_Output_float = OpTypePointer Output %float
192 %fo = OpVariable %_ptr_Output_float Output
193 )";
194 
195   const std::string before =
196       R"(
197 ; CHECK: = OpFunction
198 ; CHECK-NEXT: [[entry:%\w+]] = OpLabel
199 ; CHECK: [[outer_header:%\w+]] = OpLabel
200 ; CHECK-NEXT: [[outer_f:%\w+]] = OpPhi %float %float_0 [[entry]] [[inner_f:%\w+]] [[outer_be:%\w+]]
201 ; CHECK-NEXT: [[i:%\w+]] = OpPhi %int %int_0 [[entry]] [[i_next:%\w+]] [[outer_be]]
202 ; CHECK-NEXT: OpSLessThan {{%\w+}} [[i]]
203 ; CHECK: [[inner_pre_header:%\w+]] = OpLabel
204 ; CHECK: [[inner_header:%\w+]] = OpLabel
205 ; CHECK-NEXT: [[inner_f]] = OpPhi %float [[outer_f]] [[inner_pre_header]] [[f_next:%\w+]] [[inner_be:%\w+]]
206 ; CHECK-NEXT: [[j:%\w+]] = OpPhi %int %int_0 [[inner_pre_header]] [[j_next:%\w+]] [[inner_be]]
207 ; CHECK: [[inner_be]] = OpLabel
208 ; CHECK: [[f_next]] = OpFAdd %float [[inner_f]]
209 ; CHECK: [[j_next]] = OpIAdd %int [[j]] %int_1
210 ; CHECK: [[outer_be]] = OpLabel
211 ; CHECK: [[i_next]] = OpIAdd
212 ; CHECK: OpStore %fo [[outer_f]]
213 %main = OpFunction %void None %9
214 %24 = OpLabel
215 %f = OpVariable %_ptr_Function_float Function
216 %i = OpVariable %_ptr_Function_int Function
217 %j = OpVariable %_ptr_Function_int Function
218 OpStore %f %float_0
219 OpStore %i %int_0
220 OpBranch %25
221 %25 = OpLabel
222 %26 = OpLoad %int %i
223 %27 = OpSLessThan %bool %26 %int_4
224 OpLoopMerge %28 %29 None
225 OpBranchConditional %27 %30 %28
226 %30 = OpLabel
227 OpStore %j %int_0
228 OpBranch %31
229 %31 = OpLabel
230 %32 = OpLoad %int %j
231 %33 = OpSLessThan %bool %32 %int_4
232 OpLoopMerge %50 %34 None
233 OpBranchConditional %33 %34 %50
234 %34 = OpLabel
235 %35 = OpLoad %float %f
236 %36 = OpLoad %int %i
237 %37 = OpLoad %int %j
238 %38 = OpAccessChain %_ptr_Input_float %BC %36 %37
239 %39 = OpLoad %float %38
240 %40 = OpFAdd %float %35 %39
241 OpStore %f %40
242 %41 = OpLoad %int %j
243 %42 = OpIAdd %int %41 %int_1
244 OpStore %j %42
245 OpBranch %31
246 %50 = OpLabel
247 OpBranch %29
248 %29 = OpLabel
249 %43 = OpLoad %int %i
250 %44 = OpIAdd %int %43 %int_1
251 OpStore %i %44
252 OpBranch %25
253 %28 = OpLabel
254 %45 = OpLoad %float %f
255 OpStore %fo %45
256 OpReturn
257 OpFunctionEnd
258 )";
259 
260   SinglePassRunAndMatch<SSARewritePass>(predefs + before, true);
261 }
262 
TEST_F(LocalSSAElimTest,ForLoopWithContinue)263 TEST_F(LocalSSAElimTest, ForLoopWithContinue) {
264   // #version 140
265   //
266   // in vec4 BC;
267   // out float fo;
268   //
269   // void main()
270   // {
271   //     float f = 0.0;
272   //     for (int i=0; i<4; i++) {
273   //       float t = BC[i];
274   //       if (t < 0.0)
275   //         continue;
276   //       f = f + t;
277   //     }
278   //     fo = f;
279   // }
280 
281   const std::string predefs =
282       R"(OpCapability Shader
283 %1 = OpExtInstImport "GLSL.std.450"
284 OpMemoryModel Logical GLSL450
285 OpEntryPoint Fragment %main "main" %BC %fo
286 OpExecutionMode %main OriginUpperLeft
287 OpSource GLSL 140
288 )";
289 
290   const std::string names =
291       R"(OpName %main "main"
292 OpName %f "f"
293 OpName %i "i"
294 OpName %t "t"
295 OpName %BC "BC"
296 OpName %fo "fo"
297 )";
298 
299   const std::string predefs2 =
300       R"(%void = OpTypeVoid
301 %9 = OpTypeFunction %void
302 %float = OpTypeFloat 32
303 %_ptr_Function_float = OpTypePointer Function %float
304 %float_0 = OpConstant %float 0
305 %int = OpTypeInt 32 1
306 %_ptr_Function_int = OpTypePointer Function %int
307 %int_0 = OpConstant %int 0
308 %int_4 = OpConstant %int 4
309 %bool = OpTypeBool
310 %v4float = OpTypeVector %float 4
311 %_ptr_Input_v4float = OpTypePointer Input %v4float
312 %BC = OpVariable %_ptr_Input_v4float Input
313 %_ptr_Input_float = OpTypePointer Input %float
314 %int_1 = OpConstant %int 1
315 %_ptr_Output_float = OpTypePointer Output %float
316 %fo = OpVariable %_ptr_Output_float Output
317 )";
318 
319   const std::string before =
320       R"(%main = OpFunction %void None %9
321 %23 = OpLabel
322 %f = OpVariable %_ptr_Function_float Function
323 %i = OpVariable %_ptr_Function_int Function
324 %t = OpVariable %_ptr_Function_float Function
325 OpStore %f %float_0
326 OpStore %i %int_0
327 OpBranch %24
328 %24 = OpLabel
329 OpLoopMerge %25 %26 None
330 OpBranch %27
331 %27 = OpLabel
332 %28 = OpLoad %int %i
333 %29 = OpSLessThan %bool %28 %int_4
334 OpBranchConditional %29 %30 %25
335 %30 = OpLabel
336 %31 = OpLoad %int %i
337 %32 = OpAccessChain %_ptr_Input_float %BC %31
338 %33 = OpLoad %float %32
339 OpStore %t %33
340 %34 = OpLoad %float %t
341 %35 = OpFOrdLessThan %bool %34 %float_0
342 OpSelectionMerge %36 None
343 OpBranchConditional %35 %37 %36
344 %37 = OpLabel
345 OpBranch %26
346 %36 = OpLabel
347 %38 = OpLoad %float %f
348 %39 = OpLoad %float %t
349 %40 = OpFAdd %float %38 %39
350 OpStore %f %40
351 OpBranch %26
352 %26 = OpLabel
353 %41 = OpLoad %int %i
354 %42 = OpIAdd %int %41 %int_1
355 OpStore %i %42
356 OpBranch %24
357 %25 = OpLabel
358 %43 = OpLoad %float %f
359 OpStore %fo %43
360 OpReturn
361 OpFunctionEnd
362 )";
363 
364   const std::string after =
365       R"(%main = OpFunction %void None %9
366 %23 = OpLabel
367 %f = OpVariable %_ptr_Function_float Function
368 %i = OpVariable %_ptr_Function_int Function
369 %t = OpVariable %_ptr_Function_float Function
370 OpStore %f %float_0
371 OpStore %i %int_0
372 OpBranch %24
373 %24 = OpLabel
374 %45 = OpPhi %float %float_0 %23 %47 %26
375 %44 = OpPhi %int %int_0 %23 %42 %26
376 OpLoopMerge %25 %26 None
377 OpBranch %27
378 %27 = OpLabel
379 %29 = OpSLessThan %bool %44 %int_4
380 OpBranchConditional %29 %30 %25
381 %30 = OpLabel
382 %32 = OpAccessChain %_ptr_Input_float %BC %44
383 %33 = OpLoad %float %32
384 OpStore %t %33
385 %35 = OpFOrdLessThan %bool %33 %float_0
386 OpSelectionMerge %36 None
387 OpBranchConditional %35 %37 %36
388 %37 = OpLabel
389 OpBranch %26
390 %36 = OpLabel
391 %40 = OpFAdd %float %45 %33
392 OpStore %f %40
393 OpBranch %26
394 %26 = OpLabel
395 %47 = OpPhi %float %45 %37 %40 %36
396 %42 = OpIAdd %int %44 %int_1
397 OpStore %i %42
398 OpBranch %24
399 %25 = OpLabel
400 OpStore %fo %45
401 OpReturn
402 OpFunctionEnd
403 )";
404 
405   SinglePassRunAndCheck<SSARewritePass>(predefs + names + predefs2 + before,
406                                         predefs + names + predefs2 + after,
407                                         true, true);
408 }
409 
TEST_F(LocalSSAElimTest,ForLoopWithBreak)410 TEST_F(LocalSSAElimTest, ForLoopWithBreak) {
411   // #version 140
412   //
413   // in vec4 BC;
414   // out float fo;
415   //
416   // void main()
417   // {
418   //     float f = 0.0;
419   //     for (int i=0; i<4; i++) {
420   //       float t = f + BC[i];
421   //       if (t > 1.0)
422   //         break;
423   //       f = t;
424   //     }
425   //     fo = f;
426   // }
427 
428   const std::string predefs =
429       R"(OpCapability Shader
430 %1 = OpExtInstImport "GLSL.std.450"
431 OpMemoryModel Logical GLSL450
432 OpEntryPoint Fragment %main "main" %BC %fo
433 OpExecutionMode %main OriginUpperLeft
434 OpSource GLSL 140
435 OpName %main "main"
436 OpName %f "f"
437 OpName %i "i"
438 OpName %t "t"
439 OpName %BC "BC"
440 OpName %fo "fo"
441 %void = OpTypeVoid
442 %9 = OpTypeFunction %void
443 %float = OpTypeFloat 32
444 %_ptr_Function_float = OpTypePointer Function %float
445 %float_0 = OpConstant %float 0
446 %int = OpTypeInt 32 1
447 %_ptr_Function_int = OpTypePointer Function %int
448 %int_0 = OpConstant %int 0
449 %int_4 = OpConstant %int 4
450 %bool = OpTypeBool
451 %v4float = OpTypeVector %float 4
452 %_ptr_Input_v4float = OpTypePointer Input %v4float
453 %BC = OpVariable %_ptr_Input_v4float Input
454 %_ptr_Input_float = OpTypePointer Input %float
455 %float_1 = OpConstant %float 1
456 %int_1 = OpConstant %int 1
457 %_ptr_Output_float = OpTypePointer Output %float
458 %fo = OpVariable %_ptr_Output_float Output
459 )";
460 
461   const std::string before =
462       R"(%main = OpFunction %void None %9
463 %24 = OpLabel
464 %f = OpVariable %_ptr_Function_float Function
465 %i = OpVariable %_ptr_Function_int Function
466 %t = OpVariable %_ptr_Function_float Function
467 OpStore %f %float_0
468 OpStore %i %int_0
469 OpBranch %25
470 %25 = OpLabel
471 OpLoopMerge %26 %27 None
472 OpBranch %28
473 %28 = OpLabel
474 %29 = OpLoad %int %i
475 %30 = OpSLessThan %bool %29 %int_4
476 OpBranchConditional %30 %31 %26
477 %31 = OpLabel
478 %32 = OpLoad %float %f
479 %33 = OpLoad %int %i
480 %34 = OpAccessChain %_ptr_Input_float %BC %33
481 %35 = OpLoad %float %34
482 %36 = OpFAdd %float %32 %35
483 OpStore %t %36
484 %37 = OpLoad %float %t
485 %38 = OpFOrdGreaterThan %bool %37 %float_1
486 OpSelectionMerge %39 None
487 OpBranchConditional %38 %40 %39
488 %40 = OpLabel
489 OpBranch %26
490 %39 = OpLabel
491 %41 = OpLoad %float %t
492 OpStore %f %41
493 OpBranch %27
494 %27 = OpLabel
495 %42 = OpLoad %int %i
496 %43 = OpIAdd %int %42 %int_1
497 OpStore %i %43
498 OpBranch %25
499 %26 = OpLabel
500 %44 = OpLoad %float %f
501 OpStore %fo %44
502 OpReturn
503 OpFunctionEnd
504 )";
505 
506   const std::string after =
507       R"(%main = OpFunction %void None %9
508 %24 = OpLabel
509 %f = OpVariable %_ptr_Function_float Function
510 %i = OpVariable %_ptr_Function_int Function
511 %t = OpVariable %_ptr_Function_float Function
512 OpStore %f %float_0
513 OpStore %i %int_0
514 OpBranch %25
515 %25 = OpLabel
516 %46 = OpPhi %float %float_0 %24 %36 %27
517 %45 = OpPhi %int %int_0 %24 %43 %27
518 OpLoopMerge %26 %27 None
519 OpBranch %28
520 %28 = OpLabel
521 %30 = OpSLessThan %bool %45 %int_4
522 OpBranchConditional %30 %31 %26
523 %31 = OpLabel
524 %34 = OpAccessChain %_ptr_Input_float %BC %45
525 %35 = OpLoad %float %34
526 %36 = OpFAdd %float %46 %35
527 OpStore %t %36
528 %38 = OpFOrdGreaterThan %bool %36 %float_1
529 OpSelectionMerge %39 None
530 OpBranchConditional %38 %40 %39
531 %40 = OpLabel
532 OpBranch %26
533 %39 = OpLabel
534 OpStore %f %36
535 OpBranch %27
536 %27 = OpLabel
537 %43 = OpIAdd %int %45 %int_1
538 OpStore %i %43
539 OpBranch %25
540 %26 = OpLabel
541 OpStore %fo %46
542 OpReturn
543 OpFunctionEnd
544 )";
545 
546   SinglePassRunAndCheck<SSARewritePass>(predefs + before, predefs + after, true,
547                                         true);
548 }
549 
TEST_F(LocalSSAElimTest,SwapProblem)550 TEST_F(LocalSSAElimTest, SwapProblem) {
551   // #version 140
552   //
553   // in float fe;
554   // out float fo;
555   //
556   // void main()
557   // {
558   //     float f1 = 0.0;
559   //     float f2 = 1.0;
560   //     int ie = int(fe);
561   //     for (int i=0; i<ie; i++) {
562   //       float t = f1;
563   //       f1 = f2;
564   //       f2 = t;
565   //     }
566   //     fo = f1;
567   // }
568 
569   const std::string predefs =
570       R"(OpCapability Shader
571 %1 = OpExtInstImport "GLSL.std.450"
572 OpMemoryModel Logical GLSL450
573 OpEntryPoint Fragment %main "main" %fe %fo
574 OpExecutionMode %main OriginUpperLeft
575 OpSource GLSL 140
576 OpName %main "main"
577 OpName %f1 "f1"
578 OpName %f2 "f2"
579 OpName %ie "ie"
580 OpName %fe "fe"
581 OpName %i "i"
582 OpName %t "t"
583 OpName %fo "fo"
584 %void = OpTypeVoid
585 %11 = OpTypeFunction %void
586 %float = OpTypeFloat 32
587 %_ptr_Function_float = OpTypePointer Function %float
588 %float_0 = OpConstant %float 0
589 %float_1 = OpConstant %float 1
590 %int = OpTypeInt 32 1
591 %_ptr_Function_int = OpTypePointer Function %int
592 %_ptr_Input_float = OpTypePointer Input %float
593 %fe = OpVariable %_ptr_Input_float Input
594 %int_0 = OpConstant %int 0
595 %bool = OpTypeBool
596 %int_1 = OpConstant %int 1
597 %_ptr_Output_float = OpTypePointer Output %float
598 %fo = OpVariable %_ptr_Output_float Output
599 )";
600 
601   const std::string before =
602       R"(%main = OpFunction %void None %11
603 %23 = OpLabel
604 %f1 = OpVariable %_ptr_Function_float Function
605 %f2 = OpVariable %_ptr_Function_float Function
606 %ie = OpVariable %_ptr_Function_int Function
607 %i = OpVariable %_ptr_Function_int Function
608 %t = OpVariable %_ptr_Function_float Function
609 OpStore %f1 %float_0
610 OpStore %f2 %float_1
611 %24 = OpLoad %float %fe
612 %25 = OpConvertFToS %int %24
613 OpStore %ie %25
614 OpStore %i %int_0
615 OpBranch %26
616 %26 = OpLabel
617 OpLoopMerge %27 %28 None
618 OpBranch %29
619 %29 = OpLabel
620 %30 = OpLoad %int %i
621 %31 = OpLoad %int %ie
622 %32 = OpSLessThan %bool %30 %31
623 OpBranchConditional %32 %33 %27
624 %33 = OpLabel
625 %34 = OpLoad %float %f1
626 OpStore %t %34
627 %35 = OpLoad %float %f2
628 OpStore %f1 %35
629 %36 = OpLoad %float %t
630 OpStore %f2 %36
631 OpBranch %28
632 %28 = OpLabel
633 %37 = OpLoad %int %i
634 %38 = OpIAdd %int %37 %int_1
635 OpStore %i %38
636 OpBranch %26
637 %27 = OpLabel
638 %39 = OpLoad %float %f1
639 OpStore %fo %39
640 OpReturn
641 OpFunctionEnd
642 )";
643 
644   const std::string after =
645       R"(%main = OpFunction %void None %11
646 %23 = OpLabel
647 %f1 = OpVariable %_ptr_Function_float Function
648 %f2 = OpVariable %_ptr_Function_float Function
649 %ie = OpVariable %_ptr_Function_int Function
650 %i = OpVariable %_ptr_Function_int Function
651 %t = OpVariable %_ptr_Function_float Function
652 OpStore %f1 %float_0
653 OpStore %f2 %float_1
654 %24 = OpLoad %float %fe
655 %25 = OpConvertFToS %int %24
656 OpStore %ie %25
657 OpStore %i %int_0
658 OpBranch %26
659 %26 = OpLabel
660 %43 = OpPhi %float %float_1 %23 %42 %28
661 %42 = OpPhi %float %float_0 %23 %43 %28
662 %40 = OpPhi %int %int_0 %23 %38 %28
663 OpLoopMerge %27 %28 None
664 OpBranch %29
665 %29 = OpLabel
666 %32 = OpSLessThan %bool %40 %25
667 OpBranchConditional %32 %33 %27
668 %33 = OpLabel
669 OpStore %t %42
670 OpStore %f1 %43
671 OpStore %f2 %42
672 OpBranch %28
673 %28 = OpLabel
674 %38 = OpIAdd %int %40 %int_1
675 OpStore %i %38
676 OpBranch %26
677 %27 = OpLabel
678 OpStore %fo %42
679 OpReturn
680 OpFunctionEnd
681 )";
682 
683   SinglePassRunAndCheck<SSARewritePass>(predefs + before, predefs + after, true,
684                                         true);
685 }
686 
TEST_F(LocalSSAElimTest,LostCopyProblem)687 TEST_F(LocalSSAElimTest, LostCopyProblem) {
688   // #version 140
689   //
690   // in vec4 BC;
691   // out float fo;
692   //
693   // void main()
694   // {
695   //     float f = 0.0;
696   //     float t;
697   //     for (int i=0; i<4; i++) {
698   //       t = f;
699   //       f = f + BC[i];
700   //       if (f > 1.0)
701   //         break;
702   //     }
703   //     fo = t;
704   // }
705 
706   const std::string predefs =
707       R"(OpCapability Shader
708 %1 = OpExtInstImport "GLSL.std.450"
709 OpMemoryModel Logical GLSL450
710 OpEntryPoint Fragment %main "main" %BC %fo
711 OpExecutionMode %main OriginUpperLeft
712 OpSource GLSL 140
713 OpName %main "main"
714 OpName %f "f"
715 OpName %i "i"
716 OpName %t "t"
717 OpName %BC "BC"
718 OpName %fo "fo"
719 %void = OpTypeVoid
720 %9 = OpTypeFunction %void
721 %float = OpTypeFloat 32
722 %_ptr_Function_float = OpTypePointer Function %float
723 %float_0 = OpConstant %float 0
724 %int = OpTypeInt 32 1
725 %_ptr_Function_int = OpTypePointer Function %int
726 %int_0 = OpConstant %int 0
727 %int_4 = OpConstant %int 4
728 %bool = OpTypeBool
729 %v4float = OpTypeVector %float 4
730 %_ptr_Input_v4float = OpTypePointer Input %v4float
731 %BC = OpVariable %_ptr_Input_v4float Input
732 %_ptr_Input_float = OpTypePointer Input %float
733 %float_1 = OpConstant %float 1
734 %int_1 = OpConstant %int 1
735 %_ptr_Output_float = OpTypePointer Output %float
736 %fo = OpVariable %_ptr_Output_float Output
737 )";
738 
739   const std::string before =
740       R"(%main = OpFunction %void None %9
741 %24 = OpLabel
742 %f = OpVariable %_ptr_Function_float Function
743 %i = OpVariable %_ptr_Function_int Function
744 %t = OpVariable %_ptr_Function_float Function
745 OpStore %f %float_0
746 OpStore %i %int_0
747 OpBranch %25
748 %25 = OpLabel
749 OpLoopMerge %26 %27 None
750 OpBranch %28
751 %28 = OpLabel
752 %29 = OpLoad %int %i
753 %30 = OpSLessThan %bool %29 %int_4
754 OpBranchConditional %30 %31 %26
755 %31 = OpLabel
756 %32 = OpLoad %float %f
757 OpStore %t %32
758 %33 = OpLoad %float %f
759 %34 = OpLoad %int %i
760 %35 = OpAccessChain %_ptr_Input_float %BC %34
761 %36 = OpLoad %float %35
762 %37 = OpFAdd %float %33 %36
763 OpStore %f %37
764 %38 = OpLoad %float %f
765 %39 = OpFOrdGreaterThan %bool %38 %float_1
766 OpSelectionMerge %40 None
767 OpBranchConditional %39 %41 %40
768 %41 = OpLabel
769 OpBranch %26
770 %40 = OpLabel
771 OpBranch %27
772 %27 = OpLabel
773 %42 = OpLoad %int %i
774 %43 = OpIAdd %int %42 %int_1
775 OpStore %i %43
776 OpBranch %25
777 %26 = OpLabel
778 %44 = OpLoad %float %t
779 OpStore %fo %44
780 OpReturn
781 OpFunctionEnd
782 )";
783 
784   const std::string after =
785       R"(%49 = OpUndef %float
786 %main = OpFunction %void None %9
787 %24 = OpLabel
788 %f = OpVariable %_ptr_Function_float Function
789 %i = OpVariable %_ptr_Function_int Function
790 %t = OpVariable %_ptr_Function_float Function
791 OpStore %f %float_0
792 OpStore %i %int_0
793 OpBranch %25
794 %25 = OpLabel
795 %46 = OpPhi %float %float_0 %24 %37 %27
796 %45 = OpPhi %int %int_0 %24 %43 %27
797 %48 = OpPhi %float %49 %24 %46 %27
798 OpLoopMerge %26 %27 None
799 OpBranch %28
800 %28 = OpLabel
801 %30 = OpSLessThan %bool %45 %int_4
802 OpBranchConditional %30 %31 %26
803 %31 = OpLabel
804 OpStore %t %46
805 %35 = OpAccessChain %_ptr_Input_float %BC %45
806 %36 = OpLoad %float %35
807 %37 = OpFAdd %float %46 %36
808 OpStore %f %37
809 %39 = OpFOrdGreaterThan %bool %37 %float_1
810 OpSelectionMerge %40 None
811 OpBranchConditional %39 %41 %40
812 %41 = OpLabel
813 OpBranch %26
814 %40 = OpLabel
815 OpBranch %27
816 %27 = OpLabel
817 %43 = OpIAdd %int %45 %int_1
818 OpStore %i %43
819 OpBranch %25
820 %26 = OpLabel
821 %47 = OpPhi %float %48 %28 %46 %41
822 OpStore %fo %47
823 OpReturn
824 OpFunctionEnd
825 )";
826 
827   SinglePassRunAndCheck<SSARewritePass>(predefs + before, predefs + after, true,
828                                         true);
829 }
830 
TEST_F(LocalSSAElimTest,IfThenElse)831 TEST_F(LocalSSAElimTest, IfThenElse) {
832   // #version 140
833   //
834   // in vec4 BaseColor;
835   // in float f;
836   //
837   // void main()
838   // {
839   //     vec4 v;
840   //     if (f >= 0)
841   //       v = BaseColor * 0.5;
842   //     else
843   //       v = BaseColor + vec4(1.0,1.0,1.0,1.0);
844   //     gl_FragColor = v;
845   // }
846 
847   const std::string predefs =
848       R"(OpCapability Shader
849 %1 = OpExtInstImport "GLSL.std.450"
850 OpMemoryModel Logical GLSL450
851 OpEntryPoint Fragment %main "main" %f %BaseColor %gl_FragColor
852 OpExecutionMode %main OriginUpperLeft
853 OpSource GLSL 140
854 OpName %main "main"
855 OpName %f "f"
856 OpName %v "v"
857 OpName %BaseColor "BaseColor"
858 OpName %gl_FragColor "gl_FragColor"
859 %void = OpTypeVoid
860 %8 = OpTypeFunction %void
861 %float = OpTypeFloat 32
862 %_ptr_Input_float = OpTypePointer Input %float
863 %f = OpVariable %_ptr_Input_float Input
864 %float_0 = OpConstant %float 0
865 %bool = OpTypeBool
866 %v4float = OpTypeVector %float 4
867 %_ptr_Function_v4float = OpTypePointer Function %v4float
868 %_ptr_Input_v4float = OpTypePointer Input %v4float
869 %BaseColor = OpVariable %_ptr_Input_v4float Input
870 %float_0_5 = OpConstant %float 0.5
871 %float_1 = OpConstant %float 1
872 %18 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
873 %_ptr_Output_v4float = OpTypePointer Output %v4float
874 %gl_FragColor = OpVariable %_ptr_Output_v4float Output
875 )";
876 
877   const std::string before =
878       R"(%main = OpFunction %void None %8
879 %20 = OpLabel
880 %v = OpVariable %_ptr_Function_v4float Function
881 %21 = OpLoad %float %f
882 %22 = OpFOrdGreaterThanEqual %bool %21 %float_0
883 OpSelectionMerge %23 None
884 OpBranchConditional %22 %24 %25
885 %24 = OpLabel
886 %26 = OpLoad %v4float %BaseColor
887 %27 = OpVectorTimesScalar %v4float %26 %float_0_5
888 OpStore %v %27
889 OpBranch %23
890 %25 = OpLabel
891 %28 = OpLoad %v4float %BaseColor
892 %29 = OpFAdd %v4float %28 %18
893 OpStore %v %29
894 OpBranch %23
895 %23 = OpLabel
896 %30 = OpLoad %v4float %v
897 OpStore %gl_FragColor %30
898 OpReturn
899 OpFunctionEnd
900 )";
901 
902   const std::string after =
903       R"(%main = OpFunction %void None %8
904 %20 = OpLabel
905 %v = OpVariable %_ptr_Function_v4float Function
906 %21 = OpLoad %float %f
907 %22 = OpFOrdGreaterThanEqual %bool %21 %float_0
908 OpSelectionMerge %23 None
909 OpBranchConditional %22 %24 %25
910 %24 = OpLabel
911 %26 = OpLoad %v4float %BaseColor
912 %27 = OpVectorTimesScalar %v4float %26 %float_0_5
913 OpStore %v %27
914 OpBranch %23
915 %25 = OpLabel
916 %28 = OpLoad %v4float %BaseColor
917 %29 = OpFAdd %v4float %28 %18
918 OpStore %v %29
919 OpBranch %23
920 %23 = OpLabel
921 %31 = OpPhi %v4float %27 %24 %29 %25
922 OpStore %gl_FragColor %31
923 OpReturn
924 OpFunctionEnd
925 )";
926 
927   SinglePassRunAndCheck<SSARewritePass>(predefs + before, predefs + after, true,
928                                         true);
929 }
930 
TEST_F(LocalSSAElimTest,IfThen)931 TEST_F(LocalSSAElimTest, IfThen) {
932   // #version 140
933   //
934   // in vec4 BaseColor;
935   // in float f;
936   //
937   // void main()
938   // {
939   //     vec4 v = BaseColor;
940   //     if (f <= 0)
941   //       v = v * 0.5;
942   //     gl_FragColor = v;
943   // }
944 
945   const std::string predefs =
946       R"(OpCapability Shader
947 %1 = OpExtInstImport "GLSL.std.450"
948 OpMemoryModel Logical GLSL450
949 OpEntryPoint Fragment %main "main" %BaseColor %f %gl_FragColor
950 OpExecutionMode %main OriginUpperLeft
951 OpSource GLSL 140
952 OpName %main "main"
953 OpName %v "v"
954 OpName %BaseColor "BaseColor"
955 OpName %f "f"
956 OpName %gl_FragColor "gl_FragColor"
957 %void = OpTypeVoid
958 %8 = OpTypeFunction %void
959 %float = OpTypeFloat 32
960 %v4float = OpTypeVector %float 4
961 %_ptr_Function_v4float = OpTypePointer Function %v4float
962 %_ptr_Input_v4float = OpTypePointer Input %v4float
963 %BaseColor = OpVariable %_ptr_Input_v4float Input
964 %_ptr_Input_float = OpTypePointer Input %float
965 %f = OpVariable %_ptr_Input_float Input
966 %float_0 = OpConstant %float 0
967 %bool = OpTypeBool
968 %float_0_5 = OpConstant %float 0.5
969 %_ptr_Output_v4float = OpTypePointer Output %v4float
970 %gl_FragColor = OpVariable %_ptr_Output_v4float Output
971 )";
972 
973   const std::string before =
974       R"(%main = OpFunction %void None %8
975 %18 = OpLabel
976 %v = OpVariable %_ptr_Function_v4float Function
977 %19 = OpLoad %v4float %BaseColor
978 OpStore %v %19
979 %20 = OpLoad %float %f
980 %21 = OpFOrdLessThanEqual %bool %20 %float_0
981 OpSelectionMerge %22 None
982 OpBranchConditional %21 %23 %22
983 %23 = OpLabel
984 %24 = OpLoad %v4float %v
985 %25 = OpVectorTimesScalar %v4float %24 %float_0_5
986 OpStore %v %25
987 OpBranch %22
988 %22 = OpLabel
989 %26 = OpLoad %v4float %v
990 OpStore %gl_FragColor %26
991 OpReturn
992 OpFunctionEnd
993 )";
994 
995   const std::string after =
996       R"(%main = OpFunction %void None %8
997 %18 = OpLabel
998 %v = OpVariable %_ptr_Function_v4float Function
999 %19 = OpLoad %v4float %BaseColor
1000 OpStore %v %19
1001 %20 = OpLoad %float %f
1002 %21 = OpFOrdLessThanEqual %bool %20 %float_0
1003 OpSelectionMerge %22 None
1004 OpBranchConditional %21 %23 %22
1005 %23 = OpLabel
1006 %25 = OpVectorTimesScalar %v4float %19 %float_0_5
1007 OpStore %v %25
1008 OpBranch %22
1009 %22 = OpLabel
1010 %27 = OpPhi %v4float %19 %18 %25 %23
1011 OpStore %gl_FragColor %27
1012 OpReturn
1013 OpFunctionEnd
1014 )";
1015 
1016   SinglePassRunAndCheck<SSARewritePass>(predefs + before, predefs + after, true,
1017                                         true);
1018 }
1019 
TEST_F(LocalSSAElimTest,Switch)1020 TEST_F(LocalSSAElimTest, Switch) {
1021   // #version 140
1022   //
1023   // in vec4 BaseColor;
1024   // in float f;
1025   //
1026   // void main()
1027   // {
1028   //     vec4 v = BaseColor;
1029   //     int i = int(f);
1030   //     switch (i) {
1031   //       case 0:
1032   //         v = v * 0.25;
1033   //         break;
1034   //       case 1:
1035   //         v = v * 0.625;
1036   //         break;
1037   //       case 2:
1038   //         v = v * 0.75;
1039   //         break;
1040   //       default:
1041   //         break;
1042   //     }
1043   //     gl_FragColor = v;
1044   // }
1045 
1046   const std::string predefs =
1047       R"(OpCapability Shader
1048 %1 = OpExtInstImport "GLSL.std.450"
1049 OpMemoryModel Logical GLSL450
1050 OpEntryPoint Fragment %main "main" %BaseColor %f %gl_FragColor
1051 OpExecutionMode %main OriginUpperLeft
1052 OpSource GLSL 140
1053 OpName %main "main"
1054 OpName %v "v"
1055 OpName %BaseColor "BaseColor"
1056 OpName %i "i"
1057 OpName %f "f"
1058 OpName %gl_FragColor "gl_FragColor"
1059 %void = OpTypeVoid
1060 %9 = OpTypeFunction %void
1061 %float = OpTypeFloat 32
1062 %v4float = OpTypeVector %float 4
1063 %_ptr_Function_v4float = OpTypePointer Function %v4float
1064 %_ptr_Input_v4float = OpTypePointer Input %v4float
1065 %BaseColor = OpVariable %_ptr_Input_v4float Input
1066 %int = OpTypeInt 32 1
1067 %_ptr_Function_int = OpTypePointer Function %int
1068 %_ptr_Input_float = OpTypePointer Input %float
1069 %f = OpVariable %_ptr_Input_float Input
1070 %float_0_25 = OpConstant %float 0.25
1071 %float_0_625 = OpConstant %float 0.625
1072 %float_0_75 = OpConstant %float 0.75
1073 %_ptr_Output_v4float = OpTypePointer Output %v4float
1074 %gl_FragColor = OpVariable %_ptr_Output_v4float Output
1075 )";
1076 
1077   const std::string before =
1078       R"(%main = OpFunction %void None %9
1079 %21 = OpLabel
1080 %v = OpVariable %_ptr_Function_v4float Function
1081 %i = OpVariable %_ptr_Function_int Function
1082 %22 = OpLoad %v4float %BaseColor
1083 OpStore %v %22
1084 %23 = OpLoad %float %f
1085 %24 = OpConvertFToS %int %23
1086 OpStore %i %24
1087 %25 = OpLoad %int %i
1088 OpSelectionMerge %26 None
1089 OpSwitch %25 %27 0 %28 1 %29 2 %30
1090 %27 = OpLabel
1091 OpBranch %26
1092 %28 = OpLabel
1093 %31 = OpLoad %v4float %v
1094 %32 = OpVectorTimesScalar %v4float %31 %float_0_25
1095 OpStore %v %32
1096 OpBranch %26
1097 %29 = OpLabel
1098 %33 = OpLoad %v4float %v
1099 %34 = OpVectorTimesScalar %v4float %33 %float_0_625
1100 OpStore %v %34
1101 OpBranch %26
1102 %30 = OpLabel
1103 %35 = OpLoad %v4float %v
1104 %36 = OpVectorTimesScalar %v4float %35 %float_0_75
1105 OpStore %v %36
1106 OpBranch %26
1107 %26 = OpLabel
1108 %37 = OpLoad %v4float %v
1109 OpStore %gl_FragColor %37
1110 OpReturn
1111 OpFunctionEnd
1112 )";
1113 
1114   const std::string after =
1115       R"(%main = OpFunction %void None %9
1116 %21 = OpLabel
1117 %v = OpVariable %_ptr_Function_v4float Function
1118 %i = OpVariable %_ptr_Function_int Function
1119 %22 = OpLoad %v4float %BaseColor
1120 OpStore %v %22
1121 %23 = OpLoad %float %f
1122 %24 = OpConvertFToS %int %23
1123 OpStore %i %24
1124 OpSelectionMerge %26 None
1125 OpSwitch %24 %27 0 %28 1 %29 2 %30
1126 %27 = OpLabel
1127 OpBranch %26
1128 %28 = OpLabel
1129 %32 = OpVectorTimesScalar %v4float %22 %float_0_25
1130 OpStore %v %32
1131 OpBranch %26
1132 %29 = OpLabel
1133 %34 = OpVectorTimesScalar %v4float %22 %float_0_625
1134 OpStore %v %34
1135 OpBranch %26
1136 %30 = OpLabel
1137 %36 = OpVectorTimesScalar %v4float %22 %float_0_75
1138 OpStore %v %36
1139 OpBranch %26
1140 %26 = OpLabel
1141 %38 = OpPhi %v4float %22 %27 %32 %28 %34 %29 %36 %30
1142 OpStore %gl_FragColor %38
1143 OpReturn
1144 OpFunctionEnd
1145 )";
1146 
1147   SinglePassRunAndCheck<SSARewritePass>(predefs + before, predefs + after, true,
1148                                         true);
1149 }
1150 
TEST_F(LocalSSAElimTest,SwitchWithFallThrough)1151 TEST_F(LocalSSAElimTest, SwitchWithFallThrough) {
1152   // #version 140
1153   //
1154   // in vec4 BaseColor;
1155   // in float f;
1156   //
1157   // void main()
1158   // {
1159   //     vec4 v = BaseColor;
1160   //     int i = int(f);
1161   //     switch (i) {
1162   //       case 0:
1163   //         v = v * 0.25;
1164   //         break;
1165   //       case 1:
1166   //         v = v + 0.25;
1167   //       case 2:
1168   //         v = v * 0.75;
1169   //         break;
1170   //       default:
1171   //         break;
1172   //     }
1173   //     gl_FragColor = v;
1174   // }
1175 
1176   const std::string predefs =
1177       R"(OpCapability Shader
1178 %1 = OpExtInstImport "GLSL.std.450"
1179 OpMemoryModel Logical GLSL450
1180 OpEntryPoint Fragment %main "main" %BaseColor %f %gl_FragColor
1181 OpExecutionMode %main OriginUpperLeft
1182 OpSource GLSL 140
1183 OpName %main "main"
1184 OpName %v "v"
1185 OpName %BaseColor "BaseColor"
1186 OpName %i "i"
1187 OpName %f "f"
1188 OpName %gl_FragColor "gl_FragColor"
1189 %void = OpTypeVoid
1190 %9 = OpTypeFunction %void
1191 %float = OpTypeFloat 32
1192 %v4float = OpTypeVector %float 4
1193 %_ptr_Function_v4float = OpTypePointer Function %v4float
1194 %_ptr_Input_v4float = OpTypePointer Input %v4float
1195 %BaseColor = OpVariable %_ptr_Input_v4float Input
1196 %int = OpTypeInt 32 1
1197 %_ptr_Function_int = OpTypePointer Function %int
1198 %_ptr_Input_float = OpTypePointer Input %float
1199 %f = OpVariable %_ptr_Input_float Input
1200 %float_0_25 = OpConstant %float 0.25
1201 %float_0_75 = OpConstant %float 0.75
1202 %_ptr_Output_v4float = OpTypePointer Output %v4float
1203 %gl_FragColor = OpVariable %_ptr_Output_v4float Output
1204 )";
1205 
1206   const std::string before =
1207       R"(%main = OpFunction %void None %9
1208 %20 = OpLabel
1209 %v = OpVariable %_ptr_Function_v4float Function
1210 %i = OpVariable %_ptr_Function_int Function
1211 %21 = OpLoad %v4float %BaseColor
1212 OpStore %v %21
1213 %22 = OpLoad %float %f
1214 %23 = OpConvertFToS %int %22
1215 OpStore %i %23
1216 %24 = OpLoad %int %i
1217 OpSelectionMerge %25 None
1218 OpSwitch %24 %26 0 %27 1 %28 2 %29
1219 %26 = OpLabel
1220 OpBranch %25
1221 %27 = OpLabel
1222 %30 = OpLoad %v4float %v
1223 %31 = OpVectorTimesScalar %v4float %30 %float_0_25
1224 OpStore %v %31
1225 OpBranch %25
1226 %28 = OpLabel
1227 %32 = OpLoad %v4float %v
1228 %33 = OpCompositeConstruct %v4float %float_0_25 %float_0_25 %float_0_25 %float_0_25
1229 %34 = OpFAdd %v4float %32 %33
1230 OpStore %v %34
1231 OpBranch %29
1232 %29 = OpLabel
1233 %35 = OpLoad %v4float %v
1234 %36 = OpVectorTimesScalar %v4float %35 %float_0_75
1235 OpStore %v %36
1236 OpBranch %25
1237 %25 = OpLabel
1238 %37 = OpLoad %v4float %v
1239 OpStore %gl_FragColor %37
1240 OpReturn
1241 OpFunctionEnd
1242 )";
1243 
1244   const std::string after =
1245       R"(%main = OpFunction %void None %9
1246 %20 = OpLabel
1247 %v = OpVariable %_ptr_Function_v4float Function
1248 %i = OpVariable %_ptr_Function_int Function
1249 %21 = OpLoad %v4float %BaseColor
1250 OpStore %v %21
1251 %22 = OpLoad %float %f
1252 %23 = OpConvertFToS %int %22
1253 OpStore %i %23
1254 OpSelectionMerge %25 None
1255 OpSwitch %23 %26 0 %27 1 %28 2 %29
1256 %26 = OpLabel
1257 OpBranch %25
1258 %27 = OpLabel
1259 %31 = OpVectorTimesScalar %v4float %21 %float_0_25
1260 OpStore %v %31
1261 OpBranch %25
1262 %28 = OpLabel
1263 %33 = OpCompositeConstruct %v4float %float_0_25 %float_0_25 %float_0_25 %float_0_25
1264 %34 = OpFAdd %v4float %21 %33
1265 OpStore %v %34
1266 OpBranch %29
1267 %29 = OpLabel
1268 %38 = OpPhi %v4float %21 %20 %34 %28
1269 %36 = OpVectorTimesScalar %v4float %38 %float_0_75
1270 OpStore %v %36
1271 OpBranch %25
1272 %25 = OpLabel
1273 %39 = OpPhi %v4float %21 %26 %31 %27 %36 %29
1274 OpStore %gl_FragColor %39
1275 OpReturn
1276 OpFunctionEnd
1277 )";
1278 
1279   SinglePassRunAndCheck<SSARewritePass>(predefs + before, predefs + after, true,
1280                                         true);
1281 }
1282 
TEST_F(LocalSSAElimTest,DontPatchPhiInLoopHeaderThatIsNotAVar)1283 TEST_F(LocalSSAElimTest, DontPatchPhiInLoopHeaderThatIsNotAVar) {
1284   // From https://github.com/KhronosGroup/SPIRV-Tools/issues/826
1285   // Don't try patching the (%16 %7) value/predecessor pair in the OpPhi.
1286   // That OpPhi is unrelated to this optimization: we did not set that up
1287   // in the SSA initialization for the loop header block.
1288   // The pass should be a no-op on this module.
1289 
1290   const std::string before = R"(OpCapability Shader
1291 OpMemoryModel Logical GLSL450
1292 OpEntryPoint GLCompute %1 "main"
1293 %void = OpTypeVoid
1294 %3 = OpTypeFunction %void
1295 %float = OpTypeFloat 32
1296 %float_1 = OpConstant %float 1
1297 %1 = OpFunction %void None %3
1298 %6 = OpLabel
1299 OpBranch %7
1300 %7 = OpLabel
1301 %8 = OpPhi %float %float_1 %6 %9 %7
1302 %9 = OpFAdd %float %8 %float_1
1303 OpLoopMerge %10 %7 None
1304 OpBranch %7
1305 %10 = OpLabel
1306 OpReturn
1307 OpFunctionEnd
1308 )";
1309 
1310   SinglePassRunAndCheck<SSARewritePass>(before, before, true, true);
1311 }
1312 
TEST_F(LocalSSAElimTest,OptInitializedVariableLikeStore)1313 TEST_F(LocalSSAElimTest, OptInitializedVariableLikeStore) {
1314   // Note: SPIR-V edited to change store to v into variable initialization
1315   //
1316   // #version 450
1317   //
1318   // layout (location=0) in vec4 iColor;
1319   // layout (location=1) in float fi;
1320   // layout (location=0) out vec4 oColor;
1321   //
1322   // void main()
1323   // {
1324   //     vec4 v = vec4(0.0);
1325   //     if (fi < 0.0)
1326   //       v.x = iColor.x;
1327   //     oColor = v;
1328   // }
1329 
1330   const std::string predefs =
1331       R"(OpCapability Shader
1332 %1 = OpExtInstImport "GLSL.std.450"
1333 OpMemoryModel Logical GLSL450
1334 OpEntryPoint Fragment %main "main" %fi %iColor %oColor
1335 OpExecutionMode %main OriginUpperLeft
1336 OpSource GLSL 450
1337 OpName %main "main"
1338 OpName %v "v"
1339 OpName %fi "fi"
1340 OpName %iColor "iColor"
1341 OpName %oColor "oColor"
1342 OpDecorate %fi Location 1
1343 OpDecorate %iColor Location 0
1344 OpDecorate %oColor Location 0
1345 %void = OpTypeVoid
1346 %8 = OpTypeFunction %void
1347 %float = OpTypeFloat 32
1348 %v4float = OpTypeVector %float 4
1349 %_ptr_Function_v4float = OpTypePointer Function %v4float
1350 %float_0 = OpConstant %float 0
1351 %13 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
1352 %_ptr_Input_float = OpTypePointer Input %float
1353 %fi = OpVariable %_ptr_Input_float Input
1354 %bool = OpTypeBool
1355 %_ptr_Input_v4float = OpTypePointer Input %v4float
1356 %iColor = OpVariable %_ptr_Input_v4float Input
1357 %uint = OpTypeInt 32 0
1358 %uint_0 = OpConstant %uint 0
1359 %_ptr_Function_float = OpTypePointer Function %float
1360 %_ptr_Output_v4float = OpTypePointer Output %v4float
1361 %oColor = OpVariable %_ptr_Output_v4float Output
1362 )";
1363 
1364   const std::string func_before =
1365       R"(%main = OpFunction %void None %8
1366 %21 = OpLabel
1367 %v = OpVariable %_ptr_Function_v4float Function %13
1368 %22 = OpLoad %float %fi
1369 %23 = OpFOrdLessThan %bool %22 %float_0
1370 OpSelectionMerge %24 None
1371 OpBranchConditional %23 %25 %24
1372 %25 = OpLabel
1373 %26 = OpAccessChain %_ptr_Input_float %iColor %uint_0
1374 %27 = OpLoad %float %26
1375 %28 = OpLoad %v4float %v
1376 %29 = OpCompositeInsert %v4float %27 %28 0
1377 OpStore %v %29
1378 OpBranch %24
1379 %24 = OpLabel
1380 %30 = OpLoad %v4float %v
1381 OpStore %oColor %30
1382 OpReturn
1383 OpFunctionEnd
1384 )";
1385 
1386   const std::string func_after =
1387       R"(%main = OpFunction %void None %8
1388 %21 = OpLabel
1389 %v = OpVariable %_ptr_Function_v4float Function %13
1390 %22 = OpLoad %float %fi
1391 %23 = OpFOrdLessThan %bool %22 %float_0
1392 OpSelectionMerge %24 None
1393 OpBranchConditional %23 %25 %24
1394 %25 = OpLabel
1395 %26 = OpAccessChain %_ptr_Input_float %iColor %uint_0
1396 %27 = OpLoad %float %26
1397 %29 = OpCompositeInsert %v4float %27 %13 0
1398 OpStore %v %29
1399 OpBranch %24
1400 %24 = OpLabel
1401 %31 = OpPhi %v4float %13 %21 %29 %25
1402 OpStore %oColor %31
1403 OpReturn
1404 OpFunctionEnd
1405 )";
1406 
1407   SinglePassRunAndCheck<SSARewritePass>(predefs + func_before,
1408                                         predefs + func_after, true, true);
1409 }
1410 
TEST_F(LocalSSAElimTest,PointerVariable)1411 TEST_F(LocalSSAElimTest, PointerVariable) {
1412   // Test that checks if a pointer variable is removed.
1413 
1414   const std::string before =
1415       R"(OpCapability Shader
1416 OpMemoryModel Logical GLSL450
1417 OpEntryPoint Fragment %1 "main" %2
1418 OpExecutionMode %1 OriginUpperLeft
1419 OpMemberDecorate %_struct_3 0 Offset 0
1420 OpDecorate %_runtimearr__struct_3 ArrayStride 16
1421 OpMemberDecorate %_struct_5 0 Offset 0
1422 OpDecorate %_struct_5 BufferBlock
1423 OpMemberDecorate %_struct_6 0 Offset 0
1424 OpDecorate %_struct_6 BufferBlock
1425 OpDecorate %2 Location 0
1426 OpDecorate %7 DescriptorSet 0
1427 OpDecorate %7 Binding 0
1428 %void = OpTypeVoid
1429 %10 = OpTypeFunction %void
1430 %int = OpTypeInt 32 1
1431 %uint = OpTypeInt 32 0
1432 %float = OpTypeFloat 32
1433 %v4float = OpTypeVector %float 4
1434 %_ptr_Output_v4float = OpTypePointer Output %v4float
1435 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
1436 %_struct_3 = OpTypeStruct %v4float
1437 %_runtimearr__struct_3 = OpTypeRuntimeArray %_struct_3
1438 %_struct_5 = OpTypeStruct %_runtimearr__struct_3
1439 %_ptr_Uniform__struct_5 = OpTypePointer Uniform %_struct_5
1440 %_struct_6 = OpTypeStruct %int
1441 %_ptr_Uniform__struct_6 = OpTypePointer Uniform %_struct_6
1442 %_ptr_Function__ptr_Uniform__struct_5 = OpTypePointer Function %_ptr_Uniform__struct_5
1443 %_ptr_Function__ptr_Uniform__struct_6 = OpTypePointer Function %_ptr_Uniform__struct_6
1444 %int_0 = OpConstant %int 0
1445 %uint_0 = OpConstant %uint 0
1446 %2 = OpVariable %_ptr_Output_v4float Output
1447 %7 = OpVariable %_ptr_Uniform__struct_5 Uniform
1448 %1 = OpFunction %void None %10
1449 %23 = OpLabel
1450 %24 = OpVariable %_ptr_Function__ptr_Uniform__struct_5 Function
1451 OpStore %24 %7
1452 %26 = OpLoad %_ptr_Uniform__struct_5 %24
1453 %27 = OpAccessChain %_ptr_Uniform_v4float %26 %int_0 %uint_0 %int_0
1454 %28 = OpLoad %v4float %27
1455 %29 = OpCopyObject %v4float %28
1456 OpStore %2 %28
1457 OpReturn
1458 OpFunctionEnd
1459 )";
1460 
1461   const std::string after =
1462       R"(OpCapability Shader
1463 OpMemoryModel Logical GLSL450
1464 OpEntryPoint Fragment %1 "main" %2
1465 OpExecutionMode %1 OriginUpperLeft
1466 OpMemberDecorate %_struct_3 0 Offset 0
1467 OpDecorate %_runtimearr__struct_3 ArrayStride 16
1468 OpMemberDecorate %_struct_5 0 Offset 0
1469 OpDecorate %_struct_5 BufferBlock
1470 OpMemberDecorate %_struct_6 0 Offset 0
1471 OpDecorate %_struct_6 BufferBlock
1472 OpDecorate %2 Location 0
1473 OpDecorate %7 DescriptorSet 0
1474 OpDecorate %7 Binding 0
1475 %void = OpTypeVoid
1476 %10 = OpTypeFunction %void
1477 %int = OpTypeInt 32 1
1478 %uint = OpTypeInt 32 0
1479 %float = OpTypeFloat 32
1480 %v4float = OpTypeVector %float 4
1481 %_ptr_Output_v4float = OpTypePointer Output %v4float
1482 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
1483 %_struct_3 = OpTypeStruct %v4float
1484 %_runtimearr__struct_3 = OpTypeRuntimeArray %_struct_3
1485 %_struct_5 = OpTypeStruct %_runtimearr__struct_3
1486 %_ptr_Uniform__struct_5 = OpTypePointer Uniform %_struct_5
1487 %_struct_6 = OpTypeStruct %int
1488 %_ptr_Uniform__struct_6 = OpTypePointer Uniform %_struct_6
1489 %_ptr_Function__ptr_Uniform__struct_5 = OpTypePointer Function %_ptr_Uniform__struct_5
1490 %_ptr_Function__ptr_Uniform__struct_6 = OpTypePointer Function %_ptr_Uniform__struct_6
1491 %int_0 = OpConstant %int 0
1492 %uint_0 = OpConstant %uint 0
1493 %2 = OpVariable %_ptr_Output_v4float Output
1494 %7 = OpVariable %_ptr_Uniform__struct_5 Uniform
1495 %1 = OpFunction %void None %10
1496 %23 = OpLabel
1497 %24 = OpVariable %_ptr_Function__ptr_Uniform__struct_5 Function
1498 OpStore %24 %7
1499 %27 = OpAccessChain %_ptr_Uniform_v4float %7 %int_0 %uint_0 %int_0
1500 %28 = OpLoad %v4float %27
1501 %29 = OpCopyObject %v4float %28
1502 OpStore %2 %28
1503 OpReturn
1504 OpFunctionEnd
1505 )";
1506 
1507   // Relax logical pointers to allow pointer allocations.
1508   SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
1509   ValidatorOptions()->relax_logical_pointer = true;
1510   SinglePassRunAndCheck<SSARewritePass>(before, after, true, true);
1511 }
1512 
TEST_F(LocalSSAElimTest,VerifyInstToBlockMap)1513 TEST_F(LocalSSAElimTest, VerifyInstToBlockMap) {
1514   // #version 140
1515   //
1516   // in vec4 BC;
1517   // out float fo;
1518   //
1519   // void main()
1520   // {
1521   //     float f = 0.0;
1522   //     for (int i=0; i<4; i++) {
1523   //       f = f + BC[i];
1524   //     }
1525   //     fo = f;
1526   // }
1527 
1528   const std::string text = R"(
1529 OpCapability Shader
1530 %1 = OpExtInstImport "GLSL.std.450"
1531 OpMemoryModel Logical GLSL450
1532 OpEntryPoint Fragment %main "main" %BC %fo
1533 OpExecutionMode %main OriginUpperLeft
1534 OpSource GLSL 140
1535 OpName %main "main"
1536 OpName %f "f"
1537 OpName %i "i"
1538 OpName %BC "BC"
1539 OpName %fo "fo"
1540 %void = OpTypeVoid
1541 %8 = OpTypeFunction %void
1542 %float = OpTypeFloat 32
1543 %_ptr_Function_float = OpTypePointer Function %float
1544 %float_0 = OpConstant %float 0
1545 %int = OpTypeInt 32 1
1546 %_ptr_Function_int = OpTypePointer Function %int
1547 %int_0 = OpConstant %int 0
1548 %int_4 = OpConstant %int 4
1549 %bool = OpTypeBool
1550 %v4float = OpTypeVector %float 4
1551 %_ptr_Input_v4float = OpTypePointer Input %v4float
1552 %BC = OpVariable %_ptr_Input_v4float Input
1553 %_ptr_Input_float = OpTypePointer Input %float
1554 %int_1 = OpConstant %int 1
1555 %_ptr_Output_float = OpTypePointer Output %float
1556 %fo = OpVariable %_ptr_Output_float Output
1557 %main = OpFunction %void None %8
1558 %22 = OpLabel
1559 %f = OpVariable %_ptr_Function_float Function
1560 %i = OpVariable %_ptr_Function_int Function
1561 OpStore %f %float_0
1562 OpStore %i %int_0
1563 OpBranch %23
1564 %23 = OpLabel
1565 OpLoopMerge %24 %25 None
1566 OpBranch %26
1567 %26 = OpLabel
1568 %27 = OpLoad %int %i
1569 %28 = OpSLessThan %bool %27 %int_4
1570 OpBranchConditional %28 %29 %24
1571 %29 = OpLabel
1572 %30 = OpLoad %float %f
1573 %31 = OpLoad %int %i
1574 %32 = OpAccessChain %_ptr_Input_float %BC %31
1575 %33 = OpLoad %float %32
1576 %34 = OpFAdd %float %30 %33
1577 OpStore %f %34
1578 OpBranch %25
1579 %25 = OpLabel
1580 %35 = OpLoad %int %i
1581 %36 = OpIAdd %int %35 %int_1
1582 OpStore %i %36
1583 OpBranch %23
1584 %24 = OpLabel
1585 %37 = OpLoad %float %f
1586 OpStore %fo %37
1587 OpReturn
1588 OpFunctionEnd
1589 )";
1590 
1591   std::unique_ptr<IRContext> context =
1592       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
1593                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
1594   EXPECT_NE(nullptr, context);
1595 
1596   // Force the instruction to block mapping to get built.
1597   context->get_instr_block(27u);
1598 
1599   auto pass = MakeUnique<SSARewritePass>();
1600   pass->SetMessageConsumer(nullptr);
1601   const auto status = pass->Run(context.get());
1602   EXPECT_TRUE(status == Pass::Status::SuccessWithChange);
1603 }
1604 
TEST_F(LocalSSAElimTest,CompositeExtractProblem)1605 TEST_F(LocalSSAElimTest, CompositeExtractProblem) {
1606   const std::string spv_asm = R"(
1607                OpCapability Tessellation
1608           %1 = OpExtInstImport "GLSL.std.450"
1609                OpMemoryModel Logical GLSL450
1610                OpEntryPoint TessellationControl %2 "main" %16 %17 %18 %20 %22 %26 %27 %30 %31
1611        %void = OpTypeVoid
1612           %4 = OpTypeFunction %void
1613       %float = OpTypeFloat 32
1614     %v4float = OpTypeVector %float 4
1615        %uint = OpTypeInt 32 0
1616      %uint_3 = OpConstant %uint 3
1617     %v3float = OpTypeVector %float 3
1618     %v2float = OpTypeVector %float 2
1619  %_struct_11 = OpTypeStruct %v4float %v4float %v4float %v3float %v3float %v2float %v2float
1620 %_arr__struct_11_uint_3 = OpTypeArray %_struct_11 %uint_3
1621 %_ptr_Function__arr__struct_11_uint_3 = OpTypePointer Function %_arr__struct_11_uint_3
1622 %_arr_v4float_uint_3 = OpTypeArray %v4float %uint_3
1623 %_ptr_Input__arr_v4float_uint_3 = OpTypePointer Input %_arr_v4float_uint_3
1624          %16 = OpVariable %_ptr_Input__arr_v4float_uint_3 Input
1625          %17 = OpVariable %_ptr_Input__arr_v4float_uint_3 Input
1626          %18 = OpVariable %_ptr_Input__arr_v4float_uint_3 Input
1627 %_ptr_Input_uint = OpTypePointer Input %uint
1628          %20 = OpVariable %_ptr_Input_uint Input
1629 %_ptr_Output__arr_v4float_uint_3 = OpTypePointer Output %_arr_v4float_uint_3
1630          %22 = OpVariable %_ptr_Output__arr_v4float_uint_3 Output
1631 %_ptr_Output_v4float = OpTypePointer Output %v4float
1632 %_arr_v3float_uint_3 = OpTypeArray %v3float %uint_3
1633 %_ptr_Input__arr_v3float_uint_3 = OpTypePointer Input %_arr_v3float_uint_3
1634          %26 = OpVariable %_ptr_Input__arr_v3float_uint_3 Input
1635          %27 = OpVariable %_ptr_Input__arr_v3float_uint_3 Input
1636 %_arr_v2float_uint_3 = OpTypeArray %v2float %uint_3
1637 %_ptr_Input__arr_v2float_uint_3 = OpTypePointer Input %_arr_v2float_uint_3
1638          %30 = OpVariable %_ptr_Input__arr_v2float_uint_3 Input
1639          %31 = OpVariable %_ptr_Input__arr_v2float_uint_3 Input
1640 %_ptr_Function__struct_11 = OpTypePointer Function %_struct_11
1641           %2 = OpFunction %void None %4
1642          %33 = OpLabel
1643          %66 = OpVariable %_ptr_Function__arr__struct_11_uint_3 Function
1644          %34 = OpLoad %_arr_v4float_uint_3 %16
1645          %35 = OpLoad %_arr_v4float_uint_3 %17
1646          %36 = OpLoad %_arr_v4float_uint_3 %18
1647          %37 = OpLoad %_arr_v3float_uint_3 %26
1648          %38 = OpLoad %_arr_v3float_uint_3 %27
1649          %39 = OpLoad %_arr_v2float_uint_3 %30
1650          %40 = OpLoad %_arr_v2float_uint_3 %31
1651          %41 = OpCompositeExtract %v4float %34 0
1652          %42 = OpCompositeExtract %v4float %35 0
1653          %43 = OpCompositeExtract %v4float %36 0
1654          %44 = OpCompositeExtract %v3float %37 0
1655          %45 = OpCompositeExtract %v3float %38 0
1656          %46 = OpCompositeExtract %v2float %39 0
1657          %47 = OpCompositeExtract %v2float %40 0
1658          %48 = OpCompositeConstruct %_struct_11 %41 %42 %43 %44 %45 %46 %47
1659          %49 = OpCompositeExtract %v4float %34 1
1660          %50 = OpCompositeExtract %v4float %35 1
1661          %51 = OpCompositeExtract %v4float %36 1
1662          %52 = OpCompositeExtract %v3float %37 1
1663          %53 = OpCompositeExtract %v3float %38 1
1664          %54 = OpCompositeExtract %v2float %39 1
1665          %55 = OpCompositeExtract %v2float %40 1
1666          %56 = OpCompositeConstruct %_struct_11 %49 %50 %51 %52 %53 %54 %55
1667          %57 = OpCompositeExtract %v4float %34 2
1668          %58 = OpCompositeExtract %v4float %35 2
1669          %59 = OpCompositeExtract %v4float %36 2
1670          %60 = OpCompositeExtract %v3float %37 2
1671          %61 = OpCompositeExtract %v3float %38 2
1672          %62 = OpCompositeExtract %v2float %39 2
1673          %63 = OpCompositeExtract %v2float %40 2
1674          %64 = OpCompositeConstruct %_struct_11 %57 %58 %59 %60 %61 %62 %63
1675          %65 = OpCompositeConstruct %_arr__struct_11_uint_3 %48 %56 %64
1676          %67 = OpLoad %uint %20
1677 
1678 ; CHECK OpStore {{%\d+}} [[store_source:%\d+]]
1679                OpStore %66 %65
1680          %68 = OpAccessChain %_ptr_Function__struct_11 %66 %67
1681 
1682 ; This load was being removed, because %_ptr_Function__struct_11 was being
1683 ; wrongfully considered an SSA target.
1684 ; CHECK OpLoad %_struct_11 %68
1685          %69 = OpLoad %_struct_11 %68
1686 
1687 ; Similarly, %69 cannot be replaced with %65.
1688 ; CHECK-NOT: OpCompositeExtract %v4float [[store_source]] 0
1689          %70 = OpCompositeExtract %v4float %69 0
1690 
1691          %71 = OpAccessChain %_ptr_Output_v4float %22 %67
1692                OpStore %71 %70
1693                OpReturn
1694                OpFunctionEnd)";
1695 
1696   SinglePassRunAndMatch<SSARewritePass>(spv_asm, true);
1697 }
1698 
1699 // Test that the RelaxedPrecision decoration on the variable to added to the
1700 // result of the OpPhi instruction.
TEST_F(LocalSSAElimTest,DecoratedVariable)1701 TEST_F(LocalSSAElimTest, DecoratedVariable) {
1702   const std::string spv_asm = R"(
1703 ; CHECK: OpDecorate [[var:%\w+]] RelaxedPrecision
1704 ; CHECK: OpDecorate [[phi_id:%\w+]] RelaxedPrecision
1705 ; CHECK: [[phi_id]] = OpPhi
1706                OpCapability Shader
1707           %1 = OpExtInstImport "GLSL.std.450"
1708                OpMemoryModel Logical GLSL450
1709                OpEntryPoint GLCompute %2 "main"
1710                OpDecorate %v RelaxedPrecision
1711        %void = OpTypeVoid
1712      %func_t = OpTypeFunction %void
1713        %bool = OpTypeBool
1714        %true = OpConstantTrue %bool
1715        %int  = OpTypeInt 32 0
1716       %int_p = OpTypePointer Function %int
1717       %int_1 = OpConstant %int 1
1718       %int_0 = OpConstant %int 0
1719           %2 = OpFunction %void None %func_t
1720          %33 = OpLabel
1721          %v  = OpVariable %int_p Function
1722                OpSelectionMerge %merge None
1723                OpBranchConditional %true %l1 %l2
1724          %l1 = OpLabel
1725                OpStore %v %int_1
1726                OpBranch %merge
1727          %l2 = OpLabel
1728                OpStore %v %int_0
1729                OpBranch %merge
1730       %merge = OpLabel
1731          %ld = OpLoad %int %v
1732                OpReturn
1733                OpFunctionEnd)";
1734 
1735   SinglePassRunAndMatch<SSARewritePass>(spv_asm, true);
1736 }
1737 
1738 // Test that the RelaxedPrecision decoration on the variable to added to the
1739 // result of the OpPhi instruction.
TEST_F(LocalSSAElimTest,MultipleEdges)1740 TEST_F(LocalSSAElimTest, MultipleEdges) {
1741   const std::string spv_asm = R"(
1742   ; CHECK: OpSelectionMerge
1743   ; CHECK: [[header_bb:%\w+]] = OpLabel
1744   ; CHECK-NOT: OpLabel
1745   ; CHECK: OpSwitch {{%\w+}} {{%\w+}} 76 [[bb1:%\w+]] 17 [[bb2:%\w+]]
1746   ; CHECK-SAME: 4 [[bb2]]
1747   ; CHECK: [[bb2]] = OpLabel
1748   ; CHECK-NEXT: OpPhi [[type:%\w+]] [[val:%\w+]] [[header_bb]] %int_0 [[bb1]]
1749           OpCapability Shader
1750      %1 = OpExtInstImport "GLSL.std.450"
1751           OpMemoryModel Logical GLSL450
1752           OpEntryPoint Fragment %4 "main"
1753           OpExecutionMode %4 OriginUpperLeft
1754           OpSource ESSL 310
1755   %void = OpTypeVoid
1756      %3 = OpTypeFunction %void
1757    %int = OpTypeInt 32 1
1758   %_ptr_Function_int = OpTypePointer Function %int
1759   %int_0 = OpConstant %int 0
1760   %bool = OpTypeBool
1761   %true = OpConstantTrue %bool
1762   %false = OpConstantFalse %bool
1763   %int_1 = OpConstant %int 1
1764      %4 = OpFunction %void None %3
1765      %5 = OpLabel
1766      %8 = OpVariable %_ptr_Function_int Function
1767           OpBranch %10
1768     %10 = OpLabel
1769           OpLoopMerge %12 %13 None
1770           OpBranch %14
1771     %14 = OpLabel
1772           OpBranchConditional %true %11 %12
1773     %11 = OpLabel
1774           OpSelectionMerge %19 None
1775           OpBranchConditional %false %18 %19
1776     %18 = OpLabel
1777           OpSelectionMerge %22 None
1778           OpSwitch %int_0 %22 76 %20 17 %21 4 %21
1779     %20 = OpLabel
1780     %23 = OpLoad %int %8
1781           OpStore %8 %int_0
1782           OpBranch %21
1783     %21 = OpLabel
1784           OpBranch %22
1785     %22 = OpLabel
1786           OpBranch %19
1787     %19 = OpLabel
1788           OpBranch %13
1789     %13 = OpLabel
1790           OpBranch %10
1791     %12 = OpLabel
1792           OpReturn
1793           OpFunctionEnd
1794   )";
1795 
1796   SinglePassRunAndMatch<SSARewritePass>(spv_asm, true);
1797 }
1798 
TEST_F(LocalSSAElimTest,VariablePointerTest1)1799 TEST_F(LocalSSAElimTest, VariablePointerTest1) {
1800   // Check that the load of the first variable is still used and that the load
1801   // of the third variable is propagated.  The first load has to remain because
1802   // of the store to the variable pointer.
1803   const std::string text = R"(
1804 ; CHECK: [[v1:%\w+]] = OpVariable
1805 ; CHECK: [[v2:%\w+]] = OpVariable
1806 ; CHECK: [[v3:%\w+]] = OpVariable
1807 ; CHECK: [[ld1:%\w+]] = OpLoad %int [[v1]]
1808 ; CHECK: OpIAdd %int [[ld1]] %int_0
1809                OpCapability Shader
1810                OpCapability VariablePointers
1811           %1 = OpExtInstImport "GLSL.std.450"
1812                OpMemoryModel Logical GLSL450
1813                OpEntryPoint GLCompute %2 "main"
1814                OpExecutionMode %2 LocalSize 1 1 1
1815                OpSource GLSL 450
1816                OpMemberDecorate %_struct_3 0 Offset 0
1817                OpMemberDecorate %_struct_3 1 Offset 4
1818        %void = OpTypeVoid
1819           %5 = OpTypeFunction %void
1820         %int = OpTypeInt 32 1
1821        %bool = OpTypeBool
1822   %_struct_3 = OpTypeStruct %int %int
1823 %_ptr_Function__struct_3 = OpTypePointer Function %_struct_3
1824 %_ptr_Function_int = OpTypePointer Function %int
1825        %true = OpConstantTrue %bool
1826       %int_0 = OpConstant %int 0
1827       %int_1 = OpConstant %int 1
1828          %13 = OpConstantNull %_struct_3
1829           %2 = OpFunction %void None %5
1830          %14 = OpLabel
1831          %15 = OpVariable %_ptr_Function_int Function
1832          %16 = OpVariable %_ptr_Function_int Function
1833          %17 = OpVariable %_ptr_Function_int Function
1834                OpStore %15 %int_1
1835                OpStore %17 %int_0
1836                OpSelectionMerge %18 None
1837                OpBranchConditional %true %19 %20
1838          %19 = OpLabel
1839                OpBranch %18
1840          %20 = OpLabel
1841                OpBranch %18
1842          %18 = OpLabel
1843          %21 = OpPhi %_ptr_Function_int %15 %19 %16 %20
1844                OpStore %21 %int_0
1845          %22 = OpLoad %int %15
1846          %23 = OpLoad %int %17
1847          %24 = OpIAdd %int %22 %23
1848                OpReturn
1849                OpFunctionEnd
1850   )";
1851   SinglePassRunAndMatch<SSARewritePass>(text, false);
1852 }
1853 
TEST_F(LocalSSAElimTest,VariablePointerTest2)1854 TEST_F(LocalSSAElimTest, VariablePointerTest2) {
1855   // Check that the load of the first variable is still used and that the load
1856   // of the third variable is propagated.  The first load has to remain because
1857   // of the store to the variable pointer.
1858   const std::string text = R"(
1859 ; CHECK: [[v1:%\w+]] = OpVariable
1860 ; CHECK: [[v2:%\w+]] = OpVariable
1861 ; CHECK: [[v3:%\w+]] = OpVariable
1862 ; CHECK: [[ld1:%\w+]] = OpLoad %int [[v1]]
1863 ; CHECK: OpIAdd %int [[ld1]] %int_0
1864                OpCapability Shader
1865                OpCapability VariablePointers
1866           %1 = OpExtInstImport "GLSL.std.450"
1867                OpMemoryModel Logical GLSL450
1868                OpEntryPoint GLCompute %2 "main"
1869                OpExecutionMode %2 LocalSize 1 1 1
1870                OpSource GLSL 450
1871                OpMemberDecorate %_struct_3 0 Offset 0
1872                OpMemberDecorate %_struct_3 1 Offset 4
1873        %void = OpTypeVoid
1874           %5 = OpTypeFunction %void
1875         %int = OpTypeInt 32 1
1876        %bool = OpTypeBool
1877   %_struct_3 = OpTypeStruct %int %int
1878 %_ptr_Function__struct_3 = OpTypePointer Function %_struct_3
1879 %_ptr_Function_int = OpTypePointer Function %int
1880        %true = OpConstantTrue %bool
1881       %int_0 = OpConstant %int 0
1882       %int_1 = OpConstant %int 1
1883          %13 = OpConstantNull %_struct_3
1884           %2 = OpFunction %void None %5
1885          %14 = OpLabel
1886          %15 = OpVariable %_ptr_Function_int Function
1887          %16 = OpVariable %_ptr_Function_int Function
1888          %17 = OpVariable %_ptr_Function_int Function
1889                OpStore %15 %int_1
1890                OpStore %17 %int_0
1891                OpSelectionMerge %18 None
1892                OpBranchConditional %true %19 %20
1893          %19 = OpLabel
1894                OpBranch %18
1895          %20 = OpLabel
1896                OpBranch %18
1897          %18 = OpLabel
1898          %21 = OpPhi %_ptr_Function_int %15 %19 %16 %20
1899                OpStore %21 %int_0
1900          %22 = OpLoad %int %15
1901          %23 = OpLoad %int %17
1902          %24 = OpIAdd %int %22 %23
1903                OpReturn
1904                OpFunctionEnd
1905   )";
1906   SinglePassRunAndMatch<SSARewritePass>(text, false);
1907 }
1908 
TEST_F(LocalSSAElimTest,ChainedTrivialPhis)1909 TEST_F(LocalSSAElimTest, ChainedTrivialPhis) {
1910   // Check that the copy object get the undef value implicitly assigned in the
1911   // entry block.
1912   const std::string text = R"(
1913 ; CHECK: [[undef:%\w+]] = OpUndef %v4float
1914 ; CHECK: OpCopyObject %v4float [[undef]]
1915                OpCapability Shader
1916           %1 = OpExtInstImport "GLSL.std.450"
1917                OpMemoryModel Logical GLSL450
1918                OpEntryPoint GLCompute %2 "main"
1919                OpExecutionMode %2 LocalSize 1 18 6
1920                OpSource ESSL 310
1921        %void = OpTypeVoid
1922           %4 = OpTypeFunction %void
1923        %bool = OpTypeBool
1924       %float = OpTypeFloat 32
1925     %v4float = OpTypeVector %float 4
1926 %_ptr_Function_v4float = OpTypePointer Function %v4float
1927           %2 = OpFunction %void None %4
1928           %9 = OpLabel
1929          %10 = OpVariable %_ptr_Function_v4float Function
1930                OpBranch %11
1931          %11 = OpLabel
1932                OpLoopMerge %12 %13 None
1933                OpBranch %14
1934          %14 = OpLabel
1935          %15 = OpUndef %bool
1936                OpBranchConditional %15 %16 %12
1937          %16 = OpLabel
1938          %17 = OpUndef %bool
1939                OpSelectionMerge %18 None
1940                OpBranchConditional %17 %19 %18
1941          %19 = OpLabel
1942          %20 = OpUndef %bool
1943                OpLoopMerge %21 %22 None
1944                OpBranchConditional %20 %23 %21
1945          %23 = OpLabel
1946          %24 = OpLoad %v4float %10
1947          %25 = OpCopyObject %v4float %24
1948          %26 = OpUndef %bool
1949                OpBranch %22
1950          %22 = OpLabel
1951                OpBranch %19
1952          %21 = OpLabel
1953                OpBranch %12
1954          %18 = OpLabel
1955                OpBranch %13
1956          %13 = OpLabel
1957                OpBranch %11
1958          %12 = OpLabel
1959          %27 = OpLoad %v4float %10
1960                OpReturn
1961                OpFunctionEnd
1962   )";
1963   SinglePassRunAndMatch<SSARewritePass>(text, false);
1964 }
1965 
TEST_F(LocalSSAElimTest,Overflowtest1)1966 TEST_F(LocalSSAElimTest, Overflowtest1) {
1967   // Check that the copy object get the undef value implicitly assigned in the
1968   // entry block.
1969   const std::string text = R"(
1970 OpCapability Geometry
1971 OpMemoryModel Logical GLSL450
1972 OpEntryPoint Fragment %4 "P2Mai" %12 %17
1973 OpExecutionMode %4 OriginUpperLeft
1974 %2 = OpTypeVoid
1975 %3 = OpTypeFunction %2
1976 %6 = OpTypeFloat 32
1977 %7 = OpTypeVector %6 4
1978 %11 = OpTypePointer Input %7
1979 %16 = OpTypePointer Output %7
1980 %23 = OpTypePointer Function %7
1981 %12 = OpVariable %11 Input
1982 %17 = OpVariable %16 Output
1983 %4 = OpFunction %2 None %3
1984 %2177 = OpLabel
1985 %4194302 = OpVariable %23 Function
1986 %4194301 = OpLoad %7 %4194302
1987 OpStore %17 %4194301
1988 OpReturn
1989 OpFunctionEnd
1990   )";
1991 
1992   SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
1993 
1994   std::vector<Message> messages = {
1995       {SPV_MSG_ERROR, "", 0, 0, "ID overflow. Try running compact-ids."}};
1996   SetMessageConsumer(GetTestMessageConsumer(messages));
1997   auto result = SinglePassRunToBinary<SSARewritePass>(text, true);
1998   EXPECT_EQ(Pass::Status::Failure, std::get<1>(result));
1999 }
2000 
TEST_F(LocalSSAElimTest,OpConstantNull)2001 TEST_F(LocalSSAElimTest, OpConstantNull) {
2002   const std::string text = R"(
2003 OpCapability Addresses
2004 OpCapability Kernel
2005 OpCapability Int64
2006 OpMemoryModel Physical64 OpenCL
2007 OpEntryPoint Kernel %4 "A"
2008 OpSource OpenCL_C 200000
2009 %2 = OpTypeVoid
2010 %3 = OpTypeFunction %2
2011 %6 = OpTypeInt 32 0
2012 %11 = OpTypePointer CrossWorkgroup %6
2013 %16 = OpConstantNull %11
2014 %20 = OpConstant %6 269484031
2015 %4 = OpFunction %2 None %3
2016 %17 = OpLabel
2017 %18 = OpLoad %6 %16 Aligned 536870912
2018 %19 = OpBitwiseXor %6 %18 %20
2019 OpStore %16 %19 Aligned 536870912
2020 OpReturn
2021 OpFunctionEnd
2022   )";
2023 
2024   SinglePassRunToBinary<SSARewritePass>(text, false);
2025 }
2026 
TEST_F(LocalSSAElimTest,DebugForLoop)2027 TEST_F(LocalSSAElimTest, DebugForLoop) {
2028   // #version 140
2029   //
2030   // in vec4 BC;
2031   // out float fo;
2032   //
2033   // void main()
2034   // {
2035   //     float f = 0.0;
2036   //     for (int i=0; i<4; i++) {
2037   //       f = f + BC[i];
2038   //     }
2039   //     fo = f;
2040   // }
2041 
2042   const std::string text = R"(
2043 ; CHECK: [[f_name:%\w+]] = OpString "f"
2044 ; CHECK: [[i_name:%\w+]] = OpString "i"
2045 ; CHECK: [[dbg_f:%\w+]] = OpExtInst %void [[ext:%\d+]] DebugLocalVariable [[f_name]]
2046 ; CHECK: [[dbg_i:%\w+]] = OpExtInst %void [[ext]] DebugLocalVariable [[i_name]]
2047 
2048 ; CHECK:      OpStore %f %float_0
2049 ; CHECK-NEXT: OpExtInst %void [[ext]] DebugValue [[dbg_f]] %float_0
2050 ; CHECK-NEXT: OpStore %i %int_0
2051 ; CHECK-NEXT: OpExtInst %void [[ext]] DebugValue [[dbg_i]] %int_0
2052 
2053 ; CHECK-NOT:  DebugDeclare
2054 
2055 ; CHECK:      [[loop_head:%\w+]] = OpLabel
2056 ; CHECK:      [[phi0:%\w+]] = OpPhi %float %float_0
2057 ; CHECK:      [[phi1:%\w+]] = OpPhi %int %int_0
2058 ; CHECK-NEXT: OpExtInst %void [[ext]] DebugValue [[dbg_f]] [[phi0]]
2059 ; CHECK-NEXT: OpExtInst %void [[ext]] DebugValue [[dbg_i]] [[phi1]]
2060 ; CHECK:      OpLoopMerge [[loop_merge:%\w+]] [[loop_cont:%\w+]] None
2061 ; CHECK-NEXT: OpBranch [[loop_body:%\w+]]
2062 
2063 ; CHECK-NEXT: [[loop_body]] = OpLabel
2064 ; CHECK:      OpBranchConditional {{%\w+}} [[bb:%\w+]] [[loop_merge]]
2065 
2066 ; CHECK:      [[bb]] = OpLabel
2067 ; CHECK:      OpStore %f [[f_val:%\w+]]
2068 ; CHECK-NEXT: OpExtInst %void [[ext]] DebugValue [[dbg_f]] [[f_val]]
2069 ; CHECK-NEXT: OpBranch [[loop_cont]]
2070 
2071 ; CHECK:      [[loop_cont]] = OpLabel
2072 ; CHECK:      OpStore %i [[i_val:%\w+]]
2073 ; CHECK-NEXT: OpExtInst %void [[ext]] DebugValue [[dbg_i]] [[i_val]]
2074 ; CHECK-NEXT: OpBranch [[loop_head]]
2075 
2076 ; CHECK:      [[loop_merge]] = OpLabel
2077 
2078 OpCapability Shader
2079 %1 = OpExtInstImport "GLSL.std.450"
2080 %ext = OpExtInstImport "OpenCL.DebugInfo.100"
2081 OpMemoryModel Logical GLSL450
2082 OpEntryPoint Fragment %main "main" %BC %fo
2083 OpExecutionMode %main OriginUpperLeft
2084 %file_name = OpString "test"
2085 OpSource GLSL 140
2086 %float_name = OpString "float"
2087 %main_name = OpString "main"
2088 %f_name = OpString "f"
2089 %i_name = OpString "i"
2090 OpName %main "main"
2091 OpName %f "f"
2092 OpName %i "i"
2093 OpName %BC "BC"
2094 OpName %fo "fo"
2095 %void = OpTypeVoid
2096 %8 = OpTypeFunction %void
2097 %float = OpTypeFloat 32
2098 %_ptr_Function_float = OpTypePointer Function %float
2099 %float_0 = OpConstant %float 0
2100 %int = OpTypeInt 32 1
2101 %uint = OpTypeInt 32 0
2102 %uint_32 = OpConstant %uint 32
2103 %_ptr_Function_int = OpTypePointer Function %int
2104 %int_0 = OpConstant %int 0
2105 %int_4 = OpConstant %int 4
2106 %bool = OpTypeBool
2107 %v4float = OpTypeVector %float 4
2108 %_ptr_Input_v4float = OpTypePointer Input %v4float
2109 %BC = OpVariable %_ptr_Input_v4float Input
2110 %_ptr_Input_float = OpTypePointer Input %float
2111 %int_1 = OpConstant %int 1
2112 %_ptr_Output_float = OpTypePointer Output %float
2113 %fo = OpVariable %_ptr_Output_float Output
2114 %null_expr = OpExtInst %void %ext DebugExpression
2115 %src = OpExtInst %void %ext DebugSource %file_name
2116 %cu = OpExtInst %void %ext DebugCompilationUnit 1 4 %src HLSL
2117 %dbg_tf = OpExtInst %void %ext DebugTypeBasic %float_name %uint_32 Float
2118 %dbg_v4f = OpExtInst %void %ext DebugTypeVector %dbg_tf 4
2119 %main_ty = OpExtInst %void %ext DebugTypeFunction FlagIsProtected|FlagIsPrivate %dbg_v4f %dbg_v4f
2120 %dbg_main = OpExtInst %void %ext DebugFunction %main_name %main_ty %src 0 0 %cu %main_name FlagIsProtected|FlagIsPrivate 10 %main
2121 %dbg_f = OpExtInst %void %ext DebugLocalVariable %f_name %dbg_v4f %src 0 0 %dbg_main FlagIsLocal
2122 %dbg_i = OpExtInst %void %ext DebugLocalVariable %i_name %dbg_v4f %src 0 0 %dbg_main FlagIsLocal
2123 %main = OpFunction %void None %8
2124 %22 = OpLabel
2125 %s0 = OpExtInst %void %ext DebugScope %dbg_main
2126 %f = OpVariable %_ptr_Function_float Function
2127 %i = OpVariable %_ptr_Function_int Function
2128 OpStore %f %float_0
2129 OpStore %i %int_0
2130 %decl0 = OpExtInst %void %ext DebugDeclare %dbg_f %f %null_expr
2131 %decl1 = OpExtInst %void %ext DebugDeclare %dbg_i %i %null_expr
2132 OpBranch %23
2133 %23 = OpLabel
2134 %s1 = OpExtInst %void %ext DebugScope %dbg_main
2135 OpLoopMerge %24 %25 None
2136 OpBranch %26
2137 %26 = OpLabel
2138 %s2 = OpExtInst %void %ext DebugScope %dbg_main
2139 %27 = OpLoad %int %i
2140 %28 = OpSLessThan %bool %27 %int_4
2141 OpBranchConditional %28 %29 %24
2142 %29 = OpLabel
2143 %s3 = OpExtInst %void %ext DebugScope %dbg_main
2144 %30 = OpLoad %float %f
2145 %31 = OpLoad %int %i
2146 %32 = OpAccessChain %_ptr_Input_float %BC %31
2147 %33 = OpLoad %float %32
2148 %34 = OpFAdd %float %30 %33
2149 OpStore %f %34
2150 OpBranch %25
2151 %25 = OpLabel
2152 %s4 = OpExtInst %void %ext DebugScope %dbg_main
2153 %35 = OpLoad %int %i
2154 %36 = OpIAdd %int %35 %int_1
2155 OpStore %i %36
2156 OpBranch %23
2157 %24 = OpLabel
2158 %s5 = OpExtInst %void %ext DebugScope %dbg_main
2159 %37 = OpLoad %float %f
2160 OpStore %fo %37
2161 OpReturn
2162 OpFunctionEnd
2163 )";
2164 
2165   SinglePassRunAndMatch<SSARewritePass>(text, true);
2166 }
2167 
TEST_F(LocalSSAElimTest,ShaderDebugForLoop)2168 TEST_F(LocalSSAElimTest, ShaderDebugForLoop) {
2169   const std::string text = R"(
2170 ; CHECK: [[f_name:%\w+]] = OpString "f"
2171 ; CHECK: [[i_name:%\w+]] = OpString "i"
2172 ; CHECK: [[dbg_f:%\w+]] = OpExtInst %void [[ext:%\d+]] DebugLocalVariable [[f_name]]
2173 ; CHECK: [[dbg_i:%\w+]] = OpExtInst %void [[ext]] DebugLocalVariable [[i_name]]
2174 
2175 ; CHECK:      OpStore %f %float_0
2176 ; CHECK-NEXT: OpExtInst %void [[ext]] DebugValue [[dbg_f]] %float_0
2177 ; CHECK-NEXT: OpStore %i %int_0
2178 ; CHECK-NEXT: OpExtInst %void [[ext]] DebugValue [[dbg_i]] %int_0
2179 
2180 ; CHECK-NOT:  DebugDeclare
2181 
2182 ; CHECK:      [[loop_head:%\w+]] = OpLabel
2183 ; CHECK:      [[phi0:%\w+]] = OpPhi %float %float_0
2184 ; CHECK:      [[phi1:%\w+]] = OpPhi %int %int_0
2185 ; CHECK-NEXT: OpExtInst %void [[ext]] DebugValue [[dbg_f]] [[phi0]]
2186 ; CHECK-NEXT: OpExtInst %void [[ext]] DebugValue [[dbg_i]] [[phi1]]
2187 ; CHECK:      OpLoopMerge [[loop_merge:%\w+]] [[loop_cont:%\w+]] None
2188 ; CHECK-NEXT: OpBranch [[loop_body:%\w+]]
2189 
2190 ; CHECK-NEXT: [[loop_body]] = OpLabel
2191 ; CHECK:      OpBranchConditional {{%\w+}} [[bb:%\w+]] [[loop_merge]]
2192 
2193 ; CHECK:      [[bb]] = OpLabel
2194 ; CHECK:      OpStore %f [[f_val:%\w+]]
2195 ; CHECK-NEXT: OpExtInst %void [[ext]] DebugValue [[dbg_f]] [[f_val]]
2196 ; CHECK-NEXT: OpBranch [[loop_cont]]
2197 
2198 ; CHECK:      [[loop_cont]] = OpLabel
2199 ; CHECK:      OpStore %i [[i_val:%\w+]]
2200 ; CHECK-NEXT: OpExtInst %void [[ext]] DebugValue [[dbg_i]] [[i_val]]
2201 ; CHECK-NEXT: OpBranch [[loop_head]]
2202 
2203 ; CHECK:      [[loop_merge]] = OpLabel
2204 
2205 OpCapability Shader
2206 OpExtension "SPV_KHR_non_semantic_info"
2207 %1 = OpExtInstImport "GLSL.std.450"
2208 %ext = OpExtInstImport "NonSemantic.Shader.DebugInfo.100"
2209 OpMemoryModel Logical GLSL450
2210 OpEntryPoint Fragment %main "main" %BC %fo
2211 OpExecutionMode %main OriginUpperLeft
2212 %file_name = OpString "test"
2213 OpSource GLSL 140
2214 %float_name = OpString "float"
2215 %main_name = OpString "main"
2216 %f_name = OpString "f"
2217 %i_name = OpString "i"
2218 OpName %main "main"
2219 OpName %f "f"
2220 OpName %i "i"
2221 OpName %BC "BC"
2222 OpName %fo "fo"
2223 %void = OpTypeVoid
2224 %8 = OpTypeFunction %void
2225 %float = OpTypeFloat 32
2226 %_ptr_Function_float = OpTypePointer Function %float
2227 %float_0 = OpConstant %float 0
2228 %int = OpTypeInt 32 1
2229 %uint = OpTypeInt 32 0
2230 %uint_0 = OpConstant %uint 0
2231 %uint_1 = OpConstant %uint 1
2232 %uint_3 = OpConstant %uint 3
2233 %uint_4 = OpConstant %uint 4
2234 %uint_5 = OpConstant %uint 5
2235 %uint_10 = OpConstant %uint 10
2236 %uint_32 = OpConstant %uint 32
2237 %_ptr_Function_int = OpTypePointer Function %int
2238 %int_0 = OpConstant %int 0
2239 %int_4 = OpConstant %int 4
2240 %bool = OpTypeBool
2241 %v4float = OpTypeVector %float 4
2242 %_ptr_Input_v4float = OpTypePointer Input %v4float
2243 %BC = OpVariable %_ptr_Input_v4float Input
2244 %_ptr_Input_float = OpTypePointer Input %float
2245 %int_1 = OpConstant %int 1
2246 %_ptr_Output_float = OpTypePointer Output %float
2247 %fo = OpVariable %_ptr_Output_float Output
2248 %null_expr = OpExtInst %void %ext DebugExpression
2249 %src = OpExtInst %void %ext DebugSource %file_name
2250 %cu = OpExtInst %void %ext DebugCompilationUnit %uint_1 %uint_4 %src %uint_5
2251 %dbg_tf = OpExtInst %void %ext DebugTypeBasic %float_name %uint_32 %uint_3 %uint_0
2252 %dbg_v4f = OpExtInst %void %ext DebugTypeVector %dbg_tf %uint_4
2253 %main_ty = OpExtInst %void %ext DebugTypeFunction %uint_3 %dbg_v4f %dbg_v4f
2254 %dbg_main = OpExtInst %void %ext DebugFunction %main_name %main_ty %src %uint_0 %uint_0 %cu %main_name %uint_3 %uint_10
2255 %dbg_f = OpExtInst %void %ext DebugLocalVariable %f_name %dbg_v4f %src %uint_0 %uint_0 %dbg_main %uint_4
2256 %dbg_i = OpExtInst %void %ext DebugLocalVariable %i_name %dbg_v4f %src %uint_0 %uint_0 %dbg_main %uint_4
2257 %main = OpFunction %void None %8
2258 %22 = OpLabel
2259 %s0 = OpExtInst %void %ext DebugScope %dbg_main
2260 %f = OpVariable %_ptr_Function_float Function
2261 %i = OpVariable %_ptr_Function_int Function
2262 OpStore %f %float_0
2263 OpStore %i %int_0
2264 %decl0 = OpExtInst %void %ext DebugDeclare %dbg_f %f %null_expr
2265 %decl1 = OpExtInst %void %ext DebugDeclare %dbg_i %i %null_expr
2266 OpBranch %23
2267 %23 = OpLabel
2268 %s1 = OpExtInst %void %ext DebugScope %dbg_main
2269 OpLoopMerge %24 %25 None
2270 OpBranch %26
2271 %26 = OpLabel
2272 %s2 = OpExtInst %void %ext DebugScope %dbg_main
2273 %27 = OpLoad %int %i
2274 %28 = OpSLessThan %bool %27 %int_4
2275 OpBranchConditional %28 %29 %24
2276 %29 = OpLabel
2277 %s3 = OpExtInst %void %ext DebugScope %dbg_main
2278 %30 = OpLoad %float %f
2279 %31 = OpLoad %int %i
2280 %32 = OpAccessChain %_ptr_Input_float %BC %31
2281 %33 = OpLoad %float %32
2282 %34 = OpFAdd %float %30 %33
2283 OpStore %f %34
2284 OpBranch %25
2285 %25 = OpLabel
2286 %s4 = OpExtInst %void %ext DebugScope %dbg_main
2287 %35 = OpLoad %int %i
2288 %36 = OpIAdd %int %35 %int_1
2289 OpStore %i %36
2290 OpBranch %23
2291 %24 = OpLabel
2292 %s5 = OpExtInst %void %ext DebugScope %dbg_main
2293 %37 = OpLoad %float %f
2294 OpStore %fo %37
2295 OpReturn
2296 OpFunctionEnd
2297 )";
2298 
2299   SinglePassRunAndMatch<SSARewritePass>(text, true);
2300 }
2301 
TEST_F(LocalSSAElimTest,AddDebugValueForFunctionParameterWithPhi)2302 TEST_F(LocalSSAElimTest, AddDebugValueForFunctionParameterWithPhi) {
2303   // Test the distribution of DebugValue for a parameter of an inlined function
2304   // and the visibility of Phi instruction. The ssa-rewrite pass must add
2305   // DebugValue for the value assignment of function argument even when it is an
2306   // inlined function. It has to check the visibility Phi through all its value
2307   // operands. See the DebugValue for "int i" of "foo()" in the following code.
2308   //
2309   // struct VS_OUTPUT {
2310   //   float4 pos : SV_POSITION;
2311   //   float4 color : COLOR;
2312   // };
2313   //
2314   // float4 foo(int i, float4 pos) {
2315   //   while (i < pos.x) {
2316   //     pos = pos.x + i;
2317   //     ++i;
2318   //   }
2319   //   return pos;
2320   // }
2321   //
2322   // VS_OUTPUT main(float4 pos : POSITION,
2323   //                float4 color : COLOR) {
2324   //   VS_OUTPUT vout;
2325   //   vout.pos = foo(4, pos);
2326   //   vout.color = color;
2327   //   return vout;
2328   // }
2329   const std::string text = R"(
2330                OpCapability Shader
2331           %1 = OpExtInstImport "OpenCL.DebugInfo.100"
2332                OpMemoryModel Logical GLSL450
2333                OpEntryPoint Vertex %main "main" %in_var_POSITION %in_var_COLOR %gl_Position %out_var_COLOR
2334           %7 = OpString "vertex.hlsl"
2335           %8 = OpString "float"
2336           %9 = OpString "VS_OUTPUT"
2337          %10 = OpString "color"
2338          %11 = OpString "pos"
2339          %12 = OpString "int"
2340          %13 = OpString "foo"
2341          %14 = OpString ""
2342          %15 = OpString "i"
2343          %16 = OpString "main"
2344          %17 = OpString "vout"
2345                OpName %in_var_POSITION "in.var.POSITION"
2346                OpName %in_var_COLOR "in.var.COLOR"
2347                OpName %out_var_COLOR "out.var.COLOR"
2348                OpName %main "main"
2349                OpName %param_var_pos "param.var.pos"
2350                OpName %param_var_color "param.var.color"
2351                OpName %VS_OUTPUT "VS_OUTPUT"
2352                OpMemberName %VS_OUTPUT 0 "pos"
2353                OpMemberName %VS_OUTPUT 1 "color"
2354                OpDecorate %gl_Position BuiltIn Position
2355                OpDecorate %in_var_POSITION Location 0
2356                OpDecorate %in_var_COLOR Location 1
2357                OpDecorate %out_var_COLOR Location 0
2358         %int = OpTypeInt 32 1
2359       %int_4 = OpConstant %int 4
2360       %int_0 = OpConstant %int 0
2361       %int_1 = OpConstant %int 1
2362        %uint = OpTypeInt 32 0
2363     %uint_32 = OpConstant %uint 32
2364       %float = OpTypeFloat 32
2365     %v4float = OpTypeVector %float 4
2366 %_ptr_Input_v4float = OpTypePointer Input %v4float
2367 %_ptr_Output_v4float = OpTypePointer Output %v4float
2368        %void = OpTypeVoid
2369    %uint_256 = OpConstant %uint 256
2370    %uint_128 = OpConstant %uint 128
2371      %uint_0 = OpConstant %uint 0
2372          %50 = OpTypeFunction %void
2373 %_ptr_Function_v4float = OpTypePointer Function %v4float
2374   %VS_OUTPUT = OpTypeStruct %v4float %v4float
2375 %_ptr_Function_int = OpTypePointer Function %int
2376 %_ptr_Function_float = OpTypePointer Function %float
2377        %bool = OpTypeBool
2378 %in_var_POSITION = OpVariable %_ptr_Input_v4float Input
2379 %in_var_COLOR = OpVariable %_ptr_Input_v4float Input
2380 %gl_Position = OpVariable %_ptr_Output_v4float Output
2381 %out_var_COLOR = OpVariable %_ptr_Output_v4float Output
2382         %156 = OpExtInst %void %1 DebugInfoNone
2383          %77 = OpExtInst %void %1 DebugExpression
2384          %58 = OpExtInst %void %1 DebugTypeBasic %8 %uint_32 Float
2385          %59 = OpExtInst %void %1 DebugTypeVector %58 4
2386          %60 = OpExtInst %void %1 DebugSource %7
2387          %61 = OpExtInst %void %1 DebugCompilationUnit 1 4 %60 HLSL
2388          %62 = OpExtInst %void %1 DebugTypeComposite %9 Structure %60 1 8 %61 %9 %uint_256 FlagIsProtected|FlagIsPrivate %63 %64
2389          %64 = OpExtInst %void %1 DebugTypeMember %10 %59 %60 3 10 %62 %uint_128 %uint_128 FlagIsProtected|FlagIsPrivate
2390          %63 = OpExtInst %void %1 DebugTypeMember %11 %59 %60 2 10 %62 %uint_0 %uint_128 FlagIsProtected|FlagIsPrivate
2391          %65 = OpExtInst %void %1 DebugTypeBasic %12 %uint_32 Signed
2392          %66 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %59 %65 %59
2393          %67 = OpExtInst %void %1 DebugFunction %13 %66 %60 6 1 %61 %14 FlagIsProtected|FlagIsPrivate 6 %156
2394          %68 = OpExtInst %void %1 DebugLexicalBlock %60 6 31 %67
2395          %69 = OpExtInst %void %1 DebugLexicalBlock %60 7 21 %68
2396          %70 = OpExtInst %void %1 DebugLocalVariable %11 %59 %60 6 26 %67 FlagIsLocal 2
2397 
2398 ; CHECK: [[color_name:%\w+]] = OpString "color"
2399 ; CHECK: [[pos_name:%\w+]] = OpString "pos"
2400 ; CHECK: [[i_name:%\w+]] = OpString "i"
2401 ; CHECK: [[null_expr:%\w+]] = OpExtInst %void [[ext:%\w+]] DebugExpression
2402 ; CHECK: [[dbg_i:%\w+]] = OpExtInst %void [[ext]] DebugLocalVariable [[i_name]] {{%\w+}} {{%\w+}} 6 16 {{%\w+}} FlagIsLocal 1
2403 ; CHECK: [[dbg_color:%\w+]] = OpExtInst %void [[ext]] DebugLocalVariable [[color_name]] {{%\w+}} {{%\w+}} 15 23
2404 ; CHECK: [[dbg_pos:%\w+]] = OpExtInst %void [[ext]] DebugLocalVariable [[pos_name]] {{%\w+}} {{%\w+}} 14 23
2405          %71 = OpExtInst %void %1 DebugLocalVariable %15 %65 %60 6 16 %67 FlagIsLocal 1
2406          %72 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %62 %59 %59
2407          %73 = OpExtInst %void %1 DebugFunction %16 %72 %60 14 1 %61 %14 FlagIsProtected|FlagIsPrivate 15 %156
2408          %74 = OpExtInst %void %1 DebugLexicalBlock %60 15 38 %73
2409          %75 = OpExtInst %void %1 DebugLocalVariable %17 %62 %60 16 13 %74 FlagIsLocal
2410          %76 = OpExtInst %void %1 DebugLocalVariable %10 %59 %60 15 23 %73 FlagIsLocal 2
2411          %78 = OpExtInst %void %1 DebugLocalVariable %11 %59 %60 14 23 %73 FlagIsLocal 1
2412         %155 = OpExtInst %void %1 DebugInlinedAt 17 %74
2413        %main = OpFunction %void None %50
2414          %79 = OpLabel
2415         %168 = OpExtInst %void %1 DebugScope %74
2416 
2417 ; CHECK: [[i:%\w+]] = OpVariable %_ptr_Function_int Function
2418         %120 = OpVariable %_ptr_Function_int Function
2419         %121 = OpVariable %_ptr_Function_v4float Function
2420         %169 = OpExtInst %void %1 DebugNoScope
2421 %param_var_pos = OpVariable %_ptr_Function_v4float Function
2422 %param_var_color = OpVariable %_ptr_Function_v4float Function
2423                OpLine %7 100 105
2424          %80 = OpLoad %v4float %in_var_POSITION
2425                OpStore %param_var_pos %80
2426                OpNoLine
2427                OpLine %7 200 205
2428          %81 = OpLoad %v4float %in_var_COLOR
2429                OpStore %param_var_color %81
2430                OpNoLine
2431         %170 = OpExtInst %void %1 DebugScope %73
2432 
2433 ; CHECK: OpLine {{%\w+}} 100 105
2434 ; CHECK: DebugValue [[dbg_pos]]
2435         %124 = OpExtInst %void %1 DebugDeclare %78 %param_var_pos %77
2436 ; CHECK: OpLine {{%\w+}} 200 205
2437 ; CHECK: DebugValue [[dbg_color]]
2438         %125 = OpExtInst %void %1 DebugDeclare %76 %param_var_color %77
2439 
2440         %171 = OpExtInst %void %1 DebugScope %74
2441                OpLine %7 17 18
2442 
2443 ; CHECK: OpStore {{%\w+}} %int_4
2444 ; CHECK: DebugValue [[dbg_i]] %int_4 [[null_expr]]
2445                OpStore %120 %int_4
2446                OpStore %121 %80
2447         %172 = OpExtInst %void %1 DebugScope %67 %155
2448         %135 = OpExtInst %void %1 DebugDeclare %71 %120 %77
2449         %136 = OpExtInst %void %1 DebugDeclare %70 %121 %77
2450         %173 = OpExtInst %void %1 DebugScope %68 %155
2451                OpLine %7 7 3
2452                OpBranch %137
2453         %174 = OpExtInst %void %1 DebugNoScope
2454         %137 = OpLabel
2455 
2456 ; CHECK: [[phi:%\w+]] = OpPhi %int %int_4
2457 ; CHECK: DebugValue [[dbg_i]] [[phi]] [[null_expr]]
2458         %175 = OpExtInst %void %1 DebugScope %68 %155
2459                OpLine %7 7 10
2460         %138 = OpLoad %int %120
2461         %139 = OpConvertSToF %float %138
2462                OpLine %7 7 14
2463         %140 = OpAccessChain %_ptr_Function_float %121 %int_0
2464         %141 = OpLoad %float %140
2465                OpLine %7 7 12
2466         %142 = OpFOrdLessThan %bool %139 %141
2467                OpLine %7 7 3
2468         %176 = OpExtInst %void %1 DebugNoScope
2469                OpLoopMerge %153 %152 None
2470                OpBranchConditional %142 %143 %153
2471         %177 = OpExtInst %void %1 DebugNoScope
2472         %143 = OpLabel
2473         %178 = OpExtInst %void %1 DebugScope %69 %155
2474                OpLine %7 8 11
2475         %144 = OpAccessChain %_ptr_Function_float %121 %int_0
2476         %145 = OpLoad %float %144
2477                OpLine %7 8 19
2478         %146 = OpLoad %int %120
2479         %147 = OpConvertSToF %float %146
2480                OpLine %7 8 17
2481         %148 = OpFAdd %float %145 %147
2482                OpLine %7 8 11
2483         %149 = OpCompositeConstruct %v4float %148 %148 %148 %148
2484                OpLine %7 8 5
2485                OpStore %121 %149
2486                OpLine %7 9 5
2487         %151 = OpIAdd %int %146 %int_1
2488                OpLine %7 9 7
2489 
2490 ; CHECK: OpStore [[i]] [[value:%\w+]]
2491 ; CHECK: DebugValue [[dbg_i]] [[value]] [[null_expr]]
2492                OpStore %120 %151
2493         %179 = OpExtInst %void %1 DebugScope %68 %155
2494                OpLine %7 10 3
2495                OpBranch %152
2496         %180 = OpExtInst %void %1 DebugNoScope
2497         %152 = OpLabel
2498         %181 = OpExtInst %void %1 DebugScope %68 %155
2499                OpBranch %137
2500         %182 = OpExtInst %void %1 DebugNoScope
2501         %153 = OpLabel
2502         %183 = OpExtInst %void %1 DebugScope %68 %155
2503                OpLine %7 11 10
2504         %154 = OpLoad %v4float %121
2505         %184 = OpExtInst %void %1 DebugScope %74
2506         %167 = OpExtInst %void %1 DebugValue %75 %154 %77 %int_0
2507         %166 = OpExtInst %void %1 DebugValue %75 %81 %77 %int_1
2508                OpLine %7 19 10
2509         %165 = OpCompositeConstruct %VS_OUTPUT %154 %81
2510         %185 = OpExtInst %void %1 DebugNoScope
2511          %83 = OpCompositeExtract %v4float %165 0
2512                OpStore %gl_Position %83
2513          %84 = OpCompositeExtract %v4float %165 1
2514                OpStore %out_var_COLOR %84
2515                OpReturn
2516                OpFunctionEnd
2517 )";
2518 
2519   SinglePassRunAndMatch<SSARewritePass>(text, true);
2520 }
2521 
TEST_F(LocalSSAElimTest,DebugValueWithIndexesInForLoop)2522 TEST_F(LocalSSAElimTest, DebugValueWithIndexesInForLoop) {
2523   // #version 140
2524   //
2525   // in vec4 BC;
2526   // out float fo;
2527   //
2528   // struct T {
2529   //   float a;
2530   //   float f;
2531   // };
2532   //
2533   // struct value {
2534   //   int x;
2535   //   int y;
2536   //   T z;
2537   // };
2538   //
2539   // void main()
2540   // {
2541   //     value v;
2542   //     v.z.f = 0.0;
2543   //     for (int i=0; i<4; i++) {
2544   //       v.z.f = v.z.f + BC[i];
2545   //     }
2546   //     fo = v.z.f;
2547   // }
2548 
2549   const std::string text = R"(
2550 ; CHECK: [[f_name:%\w+]] = OpString "f"
2551 ; CHECK: [[dbg_f:%\w+]] = OpExtInst %void [[ext:%\d+]] DebugLocalVariable [[f_name]]
2552 
2553 ; CHECK:      OpStore %f %float_0
2554 ; CHECK-NEXT: OpExtInst %void [[ext]] DebugValue [[dbg_f]] %float_0 [[null_expr:%\d+]] %int_2 %int_1
2555 
2556 ; CHECK-NOT:  DebugDeclare
2557 
2558 ; CHECK:      [[loop_head:%\w+]] = OpLabel
2559 ; CHECK:      [[phi0:%\w+]] = OpPhi %float %float_0
2560 ; CHECK:      OpExtInst %void [[ext]] DebugValue [[dbg_f]] [[phi0]] [[null_expr]] %int_2 %int_1
2561 ; CHECK:      OpLoopMerge [[loop_merge:%\w+]] [[loop_cont:%\w+]] None
2562 ; CHECK-NEXT: OpBranch [[loop_body:%\w+]]
2563 
2564 ; CHECK-NEXT: [[loop_body]] = OpLabel
2565 ; CHECK:      OpBranchConditional {{%\w+}} [[bb:%\w+]] [[loop_merge]]
2566 
2567 ; CHECK:      [[bb]] = OpLabel
2568 ; CHECK:      OpStore %f [[f_val:%\w+]]
2569 ; CHECK-NEXT: OpExtInst %void [[ext]] DebugValue [[dbg_f]] [[f_val]] [[null_expr]] %int_2 %int_1
2570 ; CHECK-NEXT: OpBranch [[loop_cont]]
2571 
2572 ; CHECK: [[loop_cont]] = OpLabel
2573 ; CHECK: OpBranch [[loop_head]]
2574 
2575 ; CHECK: [[loop_merge]] = OpLabel
2576 
2577 OpCapability Shader
2578 %1 = OpExtInstImport "GLSL.std.450"
2579 %ext = OpExtInstImport "OpenCL.DebugInfo.100"
2580 OpMemoryModel Logical GLSL450
2581 OpEntryPoint Fragment %main "main" %BC %fo
2582 OpExecutionMode %main OriginUpperLeft
2583 %file_name = OpString "test"
2584 OpSource GLSL 140
2585 %float_name = OpString "float"
2586 %main_name = OpString "main"
2587 %f_name = OpString "f"
2588 %i_name = OpString "i"
2589 OpName %main "main"
2590 OpName %f "f"
2591 OpName %i "i"
2592 OpName %BC "BC"
2593 OpName %fo "fo"
2594 %void = OpTypeVoid
2595 %8 = OpTypeFunction %void
2596 %float = OpTypeFloat 32
2597 %_ptr_Function_float = OpTypePointer Function %float
2598 %float_0 = OpConstant %float 0
2599 %int = OpTypeInt 32 1
2600 %uint = OpTypeInt 32 0
2601 %uint_32 = OpConstant %uint 32
2602 %_ptr_Function_int = OpTypePointer Function %int
2603 %int_0 = OpConstant %int 0
2604 %int_4 = OpConstant %int 4
2605 %bool = OpTypeBool
2606 %v4float = OpTypeVector %float 4
2607 %_ptr_Input_v4float = OpTypePointer Input %v4float
2608 %BC = OpVariable %_ptr_Input_v4float Input
2609 %_ptr_Input_float = OpTypePointer Input %float
2610 %int_1 = OpConstant %int 1
2611 %int_2 = OpConstant %int 2
2612 %_ptr_Output_float = OpTypePointer Output %float
2613 %fo = OpVariable %_ptr_Output_float Output
2614 %deref = OpExtInst %void %ext DebugOperation Deref
2615 %null_expr = OpExtInst %void %ext DebugExpression
2616 %deref_expr = OpExtInst %void %ext DebugExpression %deref
2617 %src = OpExtInst %void %ext DebugSource %file_name
2618 %cu = OpExtInst %void %ext DebugCompilationUnit 1 4 %src HLSL
2619 %dbg_tf = OpExtInst %void %ext DebugTypeBasic %float_name %uint_32 Float
2620 %dbg_v4f = OpExtInst %void %ext DebugTypeVector %dbg_tf 4
2621 %main_ty = OpExtInst %void %ext DebugTypeFunction FlagIsProtected|FlagIsPrivate %dbg_v4f %dbg_v4f
2622 %dbg_main = OpExtInst %void %ext DebugFunction %main_name %main_ty %src 0 0 %cu %main_name FlagIsProtected|FlagIsPrivate 10 %main
2623 %dbg_f = OpExtInst %void %ext DebugLocalVariable %f_name %dbg_v4f %src 0 0 %dbg_main FlagIsLocal
2624 %dbg_i = OpExtInst %void %ext DebugLocalVariable %i_name %dbg_v4f %src 0 0 %dbg_main FlagIsLocal
2625 %main = OpFunction %void None %8
2626 %22 = OpLabel
2627 %s0 = OpExtInst %void %ext DebugScope %dbg_main
2628 %f = OpVariable %_ptr_Function_float Function
2629 %i = OpVariable %_ptr_Function_int Function
2630 OpStore %f %float_0
2631 OpStore %i %int_0
2632 %decl0 = OpExtInst %void %ext DebugValue %dbg_f %f %deref_expr %int_2 %int_1
2633 %decl1 = OpExtInst %void %ext DebugDeclare %dbg_i %i %null_expr
2634 OpBranch %23
2635 %23 = OpLabel
2636 %s1 = OpExtInst %void %ext DebugScope %dbg_main
2637 OpLoopMerge %24 %25 None
2638 OpBranch %26
2639 %26 = OpLabel
2640 %s2 = OpExtInst %void %ext DebugScope %dbg_main
2641 %27 = OpLoad %int %i
2642 %28 = OpSLessThan %bool %27 %int_4
2643 OpBranchConditional %28 %29 %24
2644 %29 = OpLabel
2645 %s3 = OpExtInst %void %ext DebugScope %dbg_main
2646 %30 = OpLoad %float %f
2647 %31 = OpLoad %int %i
2648 %32 = OpAccessChain %_ptr_Input_float %BC %31
2649 %33 = OpLoad %float %32
2650 %34 = OpFAdd %float %30 %33
2651 OpStore %f %34
2652 OpBranch %25
2653 %25 = OpLabel
2654 %s4 = OpExtInst %void %ext DebugScope %dbg_main
2655 %35 = OpLoad %int %i
2656 %36 = OpIAdd %int %35 %int_1
2657 OpStore %i %36
2658 OpBranch %23
2659 %24 = OpLabel
2660 %s5 = OpExtInst %void %ext DebugScope %dbg_main
2661 %37 = OpLoad %float %f
2662 OpStore %fo %37
2663 OpReturn
2664 OpFunctionEnd
2665 )";
2666 
2667   SinglePassRunAndMatch<SSARewritePass>(text, true);
2668 }
2669 
TEST_F(LocalSSAElimTest,PartiallyKillDebugDeclare)2670 TEST_F(LocalSSAElimTest, PartiallyKillDebugDeclare) {
2671   // For a reference variable e.g., int i in the following example,
2672   // we do not propagate DebugValue for a store or phi instruction
2673   // out of the variable's scope. In that case, we should not remove
2674   // DebugDeclare for the variable that we did not add its DebugValue.
2675   //
2676   // #version 140
2677   //
2678   // in vec4 BC;
2679   // out float fo;
2680   //
2681   // int j;
2682   // void main()
2683   // {
2684   //     float f = 0.0;
2685   //     for (j=0; j<4; j++) {
2686   //       int& i = j;
2687   //       f = f + BC[i];
2688   //     }
2689   //     fo = f;
2690   // }
2691 
2692   const std::string text = R"(
2693 ; CHECK: [[f_name:%\w+]] = OpString "f"
2694 ; CHECK: [[i_name:%\w+]] = OpString "i"
2695 ; CHECK: [[fn:%\w+]] = OpExtInst %void [[ext:%\d+]] DebugFunction
2696 ; CHECK: [[bb:%\w+]] = OpExtInst %void [[ext]] DebugLexicalBlock
2697 ; CHECK: [[dbg_f:%\w+]] = OpExtInst %void [[ext]] DebugLocalVariable [[f_name]] {{%\w+}} {{%\w+}} 0 0 [[fn]]
2698 ; CHECK: [[dbg_i:%\w+]] = OpExtInst %void [[ext]] DebugLocalVariable [[i_name]] {{%\w+}} {{%\w+}} 0 0 [[bb]]
2699 
2700 ; CHECK:      OpStore %f %float_0
2701 ; CHECK-NEXT: OpExtInst %void [[ext]] DebugValue [[dbg_f]] %float_0
2702 ; CHECK-NOT:  DebugDeclare [[dbg_f]]
2703 ; CHECK:      OpExtInst %void [[ext]] DebugDeclare [[dbg_i]] %j
2704 
2705 OpCapability Shader
2706 %1 = OpExtInstImport "GLSL.std.450"
2707 %ext = OpExtInstImport "OpenCL.DebugInfo.100"
2708 OpMemoryModel Logical GLSL450
2709 OpEntryPoint Fragment %main "main" %BC %fo
2710 OpExecutionMode %main OriginUpperLeft
2711 %file_name = OpString "test"
2712 OpSource GLSL 140
2713 %float_name = OpString "float"
2714 %main_name = OpString "main"
2715 %f_name = OpString "f"
2716 %i_name = OpString "i"
2717 %j_name = OpString "j"
2718 OpName %main "main"
2719 OpName %f "f"
2720 OpName %j "j"
2721 OpName %BC "BC"
2722 OpName %fo "fo"
2723 %void = OpTypeVoid
2724 %8 = OpTypeFunction %void
2725 %float = OpTypeFloat 32
2726 %_ptr_Function_float = OpTypePointer Function %float
2727 %float_0 = OpConstant %float 0
2728 %int = OpTypeInt 32 1
2729 %uint = OpTypeInt 32 0
2730 %uint_32 = OpConstant %uint 32
2731 %_ptr_Function_int = OpTypePointer Function %int
2732 %_ptr_Private_int = OpTypePointer Private %int
2733 %int_0 = OpConstant %int 0
2734 %int_4 = OpConstant %int 4
2735 %bool = OpTypeBool
2736 %v4float = OpTypeVector %float 4
2737 %_ptr_Input_v4float = OpTypePointer Input %v4float
2738 %BC = OpVariable %_ptr_Input_v4float Input
2739 %_ptr_Input_float = OpTypePointer Input %float
2740 %int_1 = OpConstant %int 1
2741 %_ptr_Output_float = OpTypePointer Output %float
2742 %fo = OpVariable %_ptr_Output_float Output
2743 %j = OpVariable %_ptr_Private_int Private
2744 %null_expr = OpExtInst %void %ext DebugExpression
2745 %src = OpExtInst %void %ext DebugSource %file_name
2746 %cu = OpExtInst %void %ext DebugCompilationUnit 1 4 %src HLSL
2747 %dbg_tf = OpExtInst %void %ext DebugTypeBasic %float_name %uint_32 Float
2748 %dbg_v4f = OpExtInst %void %ext DebugTypeVector %dbg_tf 4
2749 %main_ty = OpExtInst %void %ext DebugTypeFunction FlagIsProtected|FlagIsPrivate %dbg_v4f %dbg_v4f
2750 %dbg_main = OpExtInst %void %ext DebugFunction %main_name %main_ty %src 0 0 %cu %main_name FlagIsProtected|FlagIsPrivate 10 %main
2751 %bb = OpExtInst %void %ext DebugLexicalBlock %src 0 0 %dbg_main
2752 %dbg_f = OpExtInst %void %ext DebugLocalVariable %f_name %dbg_v4f %src 0 0 %dbg_main FlagIsLocal
2753 %dbg_i = OpExtInst %void %ext DebugLocalVariable %i_name %dbg_v4f %src 0 0 %bb FlagIsLocal
2754 %dbg_j = OpExtInst %void %ext DebugGlobalVariable %j_name %dbg_v4f %src 0 0 %dbg_main %j_name %j FlagIsPrivate
2755 %main = OpFunction %void None %8
2756 %22 = OpLabel
2757 %s0 = OpExtInst %void %ext DebugScope %dbg_main
2758 %f = OpVariable %_ptr_Function_float Function
2759 OpStore %f %float_0
2760 OpStore %j %int_0
2761 %decl0 = OpExtInst %void %ext DebugDeclare %dbg_f %f %null_expr
2762 OpBranch %23
2763 %23 = OpLabel
2764 %s1 = OpExtInst %void %ext DebugScope %dbg_main
2765 OpLoopMerge %24 %25 None
2766 OpBranch %26
2767 %26 = OpLabel
2768 %s2 = OpExtInst %void %ext DebugScope %dbg_main
2769 %27 = OpLoad %int %j
2770 %28 = OpSLessThan %bool %27 %int_4
2771 OpBranchConditional %28 %29 %24
2772 %29 = OpLabel
2773 %s3 = OpExtInst %void %ext DebugScope %bb
2774 %decl1 = OpExtInst %void %ext DebugDeclare %dbg_i %j %null_expr
2775 %30 = OpLoad %float %f
2776 %31 = OpLoad %int %j
2777 %32 = OpAccessChain %_ptr_Input_float %BC %31
2778 %33 = OpLoad %float %32
2779 %34 = OpFAdd %float %30 %33
2780 OpStore %f %34
2781 OpBranch %25
2782 %25 = OpLabel
2783 %s4 = OpExtInst %void %ext DebugScope %dbg_main
2784 %35 = OpLoad %int %j
2785 %36 = OpIAdd %int %35 %int_1
2786 OpStore %j %36
2787 OpBranch %23
2788 %24 = OpLabel
2789 %s5 = OpExtInst %void %ext DebugScope %dbg_main
2790 %37 = OpLoad %float %f
2791 OpStore %fo %37
2792 OpReturn
2793 OpFunctionEnd
2794 )";
2795 
2796   SinglePassRunAndMatch<SSARewritePass>(text, true);
2797 }
2798 
TEST_F(LocalSSAElimTest,DebugValueForReferenceVariable)2799 TEST_F(LocalSSAElimTest, DebugValueForReferenceVariable) {
2800   // #version 140
2801   //
2802   // in vec4 BC;
2803   // out float fo;
2804   //
2805   // void main()
2806   // {
2807   //     float f = 0.0;
2808   //     float& x = f;
2809   //     for (int i=0; i<4; i++) {
2810   //       x = x + BC[i];
2811   //     }
2812   //     fo = f;
2813   // }
2814 
2815   const std::string text = R"(
2816 ; CHECK: [[f_name:%\w+]] = OpString "f"
2817 ; CHECK: [[i_name:%\w+]] = OpString "i"
2818 ; CHECK: [[x_name:%\w+]] = OpString "x"
2819 ; CHECK: [[dbg_f:%\w+]] = OpExtInst %void [[ext:%\d+]] DebugLocalVariable [[f_name]]
2820 ; CHECK: [[dbg_i:%\w+]] = OpExtInst %void [[ext]] DebugLocalVariable [[i_name]]
2821 ; CHECK: [[dbg_x:%\w+]] = OpExtInst %void [[ext]] DebugLocalVariable [[x_name]]
2822 
2823 ; CHECK:      OpStore %f %float_0
2824 ; CHECK-DAG:  OpExtInst %void [[ext]] DebugValue [[dbg_f]] %float_0
2825 ; CHECK-DAG:  OpExtInst %void [[ext]] DebugValue [[dbg_x]] %float_0
2826 ; CHECK:      OpStore %i %int_0
2827 ; CHECK-NEXT: OpExtInst %void [[ext]] DebugValue [[dbg_i]] %int_0
2828 
2829 ; CHECK-NOT:  DebugDeclare
2830 
2831 ; CHECK:      [[loop_head:%\w+]] = OpLabel
2832 ; CHECK:      [[phi0:%\w+]] = OpPhi %float %float_0
2833 ; CHECK:      [[phi1:%\w+]] = OpPhi %int %int_0
2834 ; CHECK-DAG:  OpExtInst %void [[ext]] DebugValue [[dbg_f]] [[phi0]]
2835 ; CHECK-DAG:  OpExtInst %void [[ext]] DebugValue [[dbg_x]] [[phi0]]
2836 ; CHECK:      OpExtInst %void [[ext]] DebugValue [[dbg_i]] [[phi1]]
2837 ; CHECK:      OpLoopMerge [[loop_merge:%\w+]] [[loop_cont:%\w+]] None
2838 ; CHECK-NEXT: OpBranch [[loop_body:%\w+]]
2839 
2840 ; CHECK:      [[loop_body]] = OpLabel
2841 ; CHECK:      OpBranchConditional {{%\w+}} [[bb:%\w+]] [[loop_merge]]
2842 
2843 ; CHECK:      [[bb]] = OpLabel
2844 ; CHECK:      OpStore %f [[f_val:%\w+]]
2845 ; CHECK-DAG:  OpExtInst %void [[ext]] DebugValue [[dbg_f]] [[f_val]]
2846 ; CHECK-DAG:  OpExtInst %void [[ext]] DebugValue [[dbg_x]] [[f_val]]
2847 ; CHECK:      OpBranch [[loop_cont]]
2848 
2849 ; CHECK:      [[loop_cont]] = OpLabel
2850 ; CHECK:      OpStore %i [[i_val:%\w+]]
2851 ; CHECK-NEXT: OpExtInst %void [[ext]] DebugValue [[dbg_i]] [[i_val]]
2852 ; CHECK-NEXT: OpBranch [[loop_head]]
2853 
2854 ; CHECK:      [[loop_merge]] = OpLabel
2855 
2856 OpCapability Shader
2857 %1 = OpExtInstImport "GLSL.std.450"
2858 %ext = OpExtInstImport "OpenCL.DebugInfo.100"
2859 OpMemoryModel Logical GLSL450
2860 OpEntryPoint Fragment %main "main" %BC %fo
2861 OpExecutionMode %main OriginUpperLeft
2862 %file_name = OpString "test"
2863 OpSource GLSL 140
2864 %float_name = OpString "float"
2865 %main_name = OpString "main"
2866 %f_name = OpString "f"
2867 %i_name = OpString "i"
2868 %x_name = OpString "x"
2869 OpName %main "main"
2870 OpName %f "f"
2871 OpName %i "i"
2872 OpName %BC "BC"
2873 OpName %fo "fo"
2874 %void = OpTypeVoid
2875 %8 = OpTypeFunction %void
2876 %float = OpTypeFloat 32
2877 %_ptr_Function_float = OpTypePointer Function %float
2878 %float_0 = OpConstant %float 0
2879 %int = OpTypeInt 32 1
2880 %uint = OpTypeInt 32 0
2881 %uint_32 = OpConstant %uint 32
2882 %_ptr_Function_int = OpTypePointer Function %int
2883 %int_0 = OpConstant %int 0
2884 %int_4 = OpConstant %int 4
2885 %bool = OpTypeBool
2886 %v4float = OpTypeVector %float 4
2887 %_ptr_Input_v4float = OpTypePointer Input %v4float
2888 %BC = OpVariable %_ptr_Input_v4float Input
2889 %_ptr_Input_float = OpTypePointer Input %float
2890 %int_1 = OpConstant %int 1
2891 %_ptr_Output_float = OpTypePointer Output %float
2892 %fo = OpVariable %_ptr_Output_float Output
2893 %null_expr = OpExtInst %void %ext DebugExpression
2894 %src = OpExtInst %void %ext DebugSource %file_name
2895 %cu = OpExtInst %void %ext DebugCompilationUnit 1 4 %src HLSL
2896 %dbg_tf = OpExtInst %void %ext DebugTypeBasic %float_name %uint_32 Float
2897 %dbg_v4f = OpExtInst %void %ext DebugTypeVector %dbg_tf 4
2898 %main_ty = OpExtInst %void %ext DebugTypeFunction FlagIsProtected|FlagIsPrivate %dbg_v4f %dbg_v4f
2899 %dbg_main = OpExtInst %void %ext DebugFunction %main_name %main_ty %src 0 0 %cu %main_name FlagIsProtected|FlagIsPrivate 10 %main
2900 %dbg_f = OpExtInst %void %ext DebugLocalVariable %f_name %dbg_v4f %src 0 0 %dbg_main FlagIsLocal
2901 %dbg_i = OpExtInst %void %ext DebugLocalVariable %i_name %dbg_v4f %src 1 0 %dbg_main FlagIsLocal
2902 %dbg_x = OpExtInst %void %ext DebugLocalVariable %x_name %dbg_v4f %src 2 0 %dbg_main FlagIsLocal
2903 %main = OpFunction %void None %8
2904 %22 = OpLabel
2905 %s0 = OpExtInst %void %ext DebugScope %dbg_main
2906 %f = OpVariable %_ptr_Function_float Function
2907 %i = OpVariable %_ptr_Function_int Function
2908 OpStore %f %float_0
2909 OpStore %i %int_0
2910 %decl0 = OpExtInst %void %ext DebugDeclare %dbg_f %f %null_expr
2911 %decl1 = OpExtInst %void %ext DebugDeclare %dbg_i %i %null_expr
2912 %decl2 = OpExtInst %void %ext DebugDeclare %dbg_x %f %null_expr
2913 OpBranch %23
2914 %23 = OpLabel
2915 %s1 = OpExtInst %void %ext DebugScope %dbg_main
2916 OpLoopMerge %24 %25 None
2917 OpBranch %26
2918 %26 = OpLabel
2919 %s2 = OpExtInst %void %ext DebugScope %dbg_main
2920 %27 = OpLoad %int %i
2921 %28 = OpSLessThan %bool %27 %int_4
2922 OpBranchConditional %28 %29 %24
2923 %29 = OpLabel
2924 %s3 = OpExtInst %void %ext DebugScope %dbg_main
2925 %30 = OpLoad %float %f
2926 %31 = OpLoad %int %i
2927 %32 = OpAccessChain %_ptr_Input_float %BC %31
2928 %33 = OpLoad %float %32
2929 %34 = OpFAdd %float %30 %33
2930 OpStore %f %34
2931 OpBranch %25
2932 %25 = OpLabel
2933 %s4 = OpExtInst %void %ext DebugScope %dbg_main
2934 %35 = OpLoad %int %i
2935 %36 = OpIAdd %int %35 %int_1
2936 OpStore %i %36
2937 OpBranch %23
2938 %24 = OpLabel
2939 %s5 = OpExtInst %void %ext DebugScope %dbg_main
2940 %37 = OpLoad %float %f
2941 OpStore %fo %37
2942 OpReturn
2943 OpFunctionEnd
2944 )";
2945 
2946   SinglePassRunAndMatch<SSARewritePass>(text, true);
2947 }
2948 
TEST_F(LocalSSAElimTest,DebugValueForReferenceVariableInBB)2949 TEST_F(LocalSSAElimTest, DebugValueForReferenceVariableInBB) {
2950   // #version 140
2951   //
2952   // in vec4 BC;
2953   // out float fo;
2954   //
2955   // void main()
2956   // {
2957   //     float f = 0.0;
2958   //     for (int i=0; i<4; i++) {
2959   //       float& x = f;
2960   //       x = x + BC[i];
2961   //       {
2962   //         x = x + BC[i];
2963   //       }
2964   //     }
2965   //     fo = f;
2966   // }
2967 
2968   const std::string text = R"(
2969 ; CHECK: [[f_name:%\w+]] = OpString "f"
2970 ; CHECK: [[i_name:%\w+]] = OpString "i"
2971 ; CHECK: [[x_name:%\w+]] = OpString "x"
2972 ; CHECK: [[dbg_main:%\w+]] = OpExtInst %void [[ext:%\d+]] DebugFunction
2973 ; CHECK: [[dbg_bb:%\w+]] = OpExtInst %void [[ext]] DebugLexicalBlock
2974 ; CHECK: [[dbg_bb_child:%\w+]] = OpExtInst %void [[ext]] DebugLexicalBlock
2975 ; CHECK: [[dbg_f:%\w+]] = OpExtInst %void [[ext]] DebugLocalVariable [[f_name]]
2976 ; CHECK: [[dbg_i:%\w+]] = OpExtInst %void [[ext]] DebugLocalVariable [[i_name]]
2977 ; CHECK: [[dbg_x:%\w+]] = OpExtInst %void [[ext]] DebugLocalVariable [[x_name]]
2978 
2979 ; CHECK:      OpExtInst %void [[ext]] DebugScope [[dbg_main]]
2980 ; CHECK:      OpStore %f %float_0
2981 ; CHECK-NEXT: OpExtInst %void [[ext]] DebugValue [[dbg_x]] %float_0
2982 ; CHECK-NEXT: OpExtInst %void [[ext]] DebugValue [[dbg_f]] %float_0
2983 ; CHECK-NEXT: OpStore %i %int_0
2984 ; CHECK-NEXT: OpExtInst %void [[ext]] DebugValue [[dbg_i]] %int_0
2985 
2986 ; CHECK-NOT:  DebugDeclare
2987 
2988 ; CHECK:      [[loop_head:%\w+]] = OpLabel
2989 ; CHECK:      OpExtInst %void [[ext]] DebugScope [[dbg_main]]
2990 ; CHECK:      [[phi0:%\w+]] = OpPhi %float %float_0
2991 ; CHECK:      [[phi1:%\w+]] = OpPhi %int %int_0
2992 ; CHECK-DAG: OpExtInst %void [[ext]] DebugValue [[dbg_f]] [[phi0]]
2993 ; CHECK-DAG: OpExtInst %void [[ext]] DebugValue [[dbg_x]] [[phi0]]
2994 ; CHECK-DAG: OpExtInst %void [[ext]] DebugValue [[dbg_i]] [[phi1]]
2995 ; CHECK:      OpLoopMerge [[loop_merge:%\w+]] [[loop_cont:%\w+]] None
2996 ; CHECK-NEXT: OpBranch [[loop_body:%\w+]]
2997 
2998 ; CHECK-NEXT: [[loop_body]] = OpLabel
2999 ; CHECK:      OpBranchConditional {{%\w+}} [[bb:%\w+]] [[loop_merge]]
3000 
3001 ; CHECK:      [[bb]] = OpLabel
3002 ; CHECK:      OpExtInst %void [[ext]] DebugScope [[dbg_bb]]
3003 ; CHECK:      OpStore %f [[f_val:%\w+]]
3004 ; CHECK-DAG:  OpExtInst %void [[ext]] DebugValue [[dbg_f]] [[f_val]]
3005 ; CHECK-DAG:  OpExtInst %void [[ext]] DebugValue [[dbg_x]] [[f_val]]
3006 ; CHECK:      OpBranch [[bb_child:%\w+]]
3007 
3008 ; CHECK:      [[bb_child]] = OpLabel
3009 ; CHECK:      OpExtInst %void [[ext]] DebugScope [[dbg_bb_child]]
3010 ; CHECK:      OpStore %f [[new_f_val:%\w+]]
3011 ; CHECK-DAG:  OpExtInst %void [[ext]] DebugValue [[dbg_f]] [[new_f_val]]
3012 ; CHECK-DAG:  OpExtInst %void [[ext]] DebugValue [[dbg_x]] [[new_f_val]]
3013 ; CHECK:      OpBranch [[loop_cont]]
3014 
3015 ; CHECK:      [[loop_cont]] = OpLabel
3016 ; CHECK:      OpStore %i [[i_val:%\w+]]
3017 ; CHECK-NEXT: OpExtInst %void [[ext]] DebugValue [[dbg_i]] [[i_val]]
3018 ; CHECK-NEXT: OpBranch [[loop_head]]
3019 
3020 ; CHECK:      [[loop_merge]] = OpLabel
3021 
3022 OpCapability Shader
3023 %1 = OpExtInstImport "GLSL.std.450"
3024 %ext = OpExtInstImport "OpenCL.DebugInfo.100"
3025 OpMemoryModel Logical GLSL450
3026 OpEntryPoint Fragment %main "main" %BC %fo
3027 OpExecutionMode %main OriginUpperLeft
3028 %file_name = OpString "test"
3029 OpSource GLSL 140
3030 %float_name = OpString "float"
3031 %main_name = OpString "main"
3032 %f_name = OpString "f"
3033 %i_name = OpString "i"
3034 %x_name = OpString "x"
3035 OpName %main "main"
3036 OpName %f "f"
3037 OpName %i "i"
3038 OpName %BC "BC"
3039 OpName %fo "fo"
3040 %void = OpTypeVoid
3041 %8 = OpTypeFunction %void
3042 %float = OpTypeFloat 32
3043 %_ptr_Function_float = OpTypePointer Function %float
3044 %float_0 = OpConstant %float 0
3045 %int = OpTypeInt 32 1
3046 %uint = OpTypeInt 32 0
3047 %uint_32 = OpConstant %uint 32
3048 %_ptr_Function_int = OpTypePointer Function %int
3049 %int_0 = OpConstant %int 0
3050 %int_4 = OpConstant %int 4
3051 %bool = OpTypeBool
3052 %v4float = OpTypeVector %float 4
3053 %_ptr_Input_v4float = OpTypePointer Input %v4float
3054 %BC = OpVariable %_ptr_Input_v4float Input
3055 %_ptr_Input_float = OpTypePointer Input %float
3056 %int_1 = OpConstant %int 1
3057 %_ptr_Output_float = OpTypePointer Output %float
3058 %fo = OpVariable %_ptr_Output_float Output
3059 %null_expr = OpExtInst %void %ext DebugExpression
3060 %src = OpExtInst %void %ext DebugSource %file_name
3061 %cu = OpExtInst %void %ext DebugCompilationUnit 1 4 %src HLSL
3062 %dbg_tf = OpExtInst %void %ext DebugTypeBasic %float_name %uint_32 Float
3063 %dbg_v4f = OpExtInst %void %ext DebugTypeVector %dbg_tf 4
3064 %main_ty = OpExtInst %void %ext DebugTypeFunction FlagIsProtected|FlagIsPrivate %dbg_v4f %dbg_v4f
3065 %dbg_main = OpExtInst %void %ext DebugFunction %main_name %main_ty %src 0 0 %cu %main_name FlagIsProtected|FlagIsPrivate 10 %main
3066 %bb = OpExtInst %void %ext DebugLexicalBlock %src 0 0 %dbg_main
3067 %bb_child = OpExtInst %void %ext DebugLexicalBlock %src 1 0 %bb
3068 %dbg_f = OpExtInst %void %ext DebugLocalVariable %f_name %dbg_v4f %src 0 0 %dbg_main FlagIsLocal
3069 %dbg_i = OpExtInst %void %ext DebugLocalVariable %i_name %dbg_v4f %src 1 0 %dbg_main FlagIsLocal
3070 %dbg_x = OpExtInst %void %ext DebugLocalVariable %x_name %dbg_v4f %src 2 0 %bb FlagIsLocal
3071 %main = OpFunction %void None %8
3072 %22 = OpLabel
3073 %s0 = OpExtInst %void %ext DebugScope %dbg_main
3074 %f = OpVariable %_ptr_Function_float Function
3075 %i = OpVariable %_ptr_Function_int Function
3076 OpStore %f %float_0
3077 OpStore %i %int_0
3078 %decl0 = OpExtInst %void %ext DebugDeclare %dbg_f %f %null_expr
3079 %decl1 = OpExtInst %void %ext DebugDeclare %dbg_i %i %null_expr
3080 OpBranch %23
3081 %23 = OpLabel
3082 %s1 = OpExtInst %void %ext DebugScope %dbg_main
3083 OpLoopMerge %24 %25 None
3084 OpBranch %26
3085 %26 = OpLabel
3086 %s2 = OpExtInst %void %ext DebugScope %dbg_main
3087 %27 = OpLoad %int %i
3088 %28 = OpSLessThan %bool %27 %int_4
3089 OpBranchConditional %28 %29 %24
3090 %29 = OpLabel
3091 %scope = OpExtInst %void %ext DebugScope %bb
3092 %decl2 = OpExtInst %void %ext DebugDeclare %dbg_x %f %null_expr
3093 %30 = OpLoad %float %f
3094 %31 = OpLoad %int %i
3095 %32 = OpAccessChain %_ptr_Input_float %BC %31
3096 %33 = OpLoad %float %32
3097 %34 = OpFAdd %float %30 %33
3098 OpStore %f %34
3099 OpBranch %38
3100 %38 = OpLabel
3101 %child_scope = OpExtInst %void %ext DebugScope %bb_child
3102 %39 = OpLoad %float %f
3103 %40 = OpFAdd %float %39 %33
3104 OpStore %f %40
3105 OpBranch %25
3106 %25 = OpLabel
3107 %s3 = OpExtInst %void %ext DebugScope %dbg_main
3108 %35 = OpLoad %int %i
3109 %36 = OpIAdd %int %35 %int_1
3110 OpStore %i %36
3111 OpBranch %23
3112 %24 = OpLabel
3113 %s4 = OpExtInst %void %ext DebugScope %dbg_main
3114 %37 = OpLoad %float %f
3115 OpStore %fo %37
3116 OpReturn
3117 OpFunctionEnd
3118 )";
3119 
3120   SinglePassRunAndMatch<SSARewritePass>(text, true);
3121 }
3122 
TEST_F(LocalSSAElimTest,DebugForLoopUseDebugValueInsteadOfDebugDeclare)3123 TEST_F(LocalSSAElimTest, DebugForLoopUseDebugValueInsteadOfDebugDeclare) {
3124   // #version 140
3125   //
3126   // in vec4 BC;
3127   // out float fo;
3128   //
3129   // struct S {
3130   //     float f;
3131   //     int i;
3132   // };
3133   //
3134   // void main()
3135   // {
3136   //     S foo = {0.0, 0};
3137   //     for (; foo.i<4; foo.i++) {
3138   //       foo.f = foo.f + BC[foo.i];
3139   //     }
3140   //     fo = foo.f;
3141   // }
3142 
3143   const std::string text = R"(
3144 ; CHECK: [[f_name:%\w+]] = OpString "f"
3145 ; CHECK: [[empty_expr:%\w+]] = OpExtInst %void [[ext:%\d+]] DebugExpression
3146 ; CHECK: [[deref_op:%\w+]] = OpExtInst %void [[ext]] DebugOperation Deref
3147 ; CHECK: [[deref:%\w+]] = OpExtInst %void [[ext]] DebugExpression [[deref_op]]
3148 ; CHECK: [[dbg_foo:%\w+]] = OpExtInst %void [[ext]] DebugLocalVariable [[f_name]]
3149 
3150 ; CHECK:      OpStore %f %float_0
3151 ; CHECK-NEXT: OpExtInst %void [[ext]] DebugValue [[dbg_foo]] %float_0 [[empty_expr]] %uint_0
3152 ; CHECK-NEXT: OpStore %i %int_0
3153 ; CHECK-NEXT: OpExtInst %void [[ext]] DebugValue [[dbg_foo]] %int_0 [[empty_expr]] %uint_1
3154 
3155 ; CHECK:      [[loop_head:%\w+]] = OpLabel
3156 ; CHECK:      [[phi0:%\w+]] = OpPhi %float %float_0
3157 ; CHECK:      [[phi1:%\w+]] = OpPhi %int %int_0
3158 ; CHECK-NEXT: OpExtInst %void [[ext]] DebugValue [[dbg_foo]] [[phi0]] [[empty_expr]] %uint_0
3159 ; CHECK-NEXT: OpExtInst %void [[ext]] DebugValue [[dbg_foo]] [[phi1]] [[empty_expr]] %uint_1
3160 ; CHECK:      OpLoopMerge [[loop_merge:%\w+]] [[loop_cont:%\w+]] None
3161 ; CHECK-NEXT: OpBranch [[loop_body:%\w+]]
3162 
3163 ; CHECK:      [[loop_body]] = OpLabel
3164 ; CHECK:      OpBranchConditional {{%\w+}} [[bb:%\w+]] [[loop_merge]]
3165 
3166 ; CHECK:      [[bb]] = OpLabel
3167 ; CHECK:      OpStore %f [[f_val:%\w+]]
3168 ; CHECK-NEXT: OpExtInst %void [[ext]] DebugValue [[dbg_foo]] [[f_val]] [[empty_expr]] %uint_0
3169 ; CHECK-NEXT: OpBranch [[loop_cont]]
3170 
3171 ; CHECK:      [[loop_cont]] = OpLabel
3172 ; CHECK:      OpStore %i [[i_val:%\w+]]
3173 ; CHECK-NEXT: OpExtInst %void [[ext]] DebugValue [[dbg_foo]] [[i_val]] [[empty_expr]] %uint_1
3174 ; CHECK-NEXT: OpBranch [[loop_head]]
3175 
3176 OpCapability Shader
3177 %1 = OpExtInstImport "GLSL.std.450"
3178 %ext = OpExtInstImport "OpenCL.DebugInfo.100"
3179 OpMemoryModel Logical GLSL450
3180 OpEntryPoint Fragment %main "main" %BC %fo
3181 OpExecutionMode %main OriginUpperLeft
3182 %file_name = OpString "test"
3183 OpSource GLSL 140
3184 %float_name = OpString "float"
3185 %main_name = OpString "main"
3186 %f_name = OpString "f"
3187 OpName %main "main"
3188 OpName %f "f"
3189 OpName %i "i"
3190 OpName %BC "BC"
3191 OpName %fo "fo"
3192 %void = OpTypeVoid
3193 %8 = OpTypeFunction %void
3194 %float = OpTypeFloat 32
3195 %_ptr_Function_float = OpTypePointer Function %float
3196 %float_0 = OpConstant %float 0
3197 %int = OpTypeInt 32 1
3198 %uint = OpTypeInt 32 0
3199 %uint_32 = OpConstant %uint 32
3200 %uint_0 = OpConstant %uint 0
3201 %uint_1 = OpConstant %uint 1
3202 %_ptr_Function_int = OpTypePointer Function %int
3203 %int_0 = OpConstant %int 0
3204 %int_4 = OpConstant %int 4
3205 %bool = OpTypeBool
3206 %v4float = OpTypeVector %float 4
3207 %_ptr_Input_v4float = OpTypePointer Input %v4float
3208 %BC = OpVariable %_ptr_Input_v4float Input
3209 %_ptr_Input_float = OpTypePointer Input %float
3210 %int_1 = OpConstant %int 1
3211 %_ptr_Output_float = OpTypePointer Output %float
3212 %fo = OpVariable %_ptr_Output_float Output
3213 %deref_op = OpExtInst %void %ext DebugOperation Deref
3214 %deref = OpExtInst %void %ext DebugExpression %deref_op
3215 %src = OpExtInst %void %ext DebugSource %file_name
3216 %cu = OpExtInst %void %ext DebugCompilationUnit 1 4 %src HLSL
3217 %dbg_tf = OpExtInst %void %ext DebugTypeBasic %float_name %uint_32 Float
3218 %dbg_v4f = OpExtInst %void %ext DebugTypeVector %dbg_tf 4
3219 %main_ty = OpExtInst %void %ext DebugTypeFunction FlagIsProtected|FlagIsPrivate %dbg_v4f %dbg_v4f
3220 %dbg_main = OpExtInst %void %ext DebugFunction %main_name %main_ty %src 0 0 %cu %main_name FlagIsProtected|FlagIsPrivate 10 %main
3221 %dbg_foo = OpExtInst %void %ext DebugLocalVariable %f_name %dbg_v4f %src 0 0 %dbg_main FlagIsLocal
3222 %main = OpFunction %void None %8
3223 %22 = OpLabel
3224 %s0 = OpExtInst %void %ext DebugScope %dbg_main
3225 %f = OpVariable %_ptr_Function_float Function
3226 %i = OpVariable %_ptr_Function_int Function
3227 OpStore %f %float_0
3228 OpStore %i %int_0
3229 %decl0 = OpExtInst %void %ext DebugValue %dbg_foo %f %deref %uint_0
3230 %decl1 = OpExtInst %void %ext DebugValue %dbg_foo %i %deref %uint_1
3231 OpBranch %23
3232 %23 = OpLabel
3233 %s1 = OpExtInst %void %ext DebugScope %dbg_main
3234 OpLoopMerge %24 %25 None
3235 OpBranch %26
3236 %26 = OpLabel
3237 %s2 = OpExtInst %void %ext DebugScope %dbg_main
3238 %27 = OpLoad %int %i
3239 %28 = OpSLessThan %bool %27 %int_4
3240 OpBranchConditional %28 %29 %24
3241 %29 = OpLabel
3242 %s3 = OpExtInst %void %ext DebugScope %dbg_main
3243 %30 = OpLoad %float %f
3244 %31 = OpLoad %int %i
3245 %32 = OpAccessChain %_ptr_Input_float %BC %31
3246 %33 = OpLoad %float %32
3247 %34 = OpFAdd %float %30 %33
3248 OpStore %f %34
3249 OpBranch %25
3250 %25 = OpLabel
3251 %s4 = OpExtInst %void %ext DebugScope %dbg_main
3252 %35 = OpLoad %int %i
3253 %36 = OpIAdd %int %35 %int_1
3254 OpStore %i %36
3255 OpBranch %23
3256 %24 = OpLabel
3257 %s5 = OpExtInst %void %ext DebugScope %dbg_main
3258 %37 = OpLoad %float %f
3259 OpStore %fo %37
3260 OpReturn
3261 OpFunctionEnd
3262 )";
3263 
3264   SinglePassRunAndMatch<SSARewritePass>(text, true);
3265 }
3266 
TEST_F(LocalSSAElimTest,DebugValueNotUsedForDebugDeclare)3267 TEST_F(LocalSSAElimTest, DebugValueNotUsedForDebugDeclare) {
3268   // #version 140
3269   //
3270   // in vec4 BC;
3271   // out float fo;
3272   //
3273   // void main()
3274   // {
3275   //     float f = 0.0;
3276   //     for (int i=0; i<4; i++) {
3277   //       f = f + BC[i];
3278   //     }
3279   //     fo = f;
3280   // }
3281 
3282   const std::string text = R"(
3283 ; CHECK: [[f_name:%\w+]] = OpString "f"
3284 ; CHECK: [[i_name:%\w+]] = OpString "i"
3285 ; CHECK: [[dbg_f:%\w+]] = OpExtInst %void [[ext:%\d+]] DebugLocalVariable [[f_name]]
3286 ; CHECK: [[dbg_i:%\w+]] = OpExtInst %void [[ext]] DebugLocalVariable [[i_name]]
3287 
3288 ; CHECK:      OpStore %f %float_0
3289 ; CHECK-NEXT: OpStore %i %int_0
3290 ; CHECK-NEXT: OpExtInst %void [[ext]] DebugValue [[dbg_f]] %f
3291 ; CHECK-NEXT: OpExtInst %void [[ext]] DebugValue [[dbg_i]] %i
3292 
3293 ; CHECK-NOT:  DebugValue
3294 ; CHECK-NOT:  DebugDeclare
3295 
3296 OpCapability Shader
3297 %1 = OpExtInstImport "GLSL.std.450"
3298 %ext = OpExtInstImport "OpenCL.DebugInfo.100"
3299 OpMemoryModel Logical GLSL450
3300 OpEntryPoint Fragment %main "main" %BC %fo
3301 OpExecutionMode %main OriginUpperLeft
3302 %file_name = OpString "test"
3303 OpSource GLSL 140
3304 %float_name = OpString "float"
3305 %main_name = OpString "main"
3306 %f_name = OpString "f"
3307 %i_name = OpString "i"
3308 OpName %main "main"
3309 OpName %f "f"
3310 OpName %i "i"
3311 OpName %BC "BC"
3312 OpName %fo "fo"
3313 %void = OpTypeVoid
3314 %8 = OpTypeFunction %void
3315 %float = OpTypeFloat 32
3316 %_ptr_Function_float = OpTypePointer Function %float
3317 %float_0 = OpConstant %float 0
3318 %int = OpTypeInt 32 1
3319 %uint = OpTypeInt 32 0
3320 %uint_32 = OpConstant %uint 32
3321 %_ptr_Function_int = OpTypePointer Function %int
3322 %int_0 = OpConstant %int 0
3323 %int_4 = OpConstant %int 4
3324 %bool = OpTypeBool
3325 %v4float = OpTypeVector %float 4
3326 %_ptr_Input_v4float = OpTypePointer Input %v4float
3327 %BC = OpVariable %_ptr_Input_v4float Input
3328 %_ptr_Input_float = OpTypePointer Input %float
3329 %int_1 = OpConstant %int 1
3330 %_ptr_Output_float = OpTypePointer Output %float
3331 %fo = OpVariable %_ptr_Output_float Output
3332 %null_expr = OpExtInst %void %ext DebugExpression
3333 %src = OpExtInst %void %ext DebugSource %file_name
3334 %cu = OpExtInst %void %ext DebugCompilationUnit 1 4 %src HLSL
3335 %dbg_tf = OpExtInst %void %ext DebugTypeBasic %float_name %uint_32 Float
3336 %dbg_v4f = OpExtInst %void %ext DebugTypeVector %dbg_tf 4
3337 %main_ty = OpExtInst %void %ext DebugTypeFunction FlagIsProtected|FlagIsPrivate %dbg_v4f %dbg_v4f
3338 %dbg_main = OpExtInst %void %ext DebugFunction %main_name %main_ty %src 0 0 %cu %main_name FlagIsProtected|FlagIsPrivate 10 %main
3339 %dbg_f = OpExtInst %void %ext DebugLocalVariable %f_name %dbg_v4f %src 0 0 %dbg_main FlagIsLocal
3340 %dbg_i = OpExtInst %void %ext DebugLocalVariable %i_name %dbg_v4f %src 1 0 %dbg_main FlagIsLocal
3341 %main = OpFunction %void None %8
3342 %22 = OpLabel
3343 %s0 = OpExtInst %void %ext DebugScope %dbg_main
3344 %f = OpVariable %_ptr_Function_float Function
3345 %i = OpVariable %_ptr_Function_int Function
3346 OpStore %f %float_0
3347 OpStore %i %int_0
3348 %decl0 = OpExtInst %void %ext DebugValue %dbg_f %f %null_expr
3349 %decl1 = OpExtInst %void %ext DebugValue %dbg_i %i %null_expr
3350 OpBranch %23
3351 %23 = OpLabel
3352 %s1 = OpExtInst %void %ext DebugScope %dbg_main
3353 OpLoopMerge %24 %25 None
3354 OpBranch %26
3355 %26 = OpLabel
3356 %s2 = OpExtInst %void %ext DebugScope %dbg_main
3357 %27 = OpLoad %int %i
3358 %28 = OpSLessThan %bool %27 %int_4
3359 OpBranchConditional %28 %29 %24
3360 %29 = OpLabel
3361 %s3 = OpExtInst %void %ext DebugScope %dbg_main
3362 %30 = OpLoad %float %f
3363 %31 = OpLoad %int %i
3364 %32 = OpAccessChain %_ptr_Input_float %BC %31
3365 %33 = OpLoad %float %32
3366 %34 = OpFAdd %float %30 %33
3367 OpStore %f %34
3368 OpBranch %25
3369 %25 = OpLabel
3370 %s4 = OpExtInst %void %ext DebugScope %dbg_main
3371 %35 = OpLoad %int %i
3372 %36 = OpIAdd %int %35 %int_1
3373 OpStore %i %36
3374 OpBranch %23
3375 %24 = OpLabel
3376 %s5 = OpExtInst %void %ext DebugScope %dbg_main
3377 %37 = OpLoad %float %f
3378 OpStore %fo %37
3379 OpReturn
3380 OpFunctionEnd
3381 )";
3382 
3383   SinglePassRunAndMatch<SSARewritePass>(text, true);
3384 }
3385 
TEST_F(LocalSSAElimTest,DebugNestedForLoop)3386 TEST_F(LocalSSAElimTest, DebugNestedForLoop) {
3387   const std::string text = R"(
3388 ; CHECK: = OpFunction
3389 ; CHECK-NEXT: [[entry:%\w+]] = OpLabel
3390 ; CHECK: OpStore %f %float_0
3391 ; CHECK-NEXT: = OpExtInst %void [[ext:%\w+]] DebugValue [[dbg_f:%\w+]] %float_0
3392 
3393 ; CHECK: [[outer_header:%\w+]] = OpLabel
3394 ; CHECK: [[outer_f:%\w+]] = OpPhi %float %float_0 [[entry]] [[inner_f:%\w+]] [[outer_be:%\w+]]
3395 ; CHECK: = OpExtInst %void [[ext]] DebugValue [[dbg_f]] [[outer_f]]
3396 
3397 ; CHECK: [[inner_pre_header:%\w+]] = OpLabel
3398 ; CHECK: [[inner_header:%\w+]] = OpLabel
3399 ; CHECK: [[inner_f]] = OpPhi %float [[outer_f]] [[inner_pre_header]] [[f_next:%\w+]] [[inner_be:%\w+]]
3400 ; CHECK: = OpExtInst %void [[ext]] DebugValue [[dbg_f]] [[inner_f]]
3401 
3402 ; CHECK: [[inner_be]] = OpLabel
3403 ; CHECK: [[f_next]] = OpFAdd %float [[inner_f]]
3404 ; CHECK-NEXT: OpStore %f [[f_next]]
3405 ; CHECK-NEXT: = OpExtInst %void [[ext]] DebugValue [[dbg_f]] [[f_next]]
3406 
3407 OpCapability Shader
3408 %1 = OpExtInstImport "GLSL.std.450"
3409 %ext = OpExtInstImport "OpenCL.DebugInfo.100"
3410 OpMemoryModel Logical GLSL450
3411 OpEntryPoint Fragment %main "main" %BC %fo
3412 OpExecutionMode %main OriginUpperLeft
3413 %file_name = OpString "test"
3414 %float_name = OpString "float"
3415 %main_name = OpString "main"
3416 %f_name = OpString "f"
3417 OpSource GLSL 450
3418 OpName %main "main"
3419 OpName %f "f"
3420 OpName %i "i"
3421 OpName %j "j"
3422 OpName %BC "BC"
3423 OpName %fo "fo"
3424 OpDecorate %BC Location 0
3425 OpDecorate %fo Location 0
3426 %void = OpTypeVoid
3427 %9 = OpTypeFunction %void
3428 %float = OpTypeFloat 32
3429 %_ptr_Function_float = OpTypePointer Function %float
3430 %float_0 = OpConstant %float 0
3431 %int = OpTypeInt 32 1
3432 %_ptr_Function_int = OpTypePointer Function %int
3433 %int_0 = OpConstant %int 0
3434 %int_4 = OpConstant %int 4
3435 %uint = OpTypeInt 32 0
3436 %uint_32 = OpConstant %uint 32
3437 %bool = OpTypeBool
3438 %v4float = OpTypeVector %float 4
3439 %mat4v4float = OpTypeMatrix %v4float 4
3440 %_ptr_Input_mat4v4float = OpTypePointer Input %mat4v4float
3441 %BC = OpVariable %_ptr_Input_mat4v4float Input
3442 %_ptr_Input_float = OpTypePointer Input %float
3443 %int_1 = OpConstant %int 1
3444 %_ptr_Output_float = OpTypePointer Output %float
3445 %fo = OpVariable %_ptr_Output_float Output
3446 
3447 ; Debug information
3448 %null_expr = OpExtInst %void %ext DebugExpression
3449 %src = OpExtInst %void %ext DebugSource %file_name
3450 %cu = OpExtInst %void %ext DebugCompilationUnit 1 4 %src HLSL
3451 %dbg_tf = OpExtInst %void %ext DebugTypeBasic %float_name %uint_32 Float
3452 %main_ty = OpExtInst %void %ext DebugTypeFunction FlagIsProtected|FlagIsPrivate %void
3453 %dbg_main = OpExtInst %void %ext DebugFunction %main_name %main_ty %src 0 0 %cu %main_name FlagIsProtected|FlagIsPrivate 10 %main
3454 %dbg_f = OpExtInst %void %ext DebugLocalVariable %f_name %dbg_tf %src 0 0 %dbg_main FlagIsLocal
3455 
3456 %main = OpFunction %void None %9
3457 %24 = OpLabel
3458 %s1 = OpExtInst %void %ext DebugScope %dbg_main
3459 %f = OpVariable %_ptr_Function_float Function
3460 %i = OpVariable %_ptr_Function_int Function
3461 %j = OpVariable %_ptr_Function_int Function
3462 
3463 ; DebugDeclare
3464 OpStore %f %float_0
3465 %decl = OpExtInst %void %ext DebugDeclare %dbg_f %f %null_expr
3466 
3467 OpStore %i %int_0
3468 OpBranch %25
3469 %25 = OpLabel
3470 %s2 = OpExtInst %void %ext DebugScope %dbg_main
3471 %26 = OpLoad %int %i
3472 %27 = OpSLessThan %bool %26 %int_4
3473 OpLoopMerge %28 %29 None
3474 OpBranchConditional %27 %30 %28
3475 %30 = OpLabel
3476 %s3 = OpExtInst %void %ext DebugScope %dbg_main
3477 OpStore %j %int_0
3478 OpBranch %31
3479 %31 = OpLabel
3480 %s4 = OpExtInst %void %ext DebugScope %dbg_main
3481 %32 = OpLoad %int %j
3482 %33 = OpSLessThan %bool %32 %int_4
3483 OpLoopMerge %50 %34 None
3484 OpBranchConditional %33 %34 %50
3485 %34 = OpLabel
3486 %s5 = OpExtInst %void %ext DebugScope %dbg_main
3487 %35 = OpLoad %float %f
3488 %36 = OpLoad %int %i
3489 %37 = OpLoad %int %j
3490 %38 = OpAccessChain %_ptr_Input_float %BC %36 %37
3491 %39 = OpLoad %float %38
3492 %40 = OpFAdd %float %35 %39
3493 OpStore %f %40
3494 %41 = OpLoad %int %j
3495 %42 = OpIAdd %int %41 %int_1
3496 OpStore %j %42
3497 OpBranch %31
3498 %50 = OpLabel
3499 %s6 = OpExtInst %void %ext DebugScope %dbg_main
3500 OpBranch %29
3501 %29 = OpLabel
3502 %s7 = OpExtInst %void %ext DebugScope %dbg_main
3503 %43 = OpLoad %int %i
3504 %44 = OpIAdd %int %43 %int_1
3505 OpStore %i %44
3506 OpBranch %25
3507 %28 = OpLabel
3508 %s8 = OpExtInst %void %ext DebugScope %dbg_main
3509 %45 = OpLoad %float %f
3510 OpStore %fo %45
3511 OpReturn
3512 OpFunctionEnd
3513 )";
3514 
3515   SinglePassRunAndMatch<SSARewritePass>(text, true);
3516 }
3517 
TEST_F(LocalSSAElimTest,DebugForLoopWithContinue)3518 TEST_F(LocalSSAElimTest, DebugForLoopWithContinue) {
3519   const std::string text = R"(
3520 ; CHECK: = OpFunction
3521 ; CHECK-NEXT: [[entry:%\w+]] = OpLabel
3522 ; CHECK: OpStore %f %float_0
3523 ; CHECK-NEXT: = OpExtInst %void [[ext:%\w+]] DebugValue [[dbg_f:%\w+]] %float_0
3524 
3525 ; CHECK: [[outer_header:%\w+]] = OpLabel
3526 ; CHECK: [[outer_f:%\w+]] = OpPhi %float %float_0 [[entry]] [[inner_f:%\w+]] [[cont:%\w+]]
3527 ; CHECK: = OpExtInst %void [[ext]] DebugValue [[dbg_f]] [[outer_f]]
3528 
3529 ; CHECK: [[f_next:%\w+]] = OpFAdd %float [[outer_f]]
3530 ; CHECK-NEXT: OpStore %f [[f_next]]
3531 ; CHECK-NEXT: = OpExtInst %void [[ext]] DebugValue [[dbg_f]] [[f_next]]
3532 
3533 ; CHECK: [[cont]] = OpLabel
3534 ; CHECK: [[inner_f]] = OpPhi %float [[outer_f]] {{%\d+}} [[f_next]] {{%\d+}}
3535 ; CHECK-NEXT: = OpExtInst %void [[ext]] DebugValue [[dbg_f]] [[inner_f]]
3536 
3537 OpCapability Shader
3538 %1 = OpExtInstImport "GLSL.std.450"
3539 %ext = OpExtInstImport "OpenCL.DebugInfo.100"
3540 OpMemoryModel Logical GLSL450
3541 OpEntryPoint Fragment %main "main" %BC %fo
3542 OpExecutionMode %main OriginUpperLeft
3543 %file_name = OpString "test"
3544 %float_name = OpString "float"
3545 %main_name = OpString "main"
3546 %f_name = OpString "f"
3547 OpSource GLSL 140
3548 OpName %main "main"
3549 OpName %f "f"
3550 OpName %i "i"
3551 OpName %t "t"
3552 OpName %BC "BC"
3553 OpName %fo "fo"
3554 %void = OpTypeVoid
3555 %9 = OpTypeFunction %void
3556 %float = OpTypeFloat 32
3557 %_ptr_Function_float = OpTypePointer Function %float
3558 %float_0 = OpConstant %float 0
3559 %int = OpTypeInt 32 1
3560 %_ptr_Function_int = OpTypePointer Function %int
3561 %int_0 = OpConstant %int 0
3562 %int_4 = OpConstant %int 4
3563 %uint = OpTypeInt 32 0
3564 %uint_32 = OpConstant %uint 32
3565 %bool = OpTypeBool
3566 %v4float = OpTypeVector %float 4
3567 %_ptr_Input_v4float = OpTypePointer Input %v4float
3568 %BC = OpVariable %_ptr_Input_v4float Input
3569 %_ptr_Input_float = OpTypePointer Input %float
3570 %int_1 = OpConstant %int 1
3571 %_ptr_Output_float = OpTypePointer Output %float
3572 %fo = OpVariable %_ptr_Output_float Output
3573 
3574 ; Debug information
3575 %null_expr = OpExtInst %void %ext DebugExpression
3576 %src = OpExtInst %void %ext DebugSource %file_name
3577 %cu = OpExtInst %void %ext DebugCompilationUnit 1 4 %src HLSL
3578 %dbg_tf = OpExtInst %void %ext DebugTypeBasic %float_name %uint_32 Float
3579 %main_ty = OpExtInst %void %ext DebugTypeFunction FlagIsProtected|FlagIsPrivate %void
3580 %dbg_main = OpExtInst %void %ext DebugFunction %main_name %main_ty %src 0 0 %cu %main_name FlagIsProtected|FlagIsPrivate 10 %main
3581 %dbg_f = OpExtInst %void %ext DebugLocalVariable %f_name %dbg_tf %src 0 0 %dbg_main FlagIsLocal
3582 
3583 %main = OpFunction %void None %9
3584 %23 = OpLabel
3585 %s0 = OpExtInst %void %ext DebugScope %dbg_main
3586 %f = OpVariable %_ptr_Function_float Function
3587 %i = OpVariable %_ptr_Function_int Function
3588 %t = OpVariable %_ptr_Function_float Function
3589 
3590 ; DebugDeclare
3591 OpStore %f %float_0
3592 %decl = OpExtInst %void %ext DebugDeclare %dbg_f %f %null_expr
3593 
3594 OpStore %i %int_0
3595 OpBranch %24
3596 %24 = OpLabel
3597 %s1 = OpExtInst %void %ext DebugScope %dbg_main
3598 OpLoopMerge %25 %26 None
3599 OpBranch %27
3600 %27 = OpLabel
3601 %s2 = OpExtInst %void %ext DebugScope %dbg_main
3602 %28 = OpLoad %int %i
3603 %29 = OpSLessThan %bool %28 %int_4
3604 OpBranchConditional %29 %30 %25
3605 %30 = OpLabel
3606 %s3 = OpExtInst %void %ext DebugScope %dbg_main
3607 %31 = OpLoad %int %i
3608 %32 = OpAccessChain %_ptr_Input_float %BC %31
3609 %33 = OpLoad %float %32
3610 OpStore %t %33
3611 %34 = OpLoad %float %t
3612 %35 = OpFOrdLessThan %bool %34 %float_0
3613 OpSelectionMerge %36 None
3614 OpBranchConditional %35 %37 %36
3615 %37 = OpLabel
3616 %s4 = OpExtInst %void %ext DebugScope %dbg_main
3617 OpBranch %26
3618 %36 = OpLabel
3619 %s5 = OpExtInst %void %ext DebugScope %dbg_main
3620 %38 = OpLoad %float %f
3621 %39 = OpLoad %float %t
3622 %40 = OpFAdd %float %38 %39
3623 OpStore %f %40
3624 OpBranch %26
3625 %26 = OpLabel
3626 %s6 = OpExtInst %void %ext DebugScope %dbg_main
3627 %41 = OpLoad %int %i
3628 %42 = OpIAdd %int %41 %int_1
3629 OpStore %i %42
3630 OpBranch %24
3631 %25 = OpLabel
3632 %s7 = OpExtInst %void %ext DebugScope %dbg_main
3633 %43 = OpLoad %float %f
3634 OpStore %fo %43
3635 OpReturn
3636 OpFunctionEnd
3637 )";
3638 
3639   SinglePassRunAndMatch<SSARewritePass>(text, true);
3640 }
3641 
TEST_F(LocalSSAElimTest,DebugIfElse)3642 TEST_F(LocalSSAElimTest, DebugIfElse) {
3643   const std::string text = R"(
3644 OpCapability Shader
3645 %1 = OpExtInstImport "GLSL.std.450"
3646 %ext = OpExtInstImport "OpenCL.DebugInfo.100"
3647 OpMemoryModel Logical GLSL450
3648 OpEntryPoint Fragment %main "main" %f %BaseColor %gl_FragColor
3649 OpExecutionMode %main OriginUpperLeft
3650 %file_name = OpString "test"
3651 %float_name = OpString "float"
3652 %main_name = OpString "main"
3653 %v_name = OpString "v"
3654 OpSource GLSL 140
3655 OpName %main "main"
3656 OpName %f "f"
3657 OpName %v "v"
3658 OpName %BaseColor "BaseColor"
3659 OpName %gl_FragColor "gl_FragColor"
3660 %void = OpTypeVoid
3661 %8 = OpTypeFunction %void
3662 %float = OpTypeFloat 32
3663 %_ptr_Input_float = OpTypePointer Input %float
3664 %f = OpVariable %_ptr_Input_float Input
3665 %float_0 = OpConstant %float 0
3666 %uint = OpTypeInt 32 0
3667 %uint_32 = OpConstant %uint 32
3668 %bool = OpTypeBool
3669 %v4float = OpTypeVector %float 4
3670 %_ptr_Function_v4float = OpTypePointer Function %v4float
3671 %_ptr_Input_v4float = OpTypePointer Input %v4float
3672 %BaseColor = OpVariable %_ptr_Input_v4float Input
3673 %float_0_5 = OpConstant %float 0.5
3674 %float_1 = OpConstant %float 1
3675 %18 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
3676 %_ptr_Output_v4float = OpTypePointer Output %v4float
3677 %gl_FragColor = OpVariable %_ptr_Output_v4float Output
3678 
3679 ; Debug information
3680 %null_expr = OpExtInst %void %ext DebugExpression
3681 %src = OpExtInst %void %ext DebugSource %file_name
3682 %cu = OpExtInst %void %ext DebugCompilationUnit 1 4 %src HLSL
3683 %dbg_tf = OpExtInst %void %ext DebugTypeBasic %float_name %uint_32 Float
3684 %main_ty = OpExtInst %void %ext DebugTypeFunction FlagIsProtected|FlagIsPrivate %void
3685 %dbg_main = OpExtInst %void %ext DebugFunction %main_name %main_ty %src 0 0 %cu %main_name FlagIsProtected|FlagIsPrivate 10 %main
3686 %dbg_v = OpExtInst %void %ext DebugLocalVariable %v_name %dbg_tf %src 0 0 %dbg_main FlagIsLocal
3687 
3688 %main = OpFunction %void None %8
3689 %20 = OpLabel
3690 %s0 = OpExtInst %void %ext DebugScope %dbg_main
3691 
3692 ; DebugDeclare
3693 %v = OpVariable %_ptr_Function_v4float Function
3694 %decl = OpExtInst %void %ext DebugDeclare %dbg_v %v %null_expr
3695 
3696 %21 = OpLoad %float %f
3697 %22 = OpFOrdGreaterThanEqual %bool %21 %float_0
3698 OpSelectionMerge %23 None
3699 OpBranchConditional %22 %24 %25
3700 
3701 ; CHECK: OpBranchConditional
3702 ; CHECK-NEXT: [[br0:%\w+]] = OpLabel
3703 ; CHECK: OpStore %v [[v0:%\w+]]
3704 ; CHECK-NEXT: = OpExtInst %void [[ext:%\w+]] DebugValue [[dbg_v:%\w+]] [[v0]]
3705 %24 = OpLabel
3706 %s1 = OpExtInst %void %ext DebugScope %dbg_main
3707 %26 = OpLoad %v4float %BaseColor
3708 %27 = OpVectorTimesScalar %v4float %26 %float_0_5
3709 OpStore %v %27
3710 OpBranch %23
3711 
3712 ; CHECK: [[br1:%\w+]] = OpLabel
3713 ; CHECK: OpStore %v [[v1:%\w+]]
3714 ; CHECK-NEXT: = OpExtInst %void [[ext]] DebugValue [[dbg_v]] [[v1]]
3715 %25 = OpLabel
3716 %s2 = OpExtInst %void %ext DebugScope %dbg_main
3717 %28 = OpLoad %v4float %BaseColor
3718 %29 = OpFAdd %v4float %28 %18
3719 OpStore %v %29
3720 OpBranch %23
3721 
3722 ; CHECK: [[phi:%\w+]] = OpPhi %v4float [[v0]] [[br0]] [[v1]] [[br1]]
3723 ; CHECK-NEXT: = OpExtInst %void [[ext]] DebugValue [[dbg_v]] [[phi]]
3724 %23 = OpLabel
3725 %s3 = OpExtInst %void %ext DebugScope %dbg_main
3726 %30 = OpLoad %v4float %v
3727 OpStore %gl_FragColor %30
3728 OpReturn
3729 OpFunctionEnd
3730 )";
3731 
3732   SinglePassRunAndMatch<SSARewritePass>(text, true);
3733 }
3734 
TEST_F(LocalSSAElimTest,DebugSwitch)3735 TEST_F(LocalSSAElimTest, DebugSwitch) {
3736   const std::string text = R"(
3737 OpCapability Shader
3738 %1 = OpExtInstImport "GLSL.std.450"
3739 %ext = OpExtInstImport "OpenCL.DebugInfo.100"
3740 OpMemoryModel Logical GLSL450
3741 OpEntryPoint Fragment %main "main" %BaseColor %f %gl_FragColor
3742 OpExecutionMode %main OriginUpperLeft
3743 %file_name = OpString "test"
3744 %float_name = OpString "float"
3745 %main_name = OpString "main"
3746 %v_name = OpString "v"
3747 OpSource GLSL 140
3748 OpName %main "main"
3749 OpName %v "v"
3750 OpName %BaseColor "BaseColor"
3751 OpName %i "i"
3752 OpName %f "f"
3753 OpName %gl_FragColor "gl_FragColor"
3754 %void = OpTypeVoid
3755 %9 = OpTypeFunction %void
3756 %float = OpTypeFloat 32
3757 %v4float = OpTypeVector %float 4
3758 %uint = OpTypeInt 32 0
3759 %uint_32 = OpConstant %uint 32
3760 %_ptr_Function_v4float = OpTypePointer Function %v4float
3761 %_ptr_Input_v4float = OpTypePointer Input %v4float
3762 %BaseColor = OpVariable %_ptr_Input_v4float Input
3763 %int = OpTypeInt 32 1
3764 %_ptr_Function_int = OpTypePointer Function %int
3765 %_ptr_Input_float = OpTypePointer Input %float
3766 %f = OpVariable %_ptr_Input_float Input
3767 %float_0_25 = OpConstant %float 0.25
3768 %float_0_75 = OpConstant %float 0.75
3769 %_ptr_Output_v4float = OpTypePointer Output %v4float
3770 %gl_FragColor = OpVariable %_ptr_Output_v4float Output
3771 
3772 ; Debug information
3773 %null_expr = OpExtInst %void %ext DebugExpression
3774 %src = OpExtInst %void %ext DebugSource %file_name
3775 %cu = OpExtInst %void %ext DebugCompilationUnit 1 4 %src HLSL
3776 %dbg_tf = OpExtInst %void %ext DebugTypeBasic %float_name %uint_32 Float
3777 %main_ty = OpExtInst %void %ext DebugTypeFunction FlagIsProtected|FlagIsPrivate %void
3778 %dbg_main = OpExtInst %void %ext DebugFunction %main_name %main_ty %src 0 0 %cu %main_name FlagIsProtected|FlagIsPrivate 10 %main
3779 %dbg_v = OpExtInst %void %ext DebugLocalVariable %v_name %dbg_tf %src 0 0 %dbg_main FlagIsLocal
3780 
3781 %main = OpFunction %void None %9
3782 %20 = OpLabel
3783 %s0 = OpExtInst %void %ext DebugScope %dbg_main
3784 %v = OpVariable %_ptr_Function_v4float Function
3785 %i = OpVariable %_ptr_Function_int Function
3786 %21 = OpLoad %v4float %BaseColor
3787 
3788 ; DebugDeclare
3789 OpStore %v %21
3790 %decl = OpExtInst %void %ext DebugDeclare %dbg_v %v %null_expr
3791 
3792 ; CHECK: %main = OpFunction %void None
3793 ; CHECK-NEXT: [[entry:%\w+]] = OpLabel
3794 ; CHECK: OpStore %v [[v0:%\w+]]
3795 ; CHECK-NEXT: = OpExtInst %void [[ext:%\w+]] DebugValue [[dbg_v:%\w+]] [[v0]]
3796 ; CHECK: OpSwitch {{%\w+}} [[case0:%\w+]] 0 [[case1:%\w+]] 1 [[case2:%\w+]] 2 [[case3:%\w+]]
3797 ; CHECK: OpStore %v [[v1:%\w+]]
3798 ; CHECK-NEXT: = OpExtInst %void [[ext]] DebugValue [[dbg_v]] [[v1]]
3799 ; CHECK: OpStore %v [[v2:%\w+]]
3800 ; CHECK-NEXT: = OpExtInst %void [[ext]] DebugValue [[dbg_v]] [[v2]]
3801 ; CHECK: [[phi0:%\w+]] = OpPhi %v4float [[v0]] [[entry]] [[v2]] [[case2]]
3802 ; CHECK-NEXT: = OpExtInst %void [[ext]] DebugValue [[dbg_v]] [[phi0]]
3803 ; CHECK: OpStore %v [[v3:%\w+]]
3804 ; CHECK-NEXT: = OpExtInst %void [[ext]] DebugValue [[dbg_v]] [[v3]]
3805 ; CHECK: [[phi1:%\w+]] = OpPhi %v4float [[v0]] [[case0]] [[v1]] [[case1]] [[v3]] [[case3]]
3806 ; CHECK-NEXT: = OpExtInst %void [[ext]] DebugValue [[dbg_v]] [[phi1]]
3807 
3808 %22 = OpLoad %float %f
3809 %23 = OpConvertFToS %int %22
3810 OpStore %i %23
3811 %24 = OpLoad %int %i
3812 OpSelectionMerge %25 None
3813 OpSwitch %24 %26 0 %27 1 %28 2 %29
3814 %26 = OpLabel
3815 %s1 = OpExtInst %void %ext DebugScope %dbg_main
3816 OpBranch %25
3817 %27 = OpLabel
3818 %s2 = OpExtInst %void %ext DebugScope %dbg_main
3819 %30 = OpLoad %v4float %v
3820 %31 = OpVectorTimesScalar %v4float %30 %float_0_25
3821 OpStore %v %31
3822 OpBranch %25
3823 %28 = OpLabel
3824 %s3 = OpExtInst %void %ext DebugScope %dbg_main
3825 %32 = OpLoad %v4float %v
3826 %33 = OpCompositeConstruct %v4float %float_0_25 %float_0_25 %float_0_25 %float_0_25
3827 %34 = OpFAdd %v4float %32 %33
3828 OpStore %v %34
3829 OpBranch %29
3830 %29 = OpLabel
3831 %s4 = OpExtInst %void %ext DebugScope %dbg_main
3832 %35 = OpLoad %v4float %v
3833 %36 = OpVectorTimesScalar %v4float %35 %float_0_75
3834 OpStore %v %36
3835 OpBranch %25
3836 %25 = OpLabel
3837 %s5 = OpExtInst %void %ext DebugScope %dbg_main
3838 %37 = OpLoad %v4float %v
3839 OpStore %gl_FragColor %37
3840 OpReturn
3841 OpFunctionEnd
3842 )";
3843 
3844   SinglePassRunAndMatch<SSARewritePass>(text, true);
3845 }
3846 
TEST_F(LocalSSAElimTest,DebugSwapProblem)3847 TEST_F(LocalSSAElimTest, DebugSwapProblem) {
3848   // #version 140
3849   //
3850   // in float fe;
3851   // out float fo;
3852   //
3853   // void main()
3854   // {
3855   //     float f1 = 0.0;
3856   //     float f2 = 1.0;
3857   //     int ie = int(fe);
3858   //     for (int i=0; i<ie; i++) {
3859   //       float t = f1;
3860   //       f1 = f2;
3861   //       f2 = t;
3862   //     }
3863   //     fo = f1;
3864   // }
3865   //
3866   // Because of the swap in the for loop, it generates the following phi
3867   // instructions:
3868   //
3869   // [[phi_f2]] = OpPhi %float %float_1 [[entry]] [[phi_f1]] ..
3870   // [[phi_f1]] = OpPhi %float %float_0 [[entry]] [[phi_f2]] ..
3871   //
3872   // Since they are used as operands by each other, we want to clearly check
3873   // what DebugValue we have to add for them.
3874 
3875   const std::string text = R"(
3876 OpCapability Shader
3877 %1 = OpExtInstImport "GLSL.std.450"
3878 %ext = OpExtInstImport "OpenCL.DebugInfo.100"
3879 OpMemoryModel Logical GLSL450
3880 OpEntryPoint Fragment %main "main" %fe %fo
3881 OpExecutionMode %main OriginUpperLeft
3882 OpSource GLSL 140
3883 %file_name = OpString "test"
3884 %float_name = OpString "float"
3885 %main_name = OpString "main"
3886 %t_name = OpString "t"
3887 OpName %main "main"
3888 OpName %f1 "f1"
3889 OpName %f2 "f2"
3890 OpName %ie "ie"
3891 OpName %fe "fe"
3892 OpName %i "i"
3893 OpName %t "t"
3894 OpName %fo "fo"
3895 %void = OpTypeVoid
3896 %11 = OpTypeFunction %void
3897 %float = OpTypeFloat 32
3898 %_ptr_Function_float = OpTypePointer Function %float
3899 %float_0 = OpConstant %float 0
3900 %float_1 = OpConstant %float 1
3901 %int = OpTypeInt 32 1
3902 %_ptr_Function_int = OpTypePointer Function %int
3903 %_ptr_Input_float = OpTypePointer Input %float
3904 %fe = OpVariable %_ptr_Input_float Input
3905 %int_0 = OpConstant %int 0
3906 %bool = OpTypeBool
3907 %int_1 = OpConstant %int 1
3908 %uint = OpTypeInt 32 0
3909 %uint_32 = OpConstant %uint 32
3910 %_ptr_Output_float = OpTypePointer Output %float
3911 %fo = OpVariable %_ptr_Output_float Output
3912 
3913 ; Debug information
3914 %null_expr = OpExtInst %void %ext DebugExpression
3915 %src = OpExtInst %void %ext DebugSource %file_name
3916 %cu = OpExtInst %void %ext DebugCompilationUnit 1 4 %src HLSL
3917 %dbg_tf = OpExtInst %void %ext DebugTypeBasic %float_name %uint_32 Float
3918 %main_ty = OpExtInst %void %ext DebugTypeFunction FlagIsProtected|FlagIsPrivate %void
3919 %dbg_main = OpExtInst %void %ext DebugFunction %main_name %main_ty %src 0 0 %cu %main_name FlagIsProtected|FlagIsPrivate 10 %main
3920 %dbg_f1 = OpExtInst %void %ext DebugLocalVariable %t_name %dbg_tf %src 0 0 %dbg_main FlagIsLocal
3921 %dbg_f2 = OpExtInst %void %ext DebugLocalVariable %t_name %dbg_tf %src 0 0 %dbg_main FlagIsLocal
3922 %dbg_i = OpExtInst %void %ext DebugLocalVariable %t_name %dbg_tf %src 0 0 %dbg_main FlagIsLocal
3923 
3924 %main = OpFunction %void None %11
3925 %23 = OpLabel
3926 %s0 = OpExtInst %void %ext DebugScope %dbg_main
3927 %f1 = OpVariable %_ptr_Function_float Function
3928 %f2 = OpVariable %_ptr_Function_float Function
3929 %ie = OpVariable %_ptr_Function_int Function
3930 %i = OpVariable %_ptr_Function_int Function
3931 %t = OpVariable %_ptr_Function_float Function
3932 OpStore %f1 %float_0
3933 OpStore %f2 %float_1
3934 %24 = OpLoad %float %fe
3935 %25 = OpConvertFToS %int %24
3936 OpStore %ie %25
3937 OpStore %i %int_0
3938 
3939 ; DebugDeclare
3940 %decl0 = OpExtInst %void %ext DebugDeclare %dbg_f1 %f1 %null_expr
3941 %decl1 = OpExtInst %void %ext DebugDeclare %dbg_f2 %f2 %null_expr
3942 %decl2 = OpExtInst %void %ext DebugDeclare %dbg_i  %i  %null_expr
3943 
3944 ; CHECK: %main = OpFunction %void None
3945 ; CHECK-NEXT: [[entry:%\w+]] = OpLabel
3946 
3947 ; CHECK: OpStore %f1 %float_0
3948 ; CHECK-NEXT: = OpExtInst %void [[ext:%\w+]] DebugValue [[dbg_f1:%\w+]] %float_0
3949 ; CHECK: OpStore %f2 %float_1
3950 ; CHECK-NEXT: = OpExtInst %void [[ext]] DebugValue [[dbg_f2:%\w+]] %float_1
3951 ; CHECK: OpStore %i %int_0
3952 ; CHECK-NEXT: = OpExtInst %void [[ext]] DebugValue [[dbg_i:%\w+]] %int_0
3953 
3954 ; CHECK: [[phi_f2:%\w+]] = OpPhi %float %float_1 [[entry]] [[phi_f1:%\w+]]
3955 ; CHECK: [[phi_f1]] = OpPhi %float %float_0 [[entry]] [[phi_f2]]
3956 ; CHECK: [[phi_i:%\w+]] = OpPhi %int %int_0 [[entry]]
3957 ; CHECK-NEXT: = OpExtInst %void [[ext]] DebugValue [[dbg_f2]] [[phi_f2]]
3958 ; CHECK-NEXT: = OpExtInst %void [[ext]] DebugValue [[dbg_f1]] [[phi_f1]]
3959 ; CHECK-NEXT: = OpExtInst %void [[ext]] DebugValue [[dbg_i]] [[phi_i]]
3960 
3961 OpBranch %26
3962 %26 = OpLabel
3963 %s1 = OpExtInst %void %ext DebugScope %dbg_main
3964 OpLoopMerge %27 %28 None
3965 OpBranch %29
3966 %29 = OpLabel
3967 %s2 = OpExtInst %void %ext DebugScope %dbg_main
3968 %30 = OpLoad %int %i
3969 %31 = OpLoad %int %ie
3970 %32 = OpSLessThan %bool %30 %31
3971 OpBranchConditional %32 %33 %27
3972 %33 = OpLabel
3973 %s3 = OpExtInst %void %ext DebugScope %dbg_main
3974 %34 = OpLoad %float %f1
3975 OpStore %t %34
3976 %35 = OpLoad %float %f2
3977 OpStore %f1 %35
3978 %36 = OpLoad %float %t
3979 OpStore %f2 %36
3980 OpBranch %28
3981 %28 = OpLabel
3982 %s4 = OpExtInst %void %ext DebugScope %dbg_main
3983 %37 = OpLoad %int %i
3984 %38 = OpIAdd %int %37 %int_1
3985 OpStore %i %38
3986 OpBranch %26
3987 %27 = OpLabel
3988 %s5 = OpExtInst %void %ext DebugScope %dbg_main
3989 %39 = OpLoad %float %f1
3990 OpStore %fo %39
3991 OpReturn
3992 OpFunctionEnd
3993 )";
3994 
3995   SinglePassRunAndMatch<SSARewritePass>(text, true);
3996 }
3997 
TEST_F(LocalSSAElimTest,RemoveDebugDeclareWithoutLoads)3998 TEST_F(LocalSSAElimTest, RemoveDebugDeclareWithoutLoads) {
3999   // Check that the DebugDeclare for c is removed even though its loads
4000   // had been removed previously by single block store/load optimization.
4001   // In the presence of DebugDeclare, single-block can and does remove loads,
4002   // but cannot change the stores into DebugValues and remove the DebugDeclare
4003   // because it is only a per block optimization, not a function optimization.
4004   // So SSA-rewrite must perform this role.
4005   //
4006   // Texture2D g_tColor;
4007   // SamplerState g_sAniso;
4008   //
4009   // struct PS_INPUT
4010   // {
4011   //   float2 vTextureCoords2 : TEXCOORD2;
4012   //   float2 vTextureCoords3 : TEXCOORD3;
4013   // };
4014   //
4015   // struct PS_OUTPUT
4016   // {
4017   //   float4 vColor : SV_Target0;
4018   // };
4019   //
4020   // PS_OUTPUT MainPs(PS_INPUT i)
4021   // {
4022   //   PS_OUTPUT ps_output;
4023   //   float4 c;
4024   //   c = g_tColor.Sample(g_sAniso, i.vTextureCoords2.xy);
4025   //   c += g_tColor.Sample(g_sAniso, i.vTextureCoords3.xy);
4026   //   ps_output.vColor = c;
4027   //   return ps_output;
4028   // }
4029 
4030   const std::string text = R"(
4031                OpCapability Shader
4032           %1 = OpExtInstImport "OpenCL.DebugInfo.100"
4033                OpMemoryModel Logical GLSL450
4034                OpEntryPoint Fragment %MainPs "MainPs" %g_tColor %g_sAniso %in_var_TEXCOORD2 %in_var_TEXCOORD3 %out_var_SV_Target0
4035                OpExecutionMode %MainPs OriginUpperLeft
4036          %22 = OpString "foo.frag"
4037          %26 = OpString "PS_OUTPUT"
4038          %30 = OpString "float"
4039          %33 = OpString "vColor"
4040          %35 = OpString "PS_INPUT"
4041          %40 = OpString "vTextureCoords3"
4042          %42 = OpString "vTextureCoords2"
4043          %44 = OpString "@type.2d.image"
4044          %45 = OpString "type.2d.image"
4045          %47 = OpString "Texture2D.TemplateParam"
4046          %51 = OpString "src.MainPs"
4047          %55 = OpString "c"
4048          %57 = OpString "ps_output"
4049          %60 = OpString "i"
4050          %62 = OpString "@type.sampler"
4051          %63 = OpString "type.sampler"
4052          %65 = OpString "g_sAniso"
4053          %67 = OpString "g_tColor"
4054                OpName %type_2d_image "type.2d.image"
4055                OpName %g_tColor "g_tColor"
4056                OpName %type_sampler "type.sampler"
4057                OpName %g_sAniso "g_sAniso"
4058                OpName %in_var_TEXCOORD2 "in.var.TEXCOORD2"
4059                OpName %in_var_TEXCOORD3 "in.var.TEXCOORD3"
4060                OpName %out_var_SV_Target0 "out.var.SV_Target0"
4061                OpName %MainPs "MainPs"
4062                OpName %PS_INPUT "PS_INPUT"
4063                OpMemberName %PS_INPUT 0 "vTextureCoords2"
4064                OpMemberName %PS_INPUT 1 "vTextureCoords3"
4065                OpName %param_var_i "param.var.i"
4066                OpName %PS_OUTPUT "PS_OUTPUT"
4067                OpMemberName %PS_OUTPUT 0 "vColor"
4068                OpName %type_sampled_image "type.sampled.image"
4069                OpDecorate %in_var_TEXCOORD2 Location 0
4070                OpDecorate %in_var_TEXCOORD3 Location 1
4071                OpDecorate %out_var_SV_Target0 Location 0
4072                OpDecorate %g_tColor DescriptorSet 0
4073                OpDecorate %g_tColor Binding 0
4074                OpDecorate %g_sAniso DescriptorSet 0
4075                OpDecorate %g_sAniso Binding 1
4076         %int = OpTypeInt 32 1
4077       %int_0 = OpConstant %int 0
4078       %int_1 = OpConstant %int 1
4079        %uint = OpTypeInt 32 0
4080     %uint_32 = OpConstant %uint 32
4081       %float = OpTypeFloat 32
4082 %type_2d_image = OpTypeImage %float 2D 2 0 0 1 Unknown
4083 %_ptr_UniformConstant_type_2d_image = OpTypePointer UniformConstant %type_2d_image
4084 %type_sampler = OpTypeSampler
4085 %_ptr_UniformConstant_type_sampler = OpTypePointer UniformConstant %type_sampler
4086     %v2float = OpTypeVector %float 2
4087 %_ptr_Input_v2float = OpTypePointer Input %v2float
4088     %v4float = OpTypeVector %float 4
4089 %_ptr_Output_v4float = OpTypePointer Output %v4float
4090        %void = OpTypeVoid
4091    %uint_128 = OpConstant %uint 128
4092      %uint_0 = OpConstant %uint 0
4093     %uint_64 = OpConstant %uint 64
4094          %69 = OpTypeFunction %void
4095    %PS_INPUT = OpTypeStruct %v2float %v2float
4096 %_ptr_Function_PS_INPUT = OpTypePointer Function %PS_INPUT
4097   %PS_OUTPUT = OpTypeStruct %v4float
4098 %_ptr_Function_PS_OUTPUT = OpTypePointer Function %PS_OUTPUT
4099 %_ptr_Function_v4float = OpTypePointer Function %v4float
4100 %_ptr_Function_v2float = OpTypePointer Function %v2float
4101 %type_sampled_image = OpTypeSampledImage %type_2d_image
4102    %g_tColor = OpVariable %_ptr_UniformConstant_type_2d_image UniformConstant
4103    %g_sAniso = OpVariable %_ptr_UniformConstant_type_sampler UniformConstant
4104 %in_var_TEXCOORD2 = OpVariable %_ptr_Input_v2float Input
4105 %in_var_TEXCOORD3 = OpVariable %_ptr_Input_v2float Input
4106 %out_var_SV_Target0 = OpVariable %_ptr_Output_v4float Output
4107          %43 = OpExtInst %void %1 DebugInfoNone
4108          %59 = OpExtInst %void %1 DebugExpression
4109          %24 = OpExtInst %void %1 DebugSource %22
4110          %25 = OpExtInst %void %1 DebugCompilationUnit 1 4 %24 HLSL
4111          %28 = OpExtInst %void %1 DebugTypeComposite %26 Structure %24 11 1 %25 %26 %uint_128 FlagIsProtected|FlagIsPrivate %29
4112          %31 = OpExtInst %void %1 DebugTypeBasic %30 %uint_32 Float
4113          %32 = OpExtInst %void %1 DebugTypeVector %31 4
4114          %29 = OpExtInst %void %1 DebugTypeMember %33 %32 %24 13 5 %28 %uint_0 %uint_128 FlagIsProtected|FlagIsPrivate
4115          %36 = OpExtInst %void %1 DebugTypeComposite %35 Structure %24 5 1 %25 %35 %uint_128 FlagIsProtected|FlagIsPrivate %37 %38
4116          %39 = OpExtInst %void %1 DebugTypeVector %31 2
4117          %38 = OpExtInst %void %1 DebugTypeMember %40 %39 %24 8 5 %36 %uint_64 %uint_64 FlagIsProtected|FlagIsPrivate
4118          %37 = OpExtInst %void %1 DebugTypeMember %42 %39 %24 7 5 %36 %uint_0 %uint_64 FlagIsProtected|FlagIsPrivate
4119          %46 = OpExtInst %void %1 DebugTypeComposite %44 Class %24 0 0 %25 %45 %43 FlagIsProtected|FlagIsPrivate
4120          %50 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %28 %36
4121          %52 = OpExtInst %void %1 DebugFunction %51 %50 %24 16 1 %25 %51 FlagIsProtected|FlagIsPrivate 17 %43
4122          %54 = OpExtInst %void %1 DebugLexicalBlock %24 17 1 %52
4123          %56 = OpExtInst %void %1 DebugLocalVariable %55 %32 %24 20 12 %54 FlagIsLocal
4124          %58 = OpExtInst %void %1 DebugLocalVariable %57 %28 %24 18 15 %54 FlagIsLocal
4125          %61 = OpExtInst %void %1 DebugLocalVariable %60 %36 %24 16 29 %52 FlagIsLocal 1
4126          %64 = OpExtInst %void %1 DebugTypeComposite %62 Structure %24 0 0 %25 %63 %43 FlagIsProtected|FlagIsPrivate
4127          %66 = OpExtInst %void %1 DebugGlobalVariable %65 %64 %24 3 14 %25 %65 %g_sAniso FlagIsDefinition
4128          %68 = OpExtInst %void %1 DebugGlobalVariable %67 %46 %24 1 11 %25 %67 %g_tColor FlagIsDefinition
4129      %MainPs = OpFunction %void None %69
4130          %70 = OpLabel
4131         %135 = OpExtInst %void %1 DebugScope %54
4132         %111 = OpVariable %_ptr_Function_PS_OUTPUT Function
4133         %112 = OpVariable %_ptr_Function_v4float Function
4134         %136 = OpExtInst %void %1 DebugNoScope
4135 %param_var_i = OpVariable %_ptr_Function_PS_INPUT Function
4136          %74 = OpLoad %v2float %in_var_TEXCOORD2
4137          %75 = OpLoad %v2float %in_var_TEXCOORD3
4138          %76 = OpCompositeConstruct %PS_INPUT %74 %75
4139                OpStore %param_var_i %76
4140         %137 = OpExtInst %void %1 DebugScope %52
4141         %115 = OpExtInst %void %1 DebugDeclare %61 %param_var_i %59
4142         %138 = OpExtInst %void %1 DebugScope %54
4143         %116 = OpExtInst %void %1 DebugDeclare %58 %111 %59
4144         %117 = OpExtInst %void %1 DebugDeclare %56 %112 %59
4145 ;CHECK-NOT: %117 = OpExtInst %void %1 DebugDeclare %56 %112 %59
4146                OpLine %22 21 9
4147         %118 = OpLoad %type_2d_image %g_tColor
4148                OpLine %22 21 29
4149         %119 = OpLoad %type_sampler %g_sAniso
4150                OpLine %22 21 40
4151         %120 = OpAccessChain %_ptr_Function_v2float %param_var_i %int_0
4152         %121 = OpLoad %v2float %120
4153                OpLine %22 21 9
4154         %122 = OpSampledImage %type_sampled_image %118 %119
4155         %123 = OpImageSampleImplicitLod %v4float %122 %121 None
4156                OpLine %22 21 5
4157                OpStore %112 %123
4158 ;CHECK: %140 = OpExtInst %void %1 DebugValue %56 %123 %59
4159                OpLine %22 22 10
4160         %124 = OpLoad %type_2d_image %g_tColor
4161                OpLine %22 22 30
4162         %125 = OpLoad %type_sampler %g_sAniso
4163                OpLine %22 22 41
4164         %126 = OpAccessChain %_ptr_Function_v2float %param_var_i %int_1
4165         %127 = OpLoad %v2float %126
4166                OpLine %22 22 10
4167         %128 = OpSampledImage %type_sampled_image %124 %125
4168         %129 = OpImageSampleImplicitLod %v4float %128 %127 None
4169                OpLine %22 22 7
4170         %131 = OpFAdd %v4float %123 %129
4171                OpLine %22 22 5
4172                OpStore %112 %131
4173 ;CHECK: %141 = OpExtInst %void %1 DebugValue %56 %131 %59
4174                OpLine %22 23 5
4175         %133 = OpAccessChain %_ptr_Function_v4float %111 %int_0
4176                OpStore %133 %131
4177                OpLine %22 24 12
4178         %134 = OpLoad %PS_OUTPUT %111
4179         %139 = OpExtInst %void %1 DebugNoScope
4180          %79 = OpCompositeExtract %v4float %134 0
4181                OpStore %out_var_SV_Target0 %79
4182                OpReturn
4183                OpFunctionEnd
4184 )";
4185 
4186   SetTargetEnv(SPV_ENV_VULKAN_1_2);
4187   SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
4188   SinglePassRunAndMatch<SSARewritePass>(text, true);
4189 }
4190 
4191 // Check support for pointer variables. When pointer variables are used, the
4192 // computation of reaching definitions may need to follow pointer chains.
4193 // See https://github.com/KhronosGroup/SPIRV-Tools/issues/3873 for details.
TEST_F(LocalSSAElimTest,PointerVariables)4194 TEST_F(LocalSSAElimTest, PointerVariables) {
4195   const std::string text = R"(
4196                OpCapability Shader
4197                OpCapability VariablePointers
4198                OpExtension "SPV_KHR_variable_pointers"
4199                OpMemoryModel Logical Simple
4200                OpEntryPoint Fragment %1 "main" %2 %3
4201                OpExecutionMode %1 OriginUpperLeft
4202       %float = OpTypeFloat 32
4203        %void = OpTypeVoid
4204           %6 = OpTypeFunction %void
4205 %_ptr_Input_float = OpTypePointer Input %float
4206 %_ptr_Output_float = OpTypePointer Output %float
4207 %_ptr_Function__ptr_Input_float = OpTypePointer Function %_ptr_Input_float
4208           %2 = OpVariable %_ptr_Input_float Input
4209           %3 = OpVariable %_ptr_Output_float Output
4210           %1 = OpFunction %void None %6
4211          %10 = OpLabel
4212          %11 = OpVariable %_ptr_Function__ptr_Input_float Function
4213                OpStore %11 %2
4214 
4215 ; CHECK-NOT: %12 = OpLoad %_ptr_Input_float %11
4216          %12 = OpLoad %_ptr_Input_float %11
4217 
4218 ; CHECK: %13 = OpLoad %float %2
4219          %13 = OpLoad %float %12
4220 
4221                OpStore %3 %13
4222                OpReturn
4223                OpFunctionEnd
4224 )";
4225 
4226   SinglePassRunAndMatch<SSARewritePass>(text, true);
4227 }
4228 
TEST_F(LocalSSAElimTest,FunctionDeclaration)4229 TEST_F(LocalSSAElimTest, FunctionDeclaration) {
4230   // Make sure the pass works with a function declaration that is called.
4231   const std::string text = R"(OpCapability Addresses
4232 OpCapability Linkage
4233 OpCapability Kernel
4234 OpCapability Int8
4235 %1 = OpExtInstImport "OpenCL.std"
4236 OpMemoryModel Physical64 OpenCL
4237 OpEntryPoint Kernel %2 "_Z23julia__1166_kernel_77094Bool"
4238 OpExecutionMode %2 ContractionOff
4239 OpSource Unknown 0
4240 OpDecorate %3 LinkageAttributes "julia_error_7712" Import
4241 %void = OpTypeVoid
4242 %5 = OpTypeFunction %void
4243 %3 = OpFunction %void None %5
4244 OpFunctionEnd
4245 %2 = OpFunction %void None %5
4246 %6 = OpLabel
4247 %7 = OpFunctionCall %void %3
4248 OpReturn
4249 OpFunctionEnd
4250 )";
4251 
4252   SinglePassRunAndCheck<SSARewritePass>(text, text, false);
4253 }
4254 
TEST_F(LocalSSAElimTest,MissingDebugValue)4255 TEST_F(LocalSSAElimTest, MissingDebugValue) {
4256   // Make sure DebugValue for final fragcolor assignment is generated.
4257 
4258   const std::string text =
4259       R"(
4260                OpCapability Shader
4261                OpCapability ImageQuery
4262                OpExtension "SPV_KHR_non_semantic_info"
4263           %1 = OpExtInstImport "GLSL.std.450"
4264           %2 = OpExtInstImport "NonSemantic.Shader.DebugInfo.100"
4265                OpMemoryModel Logical GLSL450
4266                OpEntryPoint Fragment %main "main" %in_var_TEXCOORD0 %out_var_SV_TARGET %textureposition %samplerposition %textureNormal %samplerNormal %textureAlbedo %samplerAlbedo %textureShadowMap %samplerShadowMap %ubo
4267                OpExecutionMode %main OriginUpperLeft
4268          %15 = OpString "d2.frag"
4269          %55 = OpString "float"
4270          %63 = OpString "// Copyright 2020 Google LLC
4271 
4272 Texture2D textureposition : register(t1);
4273 SamplerState samplerposition : register(s1);
4274 Texture2D textureNormal : register(t2);
4275 SamplerState samplerNormal : register(s2);
4276 Texture2D textureAlbedo : register(t3);
4277 SamplerState samplerAlbedo : register(s3);
4278 // Depth from the light's point of view
4279 //layout (binding = 5) uniform sampler2DShadow samplerShadowMap;
4280 Texture2DArray textureShadowMap : register(t5);
4281 SamplerState samplerShadowMap : register(s5);
4282 
4283 #define LIGHT_COUNT 3
4284 #define SHADOW_FACTOR 0.25
4285 #define AMBIENT_LIGHT 0.1
4286 #define USE_PCF
4287 
4288 struct Light
4289 {
4290 	float4 position;
4291 	float4 target;
4292 	float4 color;
4293 	float4x4 viewMatrix;
4294 };
4295 
4296 struct UBO
4297 {
4298 	float4 viewPos;
4299 	Light lights[LIGHT_COUNT];
4300 	int useShadows;
4301 	int displayDebugTarget;
4302 };
4303 
4304 cbuffer ubo : register(b4) { UBO ubo; }
4305 
4306 float textureProj(float4 P, float layer, float2 offset)
4307 {
4308 	float shadow = 1.0;
4309 	float4 shadowCoord = P / P.w;
4310 	shadowCoord.xy = shadowCoord.xy * 0.5 + 0.5;
4311 
4312 	if (shadowCoord.z > -1.0 && shadowCoord.z < 1.0)
4313 	{
4314 		float dist = textureShadowMap.Sample(samplerShadowMap, float3(shadowCoord.xy + offset, layer)).r;
4315 		if (shadowCoord.w > 0.0 && dist < shadowCoord.z)
4316 		{
4317 			shadow = SHADOW_FACTOR;
4318 		}
4319 	}
4320 	return shadow;
4321 }
4322 
4323 float filterPCF(float4 sc, float layer)
4324 {
4325 	int2 texDim; int elements; int levels;
4326 	textureShadowMap.GetDimensions(0, texDim.x, texDim.y, elements, levels);
4327 	float scale = 1.5;
4328 	float dx = scale * 1.0 / float(texDim.x);
4329 	float dy = scale * 1.0 / float(texDim.y);
4330 
4331 	float shadowFactor = 0.0;
4332 	int count = 0;
4333 	int range = 1;
4334 
4335 	for (int x = -range; x <= range; x++)
4336 	{
4337 		for (int y = -range; y <= range; y++)
4338 		{
4339 			shadowFactor += textureProj(sc, layer, float2(dx*x, dy*y));
4340 			count++;
4341 		}
4342 
4343 	}
4344 	return shadowFactor / count;
4345 }
4346 
4347 float3 shadow(float3 fragcolor, float3 fragPos) {
4348 	for (int i = 0; i < LIGHT_COUNT; ++i)
4349 	{
4350 		float4 shadowClip = mul(ubo.lights[i].viewMatrix, float4(fragPos.xyz, 1.0));
4351 
4352 		float shadowFactor;
4353 		#ifdef USE_PCF
4354 			shadowFactor= filterPCF(shadowClip, i);
4355 		#else
4356 			shadowFactor = textureProj(shadowClip, i, float2(0.0, 0.0));
4357 		#endif
4358 
4359 		fragcolor *= shadowFactor;
4360 	}
4361 	return fragcolor;
4362 }
4363 
4364 float4 main([[vk::location(0)]] float2 inUV : TEXCOORD0) : SV_TARGET
4365 {
4366 	// Get G-Buffer values
4367 	float3 fragPos = textureposition.Sample(samplerposition, inUV).rgb;
4368 	float3 normal = textureNormal.Sample(samplerNormal, inUV).rgb;
4369 	float4 albedo = textureAlbedo.Sample(samplerAlbedo, inUV);
4370 
4371 	// Ambient part
4372 	float3 fragcolor  = albedo.rgb * AMBIENT_LIGHT;
4373 
4374 	float3 N = normalize(normal);
4375 
4376 	for(int i = 0; i < LIGHT_COUNT; ++i)
4377 	{
4378 		// Vector to light
4379 		float3 L = ubo.lights[i].position.xyz - fragPos;
4380 		// Distance from light to fragment position
4381 		float dist = length(L);
4382 		L = normalize(L);
4383 
4384 		// Viewer to fragment
4385 		float3 V = ubo.viewPos.xyz - fragPos;
4386 		V = normalize(V);
4387 
4388 		float lightCosInnerAngle = cos(radians(15.0));
4389 		float lightCosOuterAngle = cos(radians(25.0));
4390 		float lightRange = 100.0;
4391 
4392 		// Direction vector from source to target
4393 		float3 dir = normalize(ubo.lights[i].position.xyz - ubo.lights[i].target.xyz);
4394 
4395 		// Dual cone spot light with smooth transition between inner and outer angle
4396 		float cosDir = dot(L, dir);
4397 		float spotEffect = smoothstep(lightCosOuterAngle, lightCosInnerAngle, cosDir);
4398 		float heightAttenuation = smoothstep(lightRange, 0.0f, dist);
4399 
4400 		// Diffuse lighting
4401 		float NdotL = max(0.0, dot(N, L));
4402 		float3 diff = NdotL.xxx;
4403 
4404 		// Specular lighting
4405 		float3 R = reflect(-L, N);
4406 		float NdotR = max(0.0, dot(R, V));
4407 		float3 spec = (pow(NdotR, 16.0) * albedo.a * 2.5).xxx;
4408 
4409 		fragcolor += float3((diff + spec) * spotEffect * heightAttenuation) * ubo.lights[i].color.rgb * albedo.rgb;
4410 	}
4411 
4412 	// Shadow calculations in a separate pass
4413 	if (ubo.useShadows > 0)
4414 	{
4415 		fragcolor = shadow(fragcolor, fragPos);
4416 	}
4417 
4418 	return float4(fragcolor, 1);
4419 }
4420 "
4421          %68 = OpString "textureProj"
4422          %69 = OpString ""
4423          %78 = OpString "dist"
4424          %82 = OpString "shadowCoord"
4425          %85 = OpString "shadow"
4426          %89 = OpString "offset"
4427          %92 = OpString "layer"
4428          %95 = OpString "P"
4429          %99 = OpString "filterPCF"
4430         %108 = OpString "int"
4431         %110 = OpString "y"
4432         %114 = OpString "x"
4433         %118 = OpString "range"
4434         %122 = OpString "count"
4435         %125 = OpString "shadowFactor"
4436         %128 = OpString "dy"
4437         %131 = OpString "dx"
4438         %134 = OpString "scale"
4439         %137 = OpString "levels"
4440         %141 = OpString "elements"
4441         %145 = OpString "texDim"
4442         %150 = OpString "sc"
4443         %162 = OpString "shadowClip"
4444         %166 = OpString "i"
4445         %169 = OpString "fragPos"
4446         %171 = OpString "fragcolor"
4447         %175 = OpString "main"
4448         %184 = OpString "spec"
4449         %187 = OpString "NdotR"
4450         %190 = OpString "R"
4451         %193 = OpString "diff"
4452         %196 = OpString "NdotL"
4453         %199 = OpString "heightAttenuation"
4454         %202 = OpString "spotEffect"
4455         %205 = OpString "cosDir"
4456         %208 = OpString "dir"
4457         %211 = OpString "lightRange"
4458         %214 = OpString "lightCosOuterAngle"
4459         %217 = OpString "lightCosInnerAngle"
4460         %220 = OpString "V"
4461         %225 = OpString "L"
4462         %230 = OpString "N"
4463         %235 = OpString "albedo"
4464         %238 = OpString "normal"
4465         %244 = OpString "inUV"
4466         %246 = OpString "viewPos"
4467         %249 = OpString "position"
4468         %252 = OpString "target"
4469         %254 = OpString "color"
4470         %259 = OpString "viewMatrix"
4471         %263 = OpString "Light"
4472         %267 = OpString "lights"
4473         %271 = OpString "useShadows"
4474         %275 = OpString "displayDebugTarget"
4475         %278 = OpString "UBO"
4476         %282 = OpString "ubo"
4477         %285 = OpString "type.ubo"
4478         %289 = OpString "@type.sampler"
4479         %290 = OpString "type.sampler"
4480         %292 = OpString "samplerShadowMap"
4481         %295 = OpString "@type.2d.image.array"
4482         %296 = OpString "type.2d.image.array"
4483         %298 = OpString "TemplateParam"
4484         %301 = OpString "textureShadowMap"
4485         %304 = OpString "samplerAlbedo"
4486         %306 = OpString "@type.2d.image"
4487         %307 = OpString "type.2d.image"
4488         %311 = OpString "textureAlbedo"
4489         %313 = OpString "samplerNormal"
4490         %315 = OpString "textureNormal"
4491         %317 = OpString "samplerposition"
4492         %319 = OpString "textureposition"
4493                OpName %type_2d_image "type.2d.image"
4494                OpName %textureposition "textureposition"
4495                OpName %type_sampler "type.sampler"
4496                OpName %samplerposition "samplerposition"
4497                OpName %textureNormal "textureNormal"
4498                OpName %samplerNormal "samplerNormal"
4499                OpName %textureAlbedo "textureAlbedo"
4500                OpName %samplerAlbedo "samplerAlbedo"
4501                OpName %type_2d_image_array "type.2d.image.array"
4502                OpName %textureShadowMap "textureShadowMap"
4503                OpName %samplerShadowMap "samplerShadowMap"
4504                OpName %type_ubo "type.ubo"
4505                OpMemberName %type_ubo 0 "ubo"
4506                OpName %UBO "UBO"
4507                OpMemberName %UBO 0 "viewPos"
4508                OpMemberName %UBO 1 "lights"
4509                OpMemberName %UBO 2 "useShadows"
4510                OpMemberName %UBO 3 "displayDebugTarget"
4511                OpName %Light "Light"
4512                OpMemberName %Light 0 "position"
4513                OpMemberName %Light 1 "target"
4514                OpMemberName %Light 2 "color"
4515                OpMemberName %Light 3 "viewMatrix"
4516                OpName %ubo "ubo"
4517                OpName %in_var_TEXCOORD0 "in.var.TEXCOORD0"
4518                OpName %out_var_SV_TARGET "out.var.SV_TARGET"
4519                OpName %main "main"
4520                OpName %param_var_inUV "param.var.inUV"
4521                OpName %type_sampled_image "type.sampled.image"
4522                OpName %type_sampled_image_0 "type.sampled.image"
4523                OpDecorate %in_var_TEXCOORD0 Location 0
4524                OpDecorate %out_var_SV_TARGET Location 0
4525                OpDecorate %textureposition DescriptorSet 0
4526                OpDecorate %textureposition Binding 1
4527                OpDecorate %samplerposition DescriptorSet 0
4528                OpDecorate %samplerposition Binding 1
4529                OpDecorate %textureNormal DescriptorSet 0
4530                OpDecorate %textureNormal Binding 2
4531                OpDecorate %samplerNormal DescriptorSet 0
4532                OpDecorate %samplerNormal Binding 2
4533                OpDecorate %textureAlbedo DescriptorSet 0
4534                OpDecorate %textureAlbedo Binding 3
4535                OpDecorate %samplerAlbedo DescriptorSet 0
4536                OpDecorate %samplerAlbedo Binding 3
4537                OpDecorate %textureShadowMap DescriptorSet 0
4538                OpDecorate %textureShadowMap Binding 5
4539                OpDecorate %samplerShadowMap DescriptorSet 0
4540                OpDecorate %samplerShadowMap Binding 5
4541                OpDecorate %ubo DescriptorSet 0
4542                OpDecorate %ubo Binding 4
4543                OpMemberDecorate %Light 0 Offset 0
4544                OpMemberDecorate %Light 1 Offset 16
4545                OpMemberDecorate %Light 2 Offset 32
4546                OpMemberDecorate %Light 3 Offset 48
4547                OpMemberDecorate %Light 3 MatrixStride 16
4548                OpMemberDecorate %Light 3 RowMajor
4549                OpDecorate %_arr_Light_uint_3 ArrayStride 112
4550                OpMemberDecorate %UBO 0 Offset 0
4551                OpMemberDecorate %UBO 1 Offset 16
4552                OpMemberDecorate %UBO 2 Offset 352
4553                OpMemberDecorate %UBO 3 Offset 356
4554                OpMemberDecorate %type_ubo 0 Offset 0
4555                OpDecorate %type_ubo Block
4556 )"
4557       R"(   %float = OpTypeFloat 32
4558 %float_0_100000001 = OpConstant %float 0.100000001
4559         %int = OpTypeInt 32 1
4560       %int_0 = OpConstant %int 0
4561       %int_3 = OpConstant %int 3
4562       %int_1 = OpConstant %int 1
4563    %float_15 = OpConstant %float 15
4564    %float_25 = OpConstant %float 25
4565   %float_100 = OpConstant %float 100
4566     %float_0 = OpConstant %float 0
4567    %float_16 = OpConstant %float 16
4568   %float_2_5 = OpConstant %float 2.5
4569       %int_2 = OpConstant %int 2
4570     %float_1 = OpConstant %float 1
4571        %uint = OpTypeInt 32 0
4572      %uint_0 = OpConstant %uint 0
4573   %float_1_5 = OpConstant %float 1.5
4574   %float_0_5 = OpConstant %float 0.5
4575     %v2float = OpTypeVector %float 2
4576          %35 = OpConstantComposite %v2float %float_0_5 %float_0_5
4577    %float_n1 = OpConstant %float -1
4578  %float_0_25 = OpConstant %float 0.25
4579     %uint_32 = OpConstant %uint 32
4580 %type_2d_image = OpTypeImage %float 2D 2 0 0 1 Unknown
4581 %_ptr_UniformConstant_type_2d_image = OpTypePointer UniformConstant %type_2d_image
4582 %type_sampler = OpTypeSampler
4583 %_ptr_UniformConstant_type_sampler = OpTypePointer UniformConstant %type_sampler
4584 %type_2d_image_array = OpTypeImage %float 2D 2 1 0 1 Unknown
4585 %_ptr_UniformConstant_type_2d_image_array = OpTypePointer UniformConstant %type_2d_image_array
4586     %v4float = OpTypeVector %float 4
4587      %uint_3 = OpConstant %uint 3
4588 %mat4v4float = OpTypeMatrix %v4float 4
4589       %Light = OpTypeStruct %v4float %v4float %v4float %mat4v4float
4590 %_arr_Light_uint_3 = OpTypeArray %Light %uint_3
4591         %UBO = OpTypeStruct %v4float %_arr_Light_uint_3 %int %int
4592    %type_ubo = OpTypeStruct %UBO
4593 %_ptr_Uniform_type_ubo = OpTypePointer Uniform %type_ubo
4594 %_ptr_Input_v2float = OpTypePointer Input %v2float
4595 %_ptr_Output_v4float = OpTypePointer Output %v4float
4596        %void = OpTypeVoid
4597      %uint_4 = OpConstant %uint 4
4598      %uint_2 = OpConstant %uint 2
4599      %uint_1 = OpConstant %uint 1
4600      %uint_5 = OpConstant %uint 5
4601     %uint_37 = OpConstant %uint 37
4602     %uint_38 = OpConstant %uint 38
4603     %uint_44 = OpConstant %uint 44
4604     %uint_47 = OpConstant %uint 47
4605     %uint_45 = OpConstant %uint 45
4606      %uint_9 = OpConstant %uint 9
4607     %uint_40 = OpConstant %uint 40
4608     %uint_39 = OpConstant %uint 39
4609      %uint_8 = OpConstant %uint 8
4610     %uint_49 = OpConstant %uint 49
4611     %uint_35 = OpConstant %uint 35
4612     %uint_26 = OpConstant %uint 26
4613     %uint_54 = OpConstant %uint 54
4614     %uint_55 = OpConstant %uint 55
4615     %uint_67 = OpConstant %uint 67
4616     %uint_69 = OpConstant %uint 69
4617     %uint_68 = OpConstant %uint 68
4618     %uint_12 = OpConstant %uint 12
4619     %uint_66 = OpConstant %uint 66
4620     %uint_11 = OpConstant %uint 11
4621     %uint_64 = OpConstant %uint 64
4622      %uint_6 = OpConstant %uint 6
4623     %uint_63 = OpConstant %uint 63
4624     %uint_62 = OpConstant %uint 62
4625     %uint_60 = OpConstant %uint 60
4626     %uint_59 = OpConstant %uint 59
4627     %uint_58 = OpConstant %uint 58
4628     %uint_56 = OpConstant %uint 56
4629     %uint_33 = OpConstant %uint 33
4630     %uint_19 = OpConstant %uint 19
4631      %uint_7 = OpConstant %uint 7
4632     %uint_34 = OpConstant %uint 34
4633     %uint_24 = OpConstant %uint 24
4634     %uint_78 = OpConstant %uint 78
4635     %uint_80 = OpConstant %uint 80
4636     %uint_83 = OpConstant %uint 83
4637     %uint_81 = OpConstant %uint 81
4638     %uint_10 = OpConstant %uint 10
4639     %uint_79 = OpConstant %uint 79
4640     %uint_22 = OpConstant %uint 22
4641     %uint_95 = OpConstant %uint 95
4642     %uint_96 = OpConstant %uint 96
4643    %uint_145 = OpConstant %uint 145
4644    %uint_108 = OpConstant %uint 108
4645    %uint_138 = OpConstant %uint 138
4646    %uint_137 = OpConstant %uint 137
4647    %uint_136 = OpConstant %uint 136
4648    %uint_133 = OpConstant %uint 133
4649    %uint_132 = OpConstant %uint 132
4650    %uint_129 = OpConstant %uint 129
4651    %uint_128 = OpConstant %uint 128
4652    %uint_127 = OpConstant %uint 127
4653    %uint_124 = OpConstant %uint 124
4654    %uint_121 = OpConstant %uint 121
4655    %uint_120 = OpConstant %uint 120
4656    %uint_119 = OpConstant %uint 119
4657    %uint_116 = OpConstant %uint 116
4658    %uint_112 = OpConstant %uint 112
4659    %uint_110 = OpConstant %uint 110
4660    %uint_107 = OpConstant %uint 107
4661    %uint_105 = OpConstant %uint 105
4662    %uint_103 = OpConstant %uint 103
4663    %uint_100 = OpConstant %uint 100
4664     %uint_99 = OpConstant %uint 99
4665     %uint_98 = OpConstant %uint 98
4666     %uint_29 = OpConstant %uint 29
4667     %uint_21 = OpConstant %uint 21
4668    %uint_256 = OpConstant %uint 256
4669     %uint_23 = OpConstant %uint 23
4670    %uint_384 = OpConstant %uint 384
4671    %uint_512 = OpConstant %uint 512
4672    %uint_896 = OpConstant %uint 896
4673   %uint_2688 = OpConstant %uint 2688
4674     %uint_30 = OpConstant %uint 30
4675   %uint_2816 = OpConstant %uint 2816
4676     %uint_31 = OpConstant %uint 31
4677   %uint_2848 = OpConstant %uint 2848
4678   %uint_2880 = OpConstant %uint 2880
4679     %uint_27 = OpConstant %uint 27
4680   %uint_2944 = OpConstant %uint 2944
4681     %uint_14 = OpConstant %uint 14
4682     %uint_16 = OpConstant %uint 16
4683         %321 = OpTypeFunction %void
4684 %_ptr_Function_v2float = OpTypePointer Function %v2float
4685    %uint_150 = OpConstant %uint 150
4686     %v3float = OpTypeVector %float 3
4687 %_ptr_Function_v3float = OpTypePointer Function %v3float
4688 %_ptr_Function_v4float = OpTypePointer Function %v4float
4689 %_ptr_Function_int = OpTypePointer Function %int
4690 %_ptr_Function_float = OpTypePointer Function %float
4691     %uint_42 = OpConstant %uint 42
4692 %type_sampled_image = OpTypeSampledImage %type_2d_image
4693     %uint_65 = OpConstant %uint 65
4694     %uint_18 = OpConstant %uint 18
4695     %uint_13 = OpConstant %uint 13
4696     %uint_15 = OpConstant %uint 15
4697     %uint_17 = OpConstant %uint 17
4698        %bool = OpTypeBool
4699     %uint_25 = OpConstant %uint 25
4700 %_ptr_Uniform_UBO = OpTypePointer Uniform %UBO
4701 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
4702     %uint_28 = OpConstant %uint 28
4703     %uint_43 = OpConstant %uint 43
4704    %uint_113 = OpConstant %uint 113
4705    %uint_117 = OpConstant %uint 117
4706     %uint_46 = OpConstant %uint 46
4707     %uint_76 = OpConstant %uint 76
4708     %uint_53 = OpConstant %uint 53
4709     %uint_73 = OpConstant %uint 73
4710     %uint_48 = OpConstant %uint 48
4711    %uint_140 = OpConstant %uint 140
4712     %uint_52 = OpConstant %uint 52
4713     %uint_93 = OpConstant %uint 93
4714     %uint_87 = OpConstant %uint 87
4715    %uint_106 = OpConstant %uint 106
4716     %uint_36 = OpConstant %uint 36
4717    %uint_144 = OpConstant %uint 144
4718 %_ptr_Uniform_int = OpTypePointer Uniform %int
4719    %uint_146 = OpConstant %uint 146
4720    %uint_147 = OpConstant %uint 147
4721    %uint_149 = OpConstant %uint 149
4722     %uint_41 = OpConstant %uint 41
4723 %_ptr_Uniform_mat4v4float = OpTypePointer Uniform %mat4v4float
4724     %uint_77 = OpConstant %uint 77
4725     %uint_85 = OpConstant %uint 85
4726     %uint_90 = OpConstant %uint 90
4727     %uint_92 = OpConstant %uint 92
4728       %v2int = OpTypeVector %int 2
4729 %_ptr_Function_v2int = OpTypePointer Function %v2int
4730     %uint_57 = OpConstant %uint 57
4731      %v3uint = OpTypeVector %uint 3
4732     %uint_72 = OpConstant %uint 72
4733     %uint_70 = OpConstant %uint 70
4734     %uint_50 = OpConstant %uint 50
4735     %uint_61 = OpConstant %uint 61
4736     %uint_71 = OpConstant %uint 71
4737     %uint_75 = OpConstant %uint 75
4738     %uint_82 = OpConstant %uint 82
4739 %type_sampled_image_0 = OpTypeSampledImage %type_2d_image_array
4740     %uint_51 = OpConstant %uint 51
4741 %textureposition = OpVariable %_ptr_UniformConstant_type_2d_image UniformConstant
4742 %samplerposition = OpVariable %_ptr_UniformConstant_type_sampler UniformConstant
4743 %textureNormal = OpVariable %_ptr_UniformConstant_type_2d_image UniformConstant
4744 %samplerNormal = OpVariable %_ptr_UniformConstant_type_sampler UniformConstant
4745 %textureAlbedo = OpVariable %_ptr_UniformConstant_type_2d_image UniformConstant
4746 %samplerAlbedo = OpVariable %_ptr_UniformConstant_type_sampler UniformConstant
4747 %textureShadowMap = OpVariable %_ptr_UniformConstant_type_2d_image_array UniformConstant
4748 %samplerShadowMap = OpVariable %_ptr_UniformConstant_type_sampler UniformConstant
4749         %ubo = OpVariable %_ptr_Uniform_type_ubo Uniform
4750 %in_var_TEXCOORD0 = OpVariable %_ptr_Input_v2float Input
4751 %out_var_SV_TARGET = OpVariable %_ptr_Output_v4float Output
4752   %uint_1792 = OpConstant %uint 1792
4753   %uint_1869 = OpConstant %uint 1869
4754   %uint_2060 = OpConstant %uint 2060
4755         %288 = OpExtInst %void %2 DebugInfoNone
4756         %243 = OpExtInst %void %2 DebugExpression
4757          %57 = OpExtInst %void %2 DebugTypeBasic %55 %uint_32 %uint_3 %uint_0
4758          %58 = OpExtInst %void %2 DebugTypeVector %57 %uint_4
4759          %60 = OpExtInst %void %2 DebugTypeVector %57 %uint_2
4760          %62 = OpExtInst %void %2 DebugTypeFunction %uint_3 %57 %58 %57 %60
4761          %64 = OpExtInst %void %2 DebugSource %15 %63
4762          %65 = OpExtInst %void %2 DebugCompilationUnit %uint_1 %uint_4 %64 %uint_5
4763          %70 = OpExtInst %void %2 DebugFunction %68 %62 %64 %uint_37 %uint_1 %65 %69 %uint_3 %uint_38
4764          %73 = OpExtInst %void %2 DebugLexicalBlock %64 %uint_38 %uint_1 %70
4765          %74 = OpExtInst %void %2 DebugLexicalBlock %64 %uint_44 %uint_2 %73
4766          %76 = OpExtInst %void %2 DebugLexicalBlock %64 %uint_47 %uint_3 %74
4767          %79 = OpExtInst %void %2 DebugLocalVariable %78 %57 %64 %uint_45 %uint_9 %74 %uint_4
4768          %83 = OpExtInst %void %2 DebugLocalVariable %82 %58 %64 %uint_40 %uint_9 %73 %uint_4
4769          %86 = OpExtInst %void %2 DebugLocalVariable %85 %57 %64 %uint_39 %uint_8 %73 %uint_4
4770          %90 = OpExtInst %void %2 DebugLocalVariable %89 %60 %64 %uint_37 %uint_49 %70 %uint_4 %uint_3
4771          %93 = OpExtInst %void %2 DebugLocalVariable %92 %57 %64 %uint_37 %uint_35 %70 %uint_4 %uint_2
4772          %96 = OpExtInst %void %2 DebugLocalVariable %95 %58 %64 %uint_37 %uint_26 %70 %uint_4 %uint_1
4773          %98 = OpExtInst %void %2 DebugTypeFunction %uint_3 %57 %58 %57
4774         %100 = OpExtInst %void %2 DebugFunction %99 %98 %64 %uint_54 %uint_1 %65 %69 %uint_3 %uint_55
4775         %103 = OpExtInst %void %2 DebugLexicalBlock %64 %uint_55 %uint_1 %100
4776         %104 = OpExtInst %void %2 DebugLexicalBlock %64 %uint_67 %uint_2 %103
4777         %106 = OpExtInst %void %2 DebugLexicalBlock %64 %uint_69 %uint_3 %104
4778         %109 = OpExtInst %void %2 DebugTypeBasic %108 %uint_32 %uint_4 %uint_0
4779         %111 = OpExtInst %void %2 DebugLocalVariable %110 %109 %64 %uint_68 %uint_12 %104 %uint_4
4780         %115 = OpExtInst %void %2 DebugLocalVariable %114 %109 %64 %uint_66 %uint_11 %103 %uint_4
4781         %119 = OpExtInst %void %2 DebugLocalVariable %118 %109 %64 %uint_64 %uint_6 %103 %uint_4
4782         %123 = OpExtInst %void %2 DebugLocalVariable %122 %109 %64 %uint_63 %uint_6 %103 %uint_4
4783         %126 = OpExtInst %void %2 DebugLocalVariable %125 %57 %64 %uint_62 %uint_8 %103 %uint_4
4784         %129 = OpExtInst %void %2 DebugLocalVariable %128 %57 %64 %uint_60 %uint_8 %103 %uint_4
4785         %132 = OpExtInst %void %2 DebugLocalVariable %131 %57 %64 %uint_59 %uint_8 %103 %uint_4
4786         %135 = OpExtInst %void %2 DebugLocalVariable %134 %57 %64 %uint_58 %uint_8 %103 %uint_4
4787         %138 = OpExtInst %void %2 DebugLocalVariable %137 %109 %64 %uint_56 %uint_33 %103 %uint_4
4788         %142 = OpExtInst %void %2 DebugLocalVariable %141 %109 %64 %uint_56 %uint_19 %103 %uint_4
4789         %144 = OpExtInst %void %2 DebugTypeVector %109 %uint_2
4790         %146 = OpExtInst %void %2 DebugLocalVariable %145 %144 %64 %uint_56 %uint_7 %103 %uint_4
4791         %148 = OpExtInst %void %2 DebugLocalVariable %92 %57 %64 %uint_54 %uint_34 %100 %uint_4 %uint_2
4792         %151 = OpExtInst %void %2 DebugLocalVariable %150 %58 %64 %uint_54 %uint_24 %100 %uint_4 %uint_1
4793         %153 = OpExtInst %void %2 DebugTypeVector %57 %uint_3
4794         %154 = OpExtInst %void %2 DebugTypeFunction %uint_3 %153 %153 %153
4795         %155 = OpExtInst %void %2 DebugFunction %85 %154 %64 %uint_78 %uint_1 %65 %69 %uint_3 %uint_78
4796         %157 = OpExtInst %void %2 DebugLexicalBlock %64 %uint_78 %uint_49 %155
4797         %158 = OpExtInst %void %2 DebugLexicalBlock %64 %uint_80 %uint_2 %157
4798         %160 = OpExtInst %void %2 DebugLocalVariable %125 %57 %64 %uint_83 %uint_9 %158 %uint_4
4799         %163 = OpExtInst %void %2 DebugLocalVariable %162 %58 %64 %uint_81 %uint_10 %158 %uint_4
4800         %167 = OpExtInst %void %2 DebugLocalVariable %166 %109 %64 %uint_79 %uint_11 %157 %uint_4
4801         %170 = OpExtInst %void %2 DebugLocalVariable %169 %153 %64 %uint_78 %uint_40 %155 %uint_4 %uint_2
4802         %172 = OpExtInst %void %2 DebugLocalVariable %171 %153 %64 %uint_78 %uint_22 %155 %uint_4 %uint_1
4803         %174 = OpExtInst %void %2 DebugTypeFunction %uint_3 %58 %60
4804         %176 = OpExtInst %void %2 DebugFunction %175 %174 %64 %uint_95 %uint_1 %65 %69 %uint_3 %uint_96
4805         %179 = OpExtInst %void %2 DebugLexicalBlock %64 %uint_96 %uint_1 %176
4806         %180 = OpExtInst %void %2 DebugLexicalBlock %64 %uint_145 %uint_2 %179
4807         %182 = OpExtInst %void %2 DebugLexicalBlock %64 %uint_108 %uint_2 %179
4808         %185 = OpExtInst %void %2 DebugLocalVariable %184 %153 %64 %uint_138 %uint_10 %182 %uint_4
4809         %188 = OpExtInst %void %2 DebugLocalVariable %187 %57 %64 %uint_137 %uint_9 %182 %uint_4
4810         %191 = OpExtInst %void %2 DebugLocalVariable %190 %153 %64 %uint_136 %uint_10 %182 %uint_4
4811         %194 = OpExtInst %void %2 DebugLocalVariable %193 %153 %64 %uint_133 %uint_10 %182 %uint_4
4812         %197 = OpExtInst %void %2 DebugLocalVariable %196 %57 %64 %uint_132 %uint_9 %182 %uint_4
4813         %200 = OpExtInst %void %2 DebugLocalVariable %199 %57 %64 %uint_129 %uint_9 %182 %uint_4
4814         %203 = OpExtInst %void %2 DebugLocalVariable %202 %57 %64 %uint_128 %uint_9 %182 %uint_4
4815         %206 = OpExtInst %void %2 DebugLocalVariable %205 %57 %64 %uint_127 %uint_9 %182 %uint_4
4816         %209 = OpExtInst %void %2 DebugLocalVariable %208 %153 %64 %uint_124 %uint_10 %182 %uint_4
4817         %212 = OpExtInst %void %2 DebugLocalVariable %211 %57 %64 %uint_121 %uint_9 %182 %uint_4
4818         %215 = OpExtInst %void %2 DebugLocalVariable %214 %57 %64 %uint_120 %uint_9 %182 %uint_4
4819         %218 = OpExtInst %void %2 DebugLocalVariable %217 %57 %64 %uint_119 %uint_9 %182 %uint_4
4820         %221 = OpExtInst %void %2 DebugLocalVariable %220 %153 %64 %uint_116 %uint_10 %182 %uint_4
4821         %223 = OpExtInst %void %2 DebugLocalVariable %78 %57 %64 %uint_112 %uint_9 %182 %uint_4
4822         %226 = OpExtInst %void %2 DebugLocalVariable %225 %153 %64 %uint_110 %uint_10 %182 %uint_4
4823         %228 = OpExtInst %void %2 DebugLocalVariable %166 %109 %64 %uint_107 %uint_10 %179 %uint_4
4824         %231 = OpExtInst %void %2 DebugLocalVariable %230 %153 %64 %uint_105 %uint_9 %179 %uint_4
4825         %233 = OpExtInst %void %2 DebugLocalVariable %171 %153 %64 %uint_103 %uint_9 %179 %uint_4
4826         %236 = OpExtInst %void %2 DebugLocalVariable %235 %58 %64 %uint_100 %uint_9 %179 %uint_4
4827         %239 = OpExtInst %void %2 DebugLocalVariable %238 %153 %64 %uint_99 %uint_9 %179 %uint_4
4828         %241 = OpExtInst %void %2 DebugLocalVariable %169 %153 %64 %uint_98 %uint_9 %179 %uint_4
4829         %245 = OpExtInst %void %2 DebugLocalVariable %244 %60 %64 %uint_95 %uint_40 %176 %uint_4 %uint_1
4830 )"
4831       R"(     %247 = OpExtInst %void %2 DebugTypeMember %246 %58 %64 %uint_29 %uint_9 %uint_0 %uint_128 %uint_3
4832         %250 = OpExtInst %void %2 DebugTypeMember %249 %58 %64 %uint_21 %uint_9 %uint_0 %uint_128 %uint_3
4833         %253 = OpExtInst %void %2 DebugTypeMember %252 %58 %64 %uint_22 %uint_9 %uint_128 %uint_128 %uint_3
4834         %256 = OpExtInst %void %2 DebugTypeMember %254 %58 %64 %uint_23 %uint_9 %uint_256 %uint_128 %uint_3
4835         %258 = OpExtInst %void %2 DebugTypeArray %57 %uint_4 %uint_4
4836         %262 = OpExtInst %void %2 DebugTypeMember %259 %258 %64 %uint_24 %uint_11 %uint_384 %uint_512 %uint_3
4837         %265 = OpExtInst %void %2 DebugTypeComposite %263 %uint_1 %64 %uint_19 %uint_8 %65 %263 %uint_896 %uint_3 %250 %253 %256 %262
4838         %266 = OpExtInst %void %2 DebugTypeArray %265 %uint_3
4839         %269 = OpExtInst %void %2 DebugTypeMember %267 %266 %64 %uint_30 %uint_8 %uint_128 %uint_2688 %uint_3
4840         %273 = OpExtInst %void %2 DebugTypeMember %271 %109 %64 %uint_31 %uint_6 %uint_2816 %uint_32 %uint_3
4841         %277 = OpExtInst %void %2 DebugTypeMember %275 %109 %64 %uint_32 %uint_6 %uint_2848 %uint_32 %uint_3
4842         %280 = OpExtInst %void %2 DebugTypeComposite %278 %uint_1 %64 %uint_27 %uint_8 %65 %278 %uint_2880 %uint_3 %247 %269 %273 %277
4843         %284 = OpExtInst %void %2 DebugTypeMember %282 %280 %64 %uint_35 %uint_34 %uint_0 %uint_2944 %uint_3
4844         %286 = OpExtInst %void %2 DebugTypeComposite %285 %uint_1 %64 %uint_35 %uint_9 %65 %285 %uint_2944 %uint_3 %284
4845         %287 = OpExtInst %void %2 DebugGlobalVariable %282 %286 %64 %uint_35 %uint_9 %65 %282 %ubo %uint_8
4846         %291 = OpExtInst %void %2 DebugTypeComposite %289 %uint_1 %64 %uint_0 %uint_0 %65 %290 %288 %uint_3
4847         %293 = OpExtInst %void %2 DebugGlobalVariable %292 %291 %64 %uint_12 %uint_14 %65 %292 %samplerShadowMap %uint_8
4848         %297 = OpExtInst %void %2 DebugTypeComposite %295 %uint_0 %64 %uint_0 %uint_0 %65 %296 %288 %uint_3
4849         %299 = OpExtInst %void %2 DebugTypeTemplateParameter %298 %58 %288 %64 %uint_0 %uint_0
4850         %300 = OpExtInst %void %2 DebugTypeTemplate %297 %299
4851         %302 = OpExtInst %void %2 DebugGlobalVariable %301 %300 %64 %uint_11 %uint_16 %65 %301 %textureShadowMap %uint_8
4852         %305 = OpExtInst %void %2 DebugGlobalVariable %304 %291 %64 %uint_8 %uint_14 %65 %304 %samplerAlbedo %uint_8
4853         %308 = OpExtInst %void %2 DebugTypeComposite %306 %uint_0 %64 %uint_0 %uint_0 %65 %307 %288 %uint_3
4854         %309 = OpExtInst %void %2 DebugTypeTemplateParameter %298 %58 %288 %64 %uint_0 %uint_0
4855         %310 = OpExtInst %void %2 DebugTypeTemplate %308 %309
4856         %312 = OpExtInst %void %2 DebugGlobalVariable %311 %310 %64 %uint_7 %uint_11 %65 %311 %textureAlbedo %uint_8
4857         %314 = OpExtInst %void %2 DebugGlobalVariable %313 %291 %64 %uint_6 %uint_14 %65 %313 %samplerNormal %uint_8
4858         %316 = OpExtInst %void %2 DebugGlobalVariable %315 %310 %64 %uint_5 %uint_11 %65 %315 %textureNormal %uint_8
4859         %318 = OpExtInst %void %2 DebugGlobalVariable %317 %291 %64 %uint_4 %uint_14 %65 %317 %samplerposition %uint_8
4860         %320 = OpExtInst %void %2 DebugGlobalVariable %319 %310 %64 %uint_3 %uint_11 %65 %319 %textureposition %uint_8
4861        %1803 = OpExtInst %void %2 DebugInlinedAt %uint_1792 %180
4862        %1885 = OpExtInst %void %2 DebugInlinedAt %uint_1869 %158 %1803
4863        %2085 = OpExtInst %void %2 DebugInlinedAt %uint_2060 %106 %1885
4864 )"
4865       R"(    %main = OpFunction %void None %321
4866         %322 = OpLabel
4867        %2083 = OpVariable %_ptr_Function_float Function
4868        %2086 = OpVariable %_ptr_Function_v4float Function
4869        %1883 = OpVariable %_ptr_Function_v2int Function
4870        %1891 = OpVariable %_ptr_Function_float Function
4871        %1892 = OpVariable %_ptr_Function_int Function
4872        %1894 = OpVariable %_ptr_Function_int Function
4873        %1895 = OpVariable %_ptr_Function_int Function
4874        %1896 = OpVariable %_ptr_Function_v4float Function
4875        %1801 = OpVariable %_ptr_Function_int Function
4876        %1447 = OpVariable %_ptr_Function_v4float Function
4877        %1448 = OpVariable %_ptr_Function_v3float Function
4878        %1450 = OpVariable %_ptr_Function_int Function
4879        %1451 = OpVariable %_ptr_Function_v3float Function
4880        %1453 = OpVariable %_ptr_Function_v3float Function
4881        %1466 = OpVariable %_ptr_Function_v3float Function
4882 %param_var_inUV = OpVariable %_ptr_Function_v2float Function
4883         %325 = OpExtInst %void %2 DebugFunctionDefinition %176 %main
4884         %326 = OpLoad %v2float %in_var_TEXCOORD0
4885                OpStore %param_var_inUV %326
4886        %2290 = OpExtInst %void %2 DebugScope %176
4887        %1620 = OpExtInst %void %2 DebugLine %64 %uint_95 %uint_95 %uint_33 %uint_40
4888        %1470 = OpExtInst %void %2 DebugDeclare %245 %param_var_inUV %243
4889        %2291 = OpExtInst %void %2 DebugScope %179
4890        %1621 = OpExtInst %void %2 DebugLine %64 %uint_98 %uint_98 %uint_19 %uint_19
4891        %1471 = OpLoad %type_2d_image %textureposition
4892        %1622 = OpExtInst %void %2 DebugLine %64 %uint_98 %uint_98 %uint_42 %uint_42
4893        %1472 = OpLoad %type_sampler %samplerposition
4894        %1624 = OpExtInst %void %2 DebugLine %64 %uint_98 %uint_98 %uint_19 %uint_63
4895        %1474 = OpSampledImage %type_sampled_image %1471 %1472
4896        %1475 = OpImageSampleImplicitLod %v4float %1474 %326 None
4897        %1626 = OpExtInst %void %2 DebugLine %64 %uint_98 %uint_98 %uint_19 %uint_65
4898        %1476 = OpVectorShuffle %v3float %1475 %1475 0 1 2
4899        %2241 = OpExtInst %void %2 DebugLine %64 %uint_98 %uint_98 %uint_2 %uint_65
4900        %2240 = OpExtInst %void %2 DebugValue %241 %1476 %243
4901        %1629 = OpExtInst %void %2 DebugLine %64 %uint_99 %uint_99 %uint_18 %uint_18
4902        %1478 = OpLoad %type_2d_image %textureNormal
4903        %1630 = OpExtInst %void %2 DebugLine %64 %uint_99 %uint_99 %uint_39 %uint_39
4904        %1479 = OpLoad %type_sampler %samplerNormal
4905        %1632 = OpExtInst %void %2 DebugLine %64 %uint_99 %uint_99 %uint_18 %uint_58
4906        %1481 = OpSampledImage %type_sampled_image %1478 %1479
4907        %1482 = OpImageSampleImplicitLod %v4float %1481 %326 None
4908        %1634 = OpExtInst %void %2 DebugLine %64 %uint_99 %uint_99 %uint_18 %uint_60
4909        %1483 = OpVectorShuffle %v3float %1482 %1482 0 1 2
4910        %2244 = OpExtInst %void %2 DebugLine %64 %uint_99 %uint_99 %uint_2 %uint_60
4911        %2243 = OpExtInst %void %2 DebugValue %239 %1483 %243
4912        %1637 = OpExtInst %void %2 DebugLine %64 %uint_100 %uint_100 %uint_18 %uint_18
4913        %1485 = OpLoad %type_2d_image %textureAlbedo
4914        %1638 = OpExtInst %void %2 DebugLine %64 %uint_100 %uint_100 %uint_39 %uint_39
4915        %1486 = OpLoad %type_sampler %samplerAlbedo
4916        %1640 = OpExtInst %void %2 DebugLine %64 %uint_100 %uint_100 %uint_18 %uint_58
4917        %1488 = OpSampledImage %type_sampled_image %1485 %1486
4918        %1489 = OpImageSampleImplicitLod %v4float %1488 %326 None
4919        %1642 = OpExtInst %void %2 DebugLine %64 %uint_100 %uint_100 %uint_2 %uint_58
4920                OpStore %1447 %1489
4921        %1490 = OpExtInst %void %2 DebugDeclare %236 %1447 %243
4922        %1645 = OpExtInst %void %2 DebugLine %64 %uint_103 %uint_103 %uint_22 %uint_29
4923        %1492 = OpVectorShuffle %v3float %1489 %1489 0 1 2
4924        %1646 = OpExtInst %void %2 DebugLine %64 %uint_103 %uint_103 %uint_22 %uint_35
4925        %1493 = OpVectorTimesScalar %v3float %1492 %float_0_100000001
4926        %1647 = OpExtInst %void %2 DebugLine %64 %uint_103 %uint_103 %uint_2 %uint_35
4927                OpStore %1448 %1493
4928        %1494 = OpExtInst %void %2 DebugDeclare %233 %1448 %243
4929        %1650 = OpExtInst %void %2 DebugLine %64 %uint_105 %uint_105 %uint_13 %uint_29
4930        %1496 = OpExtInst %v3float %1 Normalize %1483
4931        %2247 = OpExtInst %void %2 DebugLine %64 %uint_105 %uint_105 %uint_2 %uint_29
4932        %2246 = OpExtInst %void %2 DebugValue %231 %1496 %243
4933        %1653 = OpExtInst %void %2 DebugLine %64 %uint_107 %uint_107 %uint_6 %uint_14
4934                OpStore %1450 %int_0
4935        %1498 = OpExtInst %void %2 DebugDeclare %228 %1450 %243
4936        %1655 = OpExtInst %void %2 DebugLine %64 %uint_107 %uint_107 %uint_6 %uint_15
4937                OpBranch %1499
4938        %1499 = OpLabel
4939        %2292 = OpExtInst %void %2 DebugScope %179
4940        %1656 = OpExtInst %void %2 DebugLine %64 %uint_107 %uint_107 %uint_17 %uint_17
4941        %1500 = OpLoad %int %1450
4942        %1657 = OpExtInst %void %2 DebugLine %64 %uint_107 %uint_107 %uint_17 %uint_21
4943        %1501 = OpSLessThan %bool %1500 %int_3
4944        %2293 = OpExtInst %void %2 DebugNoScope
4945                OpLoopMerge %1605 %1602 None
4946                OpBranchConditional %1501 %1502 %1605
4947        %1502 = OpLabel
4948        %2294 = OpExtInst %void %2 DebugScope %182
4949        %1660 = OpExtInst %void %2 DebugLine %64 %uint_110 %uint_110 %uint_25 %uint_25
4950        %1503 = OpLoad %int %1450
4951        %1661 = OpExtInst %void %2 DebugLine %64 %uint_110 %uint_110 %uint_14 %uint_37
4952        %1504 = OpAccessChain %_ptr_Uniform_UBO %ubo %int_0
4953        %1505 = OpAccessChain %_ptr_Uniform_v4float %1504 %int_1 %1503 %int_0
4954        %1663 = OpExtInst %void %2 DebugLine %64 %uint_110 %uint_110 %uint_14 %uint_28
4955        %1506 = OpLoad %v4float %1505
4956        %1664 = OpExtInst %void %2 DebugLine %64 %uint_110 %uint_110 %uint_14 %uint_37
4957        %1507 = OpVectorShuffle %v3float %1506 %1506 0 1 2
4958        %1666 = OpExtInst %void %2 DebugLine %64 %uint_110 %uint_110 %uint_14 %uint_43
4959        %1509 = OpFSub %v3float %1507 %1476
4960        %1667 = OpExtInst %void %2 DebugLine %64 %uint_110 %uint_110 %uint_3 %uint_43
4961                OpStore %1451 %1509
4962        %1510 = OpExtInst %void %2 DebugDeclare %226 %1451 %243
4963        %1670 = OpExtInst %void %2 DebugLine %64 %uint_112 %uint_112 %uint_16 %uint_24
4964        %1512 = OpExtInst %float %1 Length %1509
4965        %2250 = OpExtInst %void %2 DebugLine %64 %uint_112 %uint_112 %uint_3 %uint_24
4966        %2249 = OpExtInst %void %2 DebugValue %223 %1512 %243
4967        %1674 = OpExtInst %void %2 DebugLine %64 %uint_113 %uint_113 %uint_7 %uint_18
4968        %1515 = OpExtInst %v3float %1 Normalize %1509
4969        %1675 = OpExtInst %void %2 DebugLine %64 %uint_113 %uint_113 %uint_3 %uint_18
4970                OpStore %1451 %1515
4971        %1676 = OpExtInst %void %2 DebugLine %64 %uint_116 %uint_116 %uint_14 %uint_26
4972        %1516 = OpAccessChain %_ptr_Uniform_UBO %ubo %int_0
4973        %1517 = OpAccessChain %_ptr_Uniform_v4float %1516 %int_0
4974        %1678 = OpExtInst %void %2 DebugLine %64 %uint_116 %uint_116 %uint_14 %uint_18
4975        %1518 = OpLoad %v4float %1517
4976        %1679 = OpExtInst %void %2 DebugLine %64 %uint_116 %uint_116 %uint_14 %uint_26
4977        %1519 = OpVectorShuffle %v3float %1518 %1518 0 1 2
4978        %1681 = OpExtInst %void %2 DebugLine %64 %uint_116 %uint_116 %uint_14 %uint_32
4979        %1521 = OpFSub %v3float %1519 %1476
4980        %1682 = OpExtInst %void %2 DebugLine %64 %uint_116 %uint_116 %uint_3 %uint_32
4981                OpStore %1453 %1521
4982        %1522 = OpExtInst %void %2 DebugDeclare %221 %1453 %243
4983        %1685 = OpExtInst %void %2 DebugLine %64 %uint_117 %uint_117 %uint_7 %uint_18
4984        %1524 = OpExtInst %v3float %1 Normalize %1521
4985        %1686 = OpExtInst %void %2 DebugLine %64 %uint_117 %uint_117 %uint_3 %uint_18
4986                OpStore %1453 %1524
4987        %1687 = OpExtInst %void %2 DebugLine %64 %uint_119 %uint_119 %uint_34 %uint_46
4988        %1525 = OpExtInst %float %1 Radians %float_15
4989        %1688 = OpExtInst %void %2 DebugLine %64 %uint_119 %uint_119 %uint_30 %uint_47
4990        %1526 = OpExtInst %float %1 Cos %1525
4991        %2253 = OpExtInst %void %2 DebugLine %64 %uint_119 %uint_119 %uint_3 %uint_47
4992        %2252 = OpExtInst %void %2 DebugValue %218 %1526 %243
4993        %1691 = OpExtInst %void %2 DebugLine %64 %uint_120 %uint_120 %uint_34 %uint_46
4994        %1528 = OpExtInst %float %1 Radians %float_25
4995        %1692 = OpExtInst %void %2 DebugLine %64 %uint_120 %uint_120 %uint_30 %uint_47
4996        %1529 = OpExtInst %float %1 Cos %1528
4997        %2256 = OpExtInst %void %2 DebugLine %64 %uint_120 %uint_120 %uint_3 %uint_47
4998        %2255 = OpExtInst %void %2 DebugValue %215 %1529 %243
4999        %2259 = OpExtInst %void %2 DebugLine %64 %uint_121 %uint_121 %uint_3 %uint_22
5000        %2258 = OpExtInst %void %2 DebugValue %212 %float_100 %243
5001        %1698 = OpExtInst %void %2 DebugLine %64 %uint_124 %uint_124 %uint_26 %uint_49
5002        %1533 = OpAccessChain %_ptr_Uniform_UBO %ubo %int_0
5003        %1534 = OpAccessChain %_ptr_Uniform_v4float %1533 %int_1 %1503 %int_0
5004        %1700 = OpExtInst %void %2 DebugLine %64 %uint_124 %uint_124 %uint_26 %uint_40
5005        %1535 = OpLoad %v4float %1534
5006        %1701 = OpExtInst %void %2 DebugLine %64 %uint_124 %uint_124 %uint_26 %uint_49
5007        %1536 = OpVectorShuffle %v3float %1535 %1535 0 1 2
5008        %1703 = OpExtInst %void %2 DebugLine %64 %uint_124 %uint_124 %uint_55 %uint_76
5009        %1538 = OpAccessChain %_ptr_Uniform_UBO %ubo %int_0
5010        %1539 = OpAccessChain %_ptr_Uniform_v4float %1538 %int_1 %1503 %int_1
5011        %1705 = OpExtInst %void %2 DebugLine %64 %uint_124 %uint_124 %uint_55 %uint_69
5012        %1540 = OpLoad %v4float %1539
5013        %1706 = OpExtInst %void %2 DebugLine %64 %uint_124 %uint_124 %uint_55 %uint_76
5014        %1541 = OpVectorShuffle %v3float %1540 %1540 0 1 2
5015        %1707 = OpExtInst %void %2 DebugLine %64 %uint_124 %uint_124 %uint_26 %uint_76
5016        %1542 = OpFSub %v3float %1536 %1541
5017        %1708 = OpExtInst %void %2 DebugLine %64 %uint_124 %uint_124 %uint_16 %uint_79
5018        %1543 = OpExtInst %v3float %1 Normalize %1542
5019        %2262 = OpExtInst %void %2 DebugLine %64 %uint_124 %uint_124 %uint_3 %uint_79
5020        %2261 = OpExtInst %void %2 DebugValue %209 %1543 %243
5021        %1713 = OpExtInst %void %2 DebugLine %64 %uint_127 %uint_127 %uint_18 %uint_28
5022        %1547 = OpDot %float %1515 %1543
5023        %2265 = OpExtInst %void %2 DebugLine %64 %uint_127 %uint_127 %uint_3 %uint_28
5024        %2264 = OpExtInst %void %2 DebugValue %206 %1547 %243
5025        %1719 = OpExtInst %void %2 DebugLine %64 %uint_128 %uint_128 %uint_22 %uint_79
5026        %1552 = OpExtInst %float %1 SmoothStep %1529 %1526 %1547
5027        %2268 = OpExtInst %void %2 DebugLine %64 %uint_128 %uint_128 %uint_3 %uint_79
5028        %2267 = OpExtInst %void %2 DebugValue %203 %1552 %243
5029        %1724 = OpExtInst %void %2 DebugLine %64 %uint_129 %uint_129 %uint_29 %uint_62
5030        %1556 = OpExtInst %float %1 SmoothStep %float_100 %float_0 %1512
5031        %2271 = OpExtInst %void %2 DebugLine %64 %uint_129 %uint_129 %uint_3 %uint_62
5032        %2270 = OpExtInst %void %2 DebugValue %200 %1556 %243
5033        %1729 = OpExtInst %void %2 DebugLine %64 %uint_132 %uint_132 %uint_26 %uint_34
5034        %1560 = OpDot %float %1496 %1515
5035        %1730 = OpExtInst %void %2 DebugLine %64 %uint_132 %uint_132 %uint_17 %uint_35
5036        %1561 = OpExtInst %float %1 FMax %float_0 %1560
5037        %2274 = OpExtInst %void %2 DebugLine %64 %uint_132 %uint_132 %uint_3 %uint_35
5038        %2273 = OpExtInst %void %2 DebugValue %197 %1561 %243
5039        %1734 = OpExtInst %void %2 DebugLine %64 %uint_133 %uint_133 %uint_17 %uint_23
5040        %1564 = OpCompositeConstruct %v3float %1561 %1561 %1561
5041        %2277 = OpExtInst %void %2 DebugLine %64 %uint_133 %uint_133 %uint_3 %uint_23
5042        %2276 = OpExtInst %void %2 DebugValue %194 %1564 %243
5043        %1738 = OpExtInst %void %2 DebugLine %64 %uint_136 %uint_136 %uint_22 %uint_23
5044        %1567 = OpFNegate %v3float %1515
5045        %1740 = OpExtInst %void %2 DebugLine %64 %uint_136 %uint_136 %uint_14 %uint_27
5046        %1569 = OpExtInst %v3float %1 Reflect %1567 %1496
5047        %2280 = OpExtInst %void %2 DebugLine %64 %uint_136 %uint_136 %uint_3 %uint_27
5048        %2279 = OpExtInst %void %2 DebugValue %191 %1569 %243
5049        %1745 = OpExtInst %void %2 DebugLine %64 %uint_137 %uint_137 %uint_26 %uint_34
5050        %1573 = OpDot %float %1569 %1524
5051        %1746 = OpExtInst %void %2 DebugLine %64 %uint_137 %uint_137 %uint_17 %uint_35
5052        %1574 = OpExtInst %float %1 FMax %float_0 %1573
5053        %2283 = OpExtInst %void %2 DebugLine %64 %uint_137 %uint_137 %uint_3 %uint_35
5054        %2282 = OpExtInst %void %2 DebugValue %188 %1574 %243
5055        %1750 = OpExtInst %void %2 DebugLine %64 %uint_138 %uint_138 %uint_18 %uint_33
5056        %1577 = OpExtInst %float %1 Pow %1574 %float_16
5057        %1751 = OpExtInst %void %2 DebugLine %64 %uint_138 %uint_138 %uint_37 %uint_44
5058        %1578 = OpAccessChain %_ptr_Function_float %1447 %int_3
5059        %1579 = OpLoad %float %1578
5060        %1753 = OpExtInst %void %2 DebugLine %64 %uint_138 %uint_138 %uint_18 %uint_44
5061        %1580 = OpFMul %float %1577 %1579
5062        %1754 = OpExtInst %void %2 DebugLine %64 %uint_138 %uint_138 %uint_18 %uint_48
5063        %1581 = OpFMul %float %1580 %float_2_5
5064        %1755 = OpExtInst %void %2 DebugLine %64 %uint_138 %uint_138 %uint_17 %uint_53
5065        %1582 = OpCompositeConstruct %v3float %1581 %1581 %1581
5066        %2286 = OpExtInst %void %2 DebugLine %64 %uint_138 %uint_138 %uint_3 %uint_53
5067        %2285 = OpExtInst %void %2 DebugValue %185 %1582 %243
5068        %1760 = OpExtInst %void %2 DebugLine %64 %uint_140 %uint_140 %uint_24 %uint_31
5069        %1586 = OpFAdd %v3float %1564 %1582
5070        %1762 = OpExtInst %void %2 DebugLine %64 %uint_140 %uint_140 %uint_23 %uint_39
5071        %1588 = OpVectorTimesScalar %v3float %1586 %1552
5072        %1764 = OpExtInst %void %2 DebugLine %64 %uint_140 %uint_140 %uint_23 %uint_52
5073        %1590 = OpVectorTimesScalar %v3float %1588 %1556
5074        %1766 = OpExtInst %void %2 DebugLine %64 %uint_140 %uint_140 %uint_73 %uint_93
5075        %1592 = OpAccessChain %_ptr_Uniform_UBO %ubo %int_0
5076        %1593 = OpAccessChain %_ptr_Uniform_v4float %1592 %int_1 %1503 %int_2
5077        %1768 = OpExtInst %void %2 DebugLine %64 %uint_140 %uint_140 %uint_73 %uint_87
5078        %1594 = OpLoad %v4float %1593
5079        %1769 = OpExtInst %void %2 DebugLine %64 %uint_140 %uint_140 %uint_73 %uint_93
5080        %1595 = OpVectorShuffle %v3float %1594 %1594 0 1 2
5081        %1770 = OpExtInst %void %2 DebugLine %64 %uint_140 %uint_140 %uint_16 %uint_93
5082        %1596 = OpFMul %v3float %1590 %1595
5083        %1772 = OpExtInst %void %2 DebugLine %64 %uint_140 %uint_140 %uint_99 %uint_106
5084        %1598 = OpVectorShuffle %v3float %1489 %1489 0 1 2
5085        %1773 = OpExtInst %void %2 DebugLine %64 %uint_140 %uint_140 %uint_16 %uint_106
5086        %1599 = OpFMul %v3float %1596 %1598
5087        %1774 = OpExtInst %void %2 DebugLine %64 %uint_140 %uint_140 %uint_3 %uint_3
5088        %1600 = OpLoad %v3float %1448
5089        %1775 = OpExtInst %void %2 DebugLine %64 %uint_140 %uint_140 %uint_3 %uint_106
5090        %1601 = OpFAdd %v3float %1600 %1599
5091                OpStore %1448 %1601
5092        %2295 = OpExtInst %void %2 DebugScope %179
5093        %1777 = OpExtInst %void %2 DebugLine %64 %uint_107 %uint_107 %uint_34 %uint_36
5094                OpBranch %1602
5095        %1602 = OpLabel
5096        %2296 = OpExtInst %void %2 DebugScope %179
5097        %1778 = OpExtInst %void %2 DebugLine %64 %uint_107 %uint_107 %uint_34 %uint_36
5098        %1603 = OpLoad %int %1450
5099        %1604 = OpIAdd %int %1603 %int_1
5100                OpStore %1450 %1604
5101                OpBranch %1499
5102        %1605 = OpLabel
5103        %2297 = OpExtInst %void %2 DebugScope %179
5104        %1782 = OpExtInst %void %2 DebugLine %64 %uint_144 %uint_144 %uint_6 %uint_10
5105        %1606 = OpAccessChain %_ptr_Uniform_UBO %ubo %int_0
5106        %1607 = OpAccessChain %_ptr_Uniform_int %1606 %int_2
5107        %1608 = OpLoad %int %1607
5108        %1785 = OpExtInst %void %2 DebugLine %64 %uint_144 %uint_144 %uint_6 %uint_23
5109        %1609 = OpSGreaterThan %bool %1608 %int_0
5110        %2298 = OpExtInst %void %2 DebugNoScope
5111                OpSelectionMerge %1614 None
5112                OpBranchConditional %1609 %1610 %1614
5113 )"
5114       R"(    %1610 = OpLabel
5115        %2299 = OpExtInst %void %2 DebugScope %180
5116        %1788 = OpExtInst %void %2 DebugLine %64 %uint_146 %uint_146 %uint_22 %uint_22
5117        %1611 = OpLoad %v3float %1448
5118                OpStore %1466 %1611
5119        %2300 = OpExtInst %void %2 DebugScope %155 %1803
5120        %1842 = OpExtInst %void %2 DebugLine %64 %uint_78 %uint_78 %uint_15 %uint_22
5121        %1810 = OpExtInst %void %2 DebugDeclare %172 %1466 %243
5122        %2301 = OpExtInst %void %2 DebugScope %180
5123        %2289 = OpExtInst %void %2 DebugLine %64 %uint_146 %uint_146 %uint_33 %uint_33
5124        %2288 = OpExtInst %void %2 DebugValue %170 %1476 %243
5125        %2302 = OpExtInst %void %2 DebugScope %157 %1803
5126        %1844 = OpExtInst %void %2 DebugLine %64 %uint_79 %uint_79 %uint_7 %uint_15
5127                OpStore %1801 %int_0
5128        %1813 = OpExtInst %void %2 DebugDeclare %167 %1801 %243
5129        %1846 = OpExtInst %void %2 DebugLine %64 %uint_79 %uint_79 %uint_7 %uint_16
5130                OpBranch %1814
5131        %1814 = OpLabel
5132        %2303 = OpExtInst %void %2 DebugScope %157 %1803
5133        %1847 = OpExtInst %void %2 DebugLine %64 %uint_79 %uint_79 %uint_18 %uint_18
5134        %1815 = OpLoad %int %1801
5135        %1848 = OpExtInst %void %2 DebugLine %64 %uint_79 %uint_79 %uint_18 %uint_22
5136        %1816 = OpSLessThan %bool %1815 %int_3
5137        %2304 = OpExtInst %void %2 DebugNoScope
5138                OpLoopMerge %1840 %1837 None
5139                OpBranchConditional %1816 %1817 %1840
5140        %1817 = OpLabel
5141        %2305 = OpExtInst %void %2 DebugScope %158 %1803
5142        %1851 = OpExtInst %void %2 DebugLine %64 %uint_81 %uint_81 %uint_38 %uint_38
5143        %1818 = OpLoad %int %1801
5144        %1852 = OpExtInst %void %2 DebugLine %64 %uint_81 %uint_81 %uint_27 %uint_41
5145        %1819 = OpAccessChain %_ptr_Uniform_UBO %ubo %int_0
5146        %1820 = OpAccessChain %_ptr_Uniform_mat4v4float %1819 %int_1 %1818 %int_3
5147        %1821 = OpLoad %mat4v4float %1820
5148        %1856 = OpExtInst %void %2 DebugLine %64 %uint_81 %uint_81 %uint_60 %uint_68
5149        %1823 = OpCompositeExtract %float %1476 0
5150        %1824 = OpCompositeExtract %float %1476 1
5151        %1825 = OpCompositeExtract %float %1476 2
5152        %1859 = OpExtInst %void %2 DebugLine %64 %uint_81 %uint_81 %uint_53 %uint_76
5153        %1826 = OpCompositeConstruct %v4float %1823 %1824 %1825 %float_1
5154        %1860 = OpExtInst %void %2 DebugLine %64 %uint_81 %uint_81 %uint_23 %uint_77
5155        %1827 = OpVectorTimesMatrix %v4float %1826 %1821
5156        %2229 = OpExtInst %void %2 DebugLine %64 %uint_81 %uint_81 %uint_3 %uint_77
5157        %2228 = OpExtInst %void %2 DebugValue %163 %1827 %243
5158        %1867 = OpExtInst %void %2 DebugLine %64 %uint_85 %uint_85 %uint_40 %uint_40
5159        %1832 = OpConvertSToF %float %1818
5160        %2235 = OpExtInst %void %2 DebugLine %64 %uint_85 %uint_85 %uint_28 %uint_28
5161        %2234 = OpExtInst %void %2 DebugValue %151 %1827 %243
5162        %2238 = OpExtInst %void %2 DebugLine %64 %uint_85 %uint_85 %uint_40 %uint_40
5163        %2237 = OpExtInst %void %2 DebugValue %148 %1832 %243
5164        %2306 = OpExtInst %void %2 DebugScope %103 %1885
5165        %1983 = OpExtInst %void %2 DebugLine %64 %uint_56 %uint_56 %uint_2 %uint_7
5166        %1904 = OpExtInst %void %2 DebugDeclare %146 %1883 %243
5167        %1986 = OpExtInst %void %2 DebugLine %64 %uint_57 %uint_57 %uint_2 %uint_2
5168        %1907 = OpLoad %type_2d_image_array %textureShadowMap
5169 )"
5170       R"(    %1987 = OpExtInst %void %2 DebugLine %64 %uint_57 %uint_57 %uint_2 %uint_72
5171        %1908 = OpImageQuerySizeLod %v3uint %1907 %uint_0
5172        %1909 = OpCompositeExtract %uint %1908 0
5173        %1910 = OpBitcast %int %1909
5174        %1911 = OpAccessChain %_ptr_Function_int %1883 %int_0
5175                OpStore %1911 %1910
5176        %1912 = OpCompositeExtract %uint %1908 1
5177        %1913 = OpBitcast %int %1912
5178        %1914 = OpAccessChain %_ptr_Function_int %1883 %int_1
5179                OpStore %1914 %1913
5180        %1915 = OpCompositeExtract %uint %1908 2
5181        %1916 = OpBitcast %int %1915
5182        %2204 = OpExtInst %void %2 DebugValue %142 %1916 %243
5183        %1999 = OpExtInst %void %2 DebugLine %64 %uint_57 %uint_57 %uint_19 %uint_19
5184        %1917 = OpImageQueryLevels %uint %1907
5185        %2000 = OpExtInst %void %2 DebugLine %64 %uint_57 %uint_57 %uint_2 %uint_72
5186        %1918 = OpBitcast %int %1917
5187        %2207 = OpExtInst %void %2 DebugValue %138 %1918 %243
5188        %2211 = OpExtInst %void %2 DebugLine %64 %uint_58 %uint_58 %uint_2 %uint_16
5189        %2210 = OpExtInst %void %2 DebugValue %135 %float_1_5 %243
5190        %2005 = OpExtInst %void %2 DebugLine %64 %uint_59 %uint_59 %uint_13 %uint_21
5191        %1921 = OpFMul %float %float_1_5 %float_1
5192        %2006 = OpExtInst %void %2 DebugLine %64 %uint_59 %uint_59 %uint_33 %uint_40
5193        %1922 = OpAccessChain %_ptr_Function_int %1883 %int_0
5194        %1923 = OpLoad %int %1922
5195        %1924 = OpConvertSToF %float %1923
5196        %2009 = OpExtInst %void %2 DebugLine %64 %uint_59 %uint_59 %uint_13 %uint_41
5197        %1925 = OpFDiv %float %1921 %1924
5198        %2214 = OpExtInst %void %2 DebugLine %64 %uint_59 %uint_59 %uint_2 %uint_41
5199        %2213 = OpExtInst %void %2 DebugValue %132 %1925 %243
5200        %2013 = OpExtInst %void %2 DebugLine %64 %uint_60 %uint_60 %uint_13 %uint_21
5201        %1928 = OpFMul %float %float_1_5 %float_1
5202        %2014 = OpExtInst %void %2 DebugLine %64 %uint_60 %uint_60 %uint_33 %uint_40
5203        %1929 = OpAccessChain %_ptr_Function_int %1883 %int_1
5204        %1930 = OpLoad %int %1929
5205        %1931 = OpConvertSToF %float %1930
5206        %2017 = OpExtInst %void %2 DebugLine %64 %uint_60 %uint_60 %uint_13 %uint_41
5207        %1932 = OpFDiv %float %1928 %1931
5208        %2217 = OpExtInst %void %2 DebugLine %64 %uint_60 %uint_60 %uint_2 %uint_41
5209        %2216 = OpExtInst %void %2 DebugValue %129 %1932 %243
5210        %2020 = OpExtInst %void %2 DebugLine %64 %uint_62 %uint_62 %uint_2 %uint_23
5211                OpStore %1891 %float_0
5212        %1934 = OpExtInst %void %2 DebugDeclare %126 %1891 %243
5213        %2022 = OpExtInst %void %2 DebugLine %64 %uint_63 %uint_63 %uint_2 %uint_14
5214                OpStore %1892 %int_0
5215        %1935 = OpExtInst %void %2 DebugDeclare %123 %1892 %243
5216        %2220 = OpExtInst %void %2 DebugLine %64 %uint_64 %uint_64 %uint_2 %uint_14
5217        %2219 = OpExtInst %void %2 DebugValue %119 %int_1 %243
5218        %2027 = OpExtInst %void %2 DebugLine %64 %uint_66 %uint_66 %uint_15 %uint_16
5219        %1938 = OpSNegate %int %int_1
5220        %2028 = OpExtInst %void %2 DebugLine %64 %uint_66 %uint_66 %uint_7 %uint_16
5221                OpStore %1894 %1938
5222        %1939 = OpExtInst %void %2 DebugDeclare %115 %1894 %243
5223        %2030 = OpExtInst %void %2 DebugLine %64 %uint_66 %uint_66 %uint_7 %uint_21
5224                OpBranch %1940
5225        %1940 = OpLabel
5226        %2307 = OpExtInst %void %2 DebugScope %103 %1885
5227        %2031 = OpExtInst %void %2 DebugLine %64 %uint_66 %uint_66 %uint_23 %uint_23
5228        %1941 = OpLoad %int %1894
5229        %2033 = OpExtInst %void %2 DebugLine %64 %uint_66 %uint_66 %uint_23 %uint_28
5230        %1943 = OpSLessThanEqual %bool %1941 %int_1
5231        %2308 = OpExtInst %void %2 DebugNoScope
5232                OpLoopMerge %1976 %1973 None
5233                OpBranchConditional %1943 %1944 %1976
5234        %1944 = OpLabel
5235        %2309 = OpExtInst %void %2 DebugScope %104 %1885
5236        %2037 = OpExtInst %void %2 DebugLine %64 %uint_68 %uint_68 %uint_16 %uint_17
5237        %1946 = OpSNegate %int %int_1
5238        %2038 = OpExtInst %void %2 DebugLine %64 %uint_68 %uint_68 %uint_8 %uint_17
5239                OpStore %1895 %1946
5240        %1947 = OpExtInst %void %2 DebugDeclare %111 %1895 %243
5241        %2040 = OpExtInst %void %2 DebugLine %64 %uint_68 %uint_68 %uint_8 %uint_22
5242                OpBranch %1948
5243        %1948 = OpLabel
5244        %2310 = OpExtInst %void %2 DebugScope %104 %1885
5245        %2041 = OpExtInst %void %2 DebugLine %64 %uint_68 %uint_68 %uint_24 %uint_24
5246        %1949 = OpLoad %int %1895
5247        %2043 = OpExtInst %void %2 DebugLine %64 %uint_68 %uint_68 %uint_24 %uint_29
5248        %1951 = OpSLessThanEqual %bool %1949 %int_1
5249        %2311 = OpExtInst %void %2 DebugNoScope
5250                OpLoopMerge %1972 %1969 None
5251                OpBranchConditional %1951 %1952 %1972
5252        %1952 = OpLabel
5253        %2312 = OpExtInst %void %2 DebugScope %106 %1885
5254        %2047 = OpExtInst %void %2 DebugLine %64 %uint_70 %uint_70 %uint_32 %uint_32
5255                OpStore %1896 %1827
5256        %2051 = OpExtInst %void %2 DebugLine %64 %uint_70 %uint_70 %uint_53 %uint_53
5257        %1956 = OpLoad %int %1894
5258        %1957 = OpConvertSToF %float %1956
5259        %2053 = OpExtInst %void %2 DebugLine %64 %uint_70 %uint_70 %uint_50 %uint_53
5260        %1958 = OpFMul %float %1925 %1957
5261        %2055 = OpExtInst %void %2 DebugLine %64 %uint_70 %uint_70 %uint_59 %uint_59
5262        %1960 = OpLoad %int %1895
5263        %1961 = OpConvertSToF %float %1960
5264        %2057 = OpExtInst %void %2 DebugLine %64 %uint_70 %uint_70 %uint_56 %uint_59
5265        %1962 = OpFMul %float %1932 %1961
5266        %2058 = OpExtInst %void %2 DebugLine %64 %uint_70 %uint_70 %uint_43 %uint_60
5267        %1963 = OpCompositeConstruct %v2float %1958 %1962
5268        %2313 = OpExtInst %void %2 DebugScope %70 %2085
5269        %2141 = OpExtInst %void %2 DebugLine %64 %uint_37 %uint_37 %uint_19 %uint_26
5270        %2090 = OpExtInst %void %2 DebugDeclare %96 %1896 %243
5271        %2314 = OpExtInst %void %2 DebugScope %106 %1885
5272        %2223 = OpExtInst %void %2 DebugLine %64 %uint_70 %uint_70 %uint_36 %uint_36
5273        %2222 = OpExtInst %void %2 DebugValue %93 %1832 %243
5274        %2226 = OpExtInst %void %2 DebugLine %64 %uint_70 %uint_70 %uint_43 %uint_60
5275        %2225 = OpExtInst %void %2 DebugValue %90 %1963 %243
5276        %2315 = OpExtInst %void %2 DebugScope %73 %2085
5277        %2144 = OpExtInst %void %2 DebugLine %64 %uint_39 %uint_39 %uint_2 %uint_17
5278                OpStore %2083 %float_1
5279        %2094 = OpExtInst %void %2 DebugDeclare %86 %2083 %243
5280        %2147 = OpExtInst %void %2 DebugLine %64 %uint_40 %uint_40 %uint_27 %uint_29
5281        %2096 = OpAccessChain %_ptr_Function_float %1896 %int_3
5282        %2097 = OpLoad %float %2096
5283        %2098 = OpCompositeConstruct %v4float %2097 %2097 %2097 %2097
5284        %2150 = OpExtInst %void %2 DebugLine %64 %uint_40 %uint_40 %uint_23 %uint_29
5285        %2099 = OpFDiv %v4float %1827 %2098
5286        %2151 = OpExtInst %void %2 DebugLine %64 %uint_40 %uint_40 %uint_2 %uint_29
5287                OpStore %2086 %2099
5288        %2100 = OpExtInst %void %2 DebugDeclare %83 %2086 %243
5289        %2154 = OpExtInst %void %2 DebugLine %64 %uint_41 %uint_41 %uint_19 %uint_31
5290        %2102 = OpVectorShuffle %v2float %2099 %2099 0 1
5291        %2155 = OpExtInst %void %2 DebugLine %64 %uint_41 %uint_41 %uint_19 %uint_36
5292        %2103 = OpVectorTimesScalar %v2float %2102 %float_0_5
5293        %2156 = OpExtInst %void %2 DebugLine %64 %uint_41 %uint_41 %uint_19 %uint_42
5294        %2104 = OpFAdd %v2float %2103 %35
5295        %2158 = OpExtInst %void %2 DebugLine %64 %uint_41 %uint_41 %uint_2 %uint_42
5296        %2106 = OpVectorShuffle %v4float %2099 %2104 4 5 2 3
5297                OpStore %2086 %2106
5298        %2160 = OpExtInst %void %2 DebugLine %64 %uint_43 %uint_43 %uint_6 %uint_18
5299        %2107 = OpAccessChain %_ptr_Function_float %2086 %int_2
5300        %2108 = OpLoad %float %2107
5301        %2162 = OpExtInst %void %2 DebugLine %64 %uint_43 %uint_43 %uint_6 %uint_23
5302        %2109 = OpFOrdGreaterThan %bool %2108 %float_n1
5303        %2163 = OpExtInst %void %2 DebugLine %64 %uint_43 %uint_43 %uint_30 %uint_42
5304        %2110 = OpAccessChain %_ptr_Function_float %2086 %int_2
5305        %2111 = OpLoad %float %2110
5306        %2165 = OpExtInst %void %2 DebugLine %64 %uint_43 %uint_43 %uint_30 %uint_46
5307        %2112 = OpFOrdLessThan %bool %2111 %float_1
5308        %2166 = OpExtInst %void %2 DebugLine %64 %uint_43 %uint_43 %uint_6 %uint_46
5309        %2113 = OpLogicalAnd %bool %2109 %2112
5310        %2316 = OpExtInst %void %2 DebugNoScope
5311                OpSelectionMerge %2139 None
5312                OpBranchConditional %2113 %2114 %2139
5313        %2114 = OpLabel
5314        %2317 = OpExtInst %void %2 DebugScope %74 %2085
5315        %2169 = OpExtInst %void %2 DebugLine %64 %uint_45 %uint_45 %uint_16 %uint_16
5316        %2115 = OpLoad %type_2d_image_array %textureShadowMap
5317        %2170 = OpExtInst %void %2 DebugLine %64 %uint_45 %uint_45 %uint_40 %uint_40
5318        %2116 = OpLoad %type_sampler %samplerShadowMap
5319        %2171 = OpExtInst %void %2 DebugLine %64 %uint_45 %uint_45 %uint_65 %uint_65
5320        %2117 = OpLoad %v4float %2086
5321        %2172 = OpExtInst %void %2 DebugLine %64 %uint_45 %uint_45 %uint_65 %uint_77
5322        %2118 = OpVectorShuffle %v2float %2117 %2117 0 1
5323        %2174 = OpExtInst %void %2 DebugLine %64 %uint_45 %uint_45 %uint_65 %uint_82
5324        %2120 = OpFAdd %v2float %2118 %1963
5325        %2122 = OpCompositeExtract %float %2120 0
5326        %2123 = OpCompositeExtract %float %2120 1
5327        %2178 = OpExtInst %void %2 DebugLine %64 %uint_45 %uint_45 %uint_58 %uint_95
5328        %2124 = OpCompositeConstruct %v3float %2122 %2123 %1832
5329        %2179 = OpExtInst %void %2 DebugLine %64 %uint_45 %uint_45 %uint_16 %uint_96
5330        %2125 = OpSampledImage %type_sampled_image_0 %2115 %2116
5331        %2126 = OpImageSampleImplicitLod %v4float %2125 %2124 None
5332        %2181 = OpExtInst %void %2 DebugLine %64 %uint_45 %uint_45 %uint_16 %uint_98
5333        %2127 = OpCompositeExtract %float %2126 0
5334        %2202 = OpExtInst %void %2 DebugLine %64 %uint_45 %uint_45 %uint_3 %uint_98
5335        %2201 = OpExtInst %void %2 DebugValue %79 %2127 %243
5336        %2184 = OpExtInst %void %2 DebugLine %64 %uint_46 %uint_46 %uint_7 %uint_19
5337        %2129 = OpAccessChain %_ptr_Function_float %2086 %int_3
5338        %2130 = OpLoad %float %2129
5339        %2186 = OpExtInst %void %2 DebugLine %64 %uint_46 %uint_46 %uint_7 %uint_23
5340        %2131 = OpFOrdGreaterThan %bool %2130 %float_0
5341        %2188 = OpExtInst %void %2 DebugLine %64 %uint_46 %uint_46 %uint_37 %uint_49
5342        %2133 = OpAccessChain %_ptr_Function_float %2086 %int_2
5343        %2134 = OpLoad %float %2133
5344        %2190 = OpExtInst %void %2 DebugLine %64 %uint_46 %uint_46 %uint_30 %uint_49
5345        %2135 = OpFOrdLessThan %bool %2127 %2134
5346        %2191 = OpExtInst %void %2 DebugLine %64 %uint_46 %uint_46 %uint_7 %uint_49
5347        %2136 = OpLogicalAnd %bool %2131 %2135
5348        %2318 = OpExtInst %void %2 DebugNoScope
5349                OpSelectionMerge %2138 None
5350                OpBranchConditional %2136 %2137 %2138
5351        %2137 = OpLabel
5352        %2319 = OpExtInst %void %2 DebugScope %76 %2085
5353        %2194 = OpExtInst %void %2 DebugLine %64 %uint_48 %uint_48 %uint_4 %uint_13
5354                OpStore %2083 %float_0_25
5355        %2320 = OpExtInst %void %2 DebugScope %74 %2085
5356        %2195 = OpExtInst %void %2 DebugLine %64 %uint_49 %uint_49 %uint_3 %uint_3
5357                OpBranch %2138
5358        %2138 = OpLabel
5359        %2321 = OpExtInst %void %2 DebugScope %73 %2085
5360        %2196 = OpExtInst %void %2 DebugLine %64 %uint_50 %uint_50 %uint_2 %uint_2
5361                OpBranch %2139
5362        %2139 = OpLabel
5363        %2322 = OpExtInst %void %2 DebugScope %73 %2085
5364        %2197 = OpExtInst %void %2 DebugLine %64 %uint_51 %uint_51 %uint_9 %uint_9
5365        %2140 = OpLoad %float %2083
5366        %2323 = OpExtInst %void %2 DebugScope %106 %1885
5367        %2061 = OpExtInst %void %2 DebugLine %64 %uint_70 %uint_70 %uint_4 %uint_4
5368        %1965 = OpLoad %float %1891
5369        %2062 = OpExtInst %void %2 DebugLine %64 %uint_70 %uint_70 %uint_4 %uint_61
5370        %1966 = OpFAdd %float %1965 %2140
5371                OpStore %1891 %1966
5372        %2064 = OpExtInst %void %2 DebugLine %64 %uint_71 %uint_71 %uint_4 %uint_9
5373        %1967 = OpLoad %int %1892
5374        %1968 = OpIAdd %int %1967 %int_1
5375                OpStore %1892 %1968
5376        %2324 = OpExtInst %void %2 DebugScope %104 %1885
5377        %2067 = OpExtInst %void %2 DebugLine %64 %uint_68 %uint_68 %uint_36 %uint_37
5378                OpBranch %1969
5379        %1969 = OpLabel
5380        %2325 = OpExtInst %void %2 DebugScope %104 %1885
5381        %2068 = OpExtInst %void %2 DebugLine %64 %uint_68 %uint_68 %uint_36 %uint_37
5382        %1970 = OpLoad %int %1895
5383        %1971 = OpIAdd %int %1970 %int_1
5384                OpStore %1895 %1971
5385                OpBranch %1948
5386        %1972 = OpLabel
5387        %2326 = OpExtInst %void %2 DebugScope %103 %1885
5388        %2072 = OpExtInst %void %2 DebugLine %64 %uint_66 %uint_66 %uint_35 %uint_36
5389                OpBranch %1973
5390        %1973 = OpLabel
5391        %2327 = OpExtInst %void %2 DebugScope %103 %1885
5392        %2073 = OpExtInst %void %2 DebugLine %64 %uint_66 %uint_66 %uint_35 %uint_36
5393        %1974 = OpLoad %int %1894
5394        %1975 = OpIAdd %int %1974 %int_1
5395                OpStore %1894 %1975
5396                OpBranch %1940
5397        %1976 = OpLabel
5398        %2328 = OpExtInst %void %2 DebugScope %103 %1885
5399        %2077 = OpExtInst %void %2 DebugLine %64 %uint_75 %uint_75 %uint_9 %uint_9
5400        %1977 = OpLoad %float %1891
5401        %2078 = OpExtInst %void %2 DebugLine %64 %uint_75 %uint_75 %uint_24 %uint_24
5402        %1978 = OpLoad %int %1892
5403        %1979 = OpConvertSToF %float %1978
5404        %2080 = OpExtInst %void %2 DebugLine %64 %uint_75 %uint_75 %uint_9 %uint_24
5405        %1980 = OpFDiv %float %1977 %1979
5406        %2329 = OpExtInst %void %2 DebugScope %158 %1803
5407        %2232 = OpExtInst %void %2 DebugLine %64 %uint_85 %uint_85 %uint_4 %uint_41
5408        %2231 = OpExtInst %void %2 DebugValue %160 %1980 %243
5409        %1872 = OpExtInst %void %2 DebugLine %64 %uint_90 %uint_90 %uint_3 %uint_3
5410        %1835 = OpLoad %v3float %1466
5411        %1873 = OpExtInst %void %2 DebugLine %64 %uint_90 %uint_90 %uint_3 %uint_16
5412        %1836 = OpVectorTimesScalar %v3float %1835 %1980
5413                OpStore %1466 %1836
5414        %2330 = OpExtInst %void %2 DebugScope %157 %1803
5415        %1875 = OpExtInst %void %2 DebugLine %64 %uint_79 %uint_79 %uint_35 %uint_37
5416                OpBranch %1837
5417        %1837 = OpLabel
5418        %2331 = OpExtInst %void %2 DebugScope %157 %1803
5419        %1876 = OpExtInst %void %2 DebugLine %64 %uint_79 %uint_79 %uint_35 %uint_37
5420        %1838 = OpLoad %int %1801
5421        %1839 = OpIAdd %int %1838 %int_1
5422                OpStore %1801 %1839
5423                OpBranch %1814
5424        %1840 = OpLabel
5425        %2332 = OpExtInst %void %2 DebugScope %157 %1803
5426        %1880 = OpExtInst %void %2 DebugLine %64 %uint_92 %uint_92 %uint_9 %uint_9
5427        %1841 = OpLoad %v3float %1466
5428        %2333 = OpExtInst %void %2 DebugScope %180
5429        %1793 = OpExtInst %void %2 DebugLine %64 %uint_146 %uint_146 %uint_3 %uint_40
5430                OpStore %1448 %1841
5431        %2334 = OpExtInst %void %2 DebugScope %179
5432        %1794 = OpExtInst %void %2 DebugLine %64 %uint_147 %uint_147 %uint_2 %uint_2
5433                OpBranch %1614
5434        %1614 = OpLabel
5435 ;CHECK:      %1614 = OpLabel
5436 ;CHECK-NEXT: [[phi:%\w+]] = OpPhi
5437 ;CHECK-NEXT: {{%\w+}} = OpExtInst %void {{%\w+}} DebugValue %233
5438        %2335 = OpExtInst %void %2 DebugScope %179
5439        %1795 = OpExtInst %void %2 DebugLine %64 %uint_149 %uint_149 %uint_16 %uint_16
5440        %1615 = OpLoad %v3float %1448
5441        %1616 = OpCompositeExtract %float %1615 0
5442        %1617 = OpCompositeExtract %float %1615 1
5443        %1618 = OpCompositeExtract %float %1615 2
5444        %1799 = OpExtInst %void %2 DebugLine %64 %uint_149 %uint_149 %uint_9 %uint_28
5445        %1619 = OpCompositeConstruct %v4float %1616 %1617 %1618 %float_1
5446        %2336 = OpExtInst %void %2 DebugNoLine
5447        %2337 = OpExtInst %void %2 DebugNoScope
5448                OpStore %out_var_SV_TARGET %1619
5449         %329 = OpExtInst %void %2 DebugLine %64 %uint_150 %uint_150 %uint_1 %uint_1
5450                OpReturn
5451                OpFunctionEnd
5452 )";
5453 
5454   SetTargetEnv(SPV_ENV_VULKAN_1_2);
5455   SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
5456   SinglePassRunAndMatch<SSARewritePass>(text, true);
5457 }
5458 
5459 // TODO(greg-lunarg): Add tests to verify handling of these cases:
5460 //
5461 //    No optimization in the presence of
5462 //      access chains
5463 //      function calls
5464 //      OpCopyMemory?
5465 //      unsupported extensions
5466 //    Others?
5467 
5468 }  // namespace
5469 }  // namespace opt
5470 }  // namespace spvtools
5471