• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2019 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "source/fuzz/fuzzer.h"
16 #include "source/fuzz/fuzzer_util.h"
17 #include "source/fuzz/replayer.h"
18 #include "source/fuzz/uniform_buffer_element_descriptor.h"
19 #include "test/fuzz/fuzz_test_util.h"
20 
21 namespace spvtools {
22 namespace fuzz {
23 namespace {
24 
25 const uint32_t kNumFuzzerRuns = 20;
26 
27 // The SPIR-V came from this GLSL:
28 //
29 // #version 310 es
30 //
31 // void foo() {
32 //   int x;
33 //   x = 2;
34 //   for (int i = 0; i < 100; i++) {
35 //     x += i;
36 //     x = x * 2;
37 //   }
38 //   return;
39 // }
40 //
41 // void main() {
42 //   foo();
43 //   for (int i = 0; i < 10; i++) {
44 //     int j = 20;
45 //     while(j > 0) {
46 //       foo();
47 //       j--;
48 //     }
49 //     do {
50 //       i++;
51 //     } while(i < 4);
52 //   }
53 // }
54 
55 const std::string kTestShader1 = R"(
56                OpCapability Shader
57           %1 = OpExtInstImport "GLSL.std.450"
58                OpMemoryModel Logical GLSL450
59                OpEntryPoint Fragment %4 "main"
60                OpExecutionMode %4 OriginUpperLeft
61                OpSource ESSL 310
62                OpName %4 "main"
63                OpName %6 "foo("
64                OpName %10 "x"
65                OpName %12 "i"
66                OpName %33 "i"
67                OpName %42 "j"
68                OpDecorate %10 RelaxedPrecision
69                OpDecorate %12 RelaxedPrecision
70                OpDecorate %19 RelaxedPrecision
71                OpDecorate %23 RelaxedPrecision
72                OpDecorate %24 RelaxedPrecision
73                OpDecorate %25 RelaxedPrecision
74                OpDecorate %26 RelaxedPrecision
75                OpDecorate %27 RelaxedPrecision
76                OpDecorate %28 RelaxedPrecision
77                OpDecorate %30 RelaxedPrecision
78                OpDecorate %33 RelaxedPrecision
79                OpDecorate %39 RelaxedPrecision
80                OpDecorate %42 RelaxedPrecision
81                OpDecorate %49 RelaxedPrecision
82                OpDecorate %52 RelaxedPrecision
83                OpDecorate %53 RelaxedPrecision
84                OpDecorate %58 RelaxedPrecision
85                OpDecorate %59 RelaxedPrecision
86                OpDecorate %60 RelaxedPrecision
87                OpDecorate %63 RelaxedPrecision
88                OpDecorate %64 RelaxedPrecision
89           %2 = OpTypeVoid
90           %3 = OpTypeFunction %2
91           %8 = OpTypeInt 32 1
92           %9 = OpTypePointer Function %8
93          %11 = OpConstant %8 2
94          %13 = OpConstant %8 0
95          %20 = OpConstant %8 100
96          %21 = OpTypeBool
97          %29 = OpConstant %8 1
98          %40 = OpConstant %8 10
99          %43 = OpConstant %8 20
100          %61 = OpConstant %8 4
101           %4 = OpFunction %2 None %3
102           %5 = OpLabel
103          %33 = OpVariable %9 Function
104          %42 = OpVariable %9 Function
105          %32 = OpFunctionCall %2 %6
106                OpStore %33 %13
107                OpBranch %34
108          %34 = OpLabel
109                OpLoopMerge %36 %37 None
110                OpBranch %38
111          %38 = OpLabel
112          %39 = OpLoad %8 %33
113          %41 = OpSLessThan %21 %39 %40
114                OpBranchConditional %41 %35 %36
115          %35 = OpLabel
116                OpStore %42 %43
117                OpBranch %44
118          %44 = OpLabel
119                OpLoopMerge %46 %47 None
120                OpBranch %48
121          %48 = OpLabel
122          %49 = OpLoad %8 %42
123          %50 = OpSGreaterThan %21 %49 %13
124                OpBranchConditional %50 %45 %46
125          %45 = OpLabel
126          %51 = OpFunctionCall %2 %6
127          %52 = OpLoad %8 %42
128          %53 = OpISub %8 %52 %29
129                OpStore %42 %53
130                OpBranch %47
131          %47 = OpLabel
132                OpBranch %44
133          %46 = OpLabel
134                OpBranch %54
135          %54 = OpLabel
136                OpLoopMerge %56 %57 None
137                OpBranch %55
138          %55 = OpLabel
139          %58 = OpLoad %8 %33
140          %59 = OpIAdd %8 %58 %29
141                OpStore %33 %59
142                OpBranch %57
143          %57 = OpLabel
144          %60 = OpLoad %8 %33
145          %62 = OpSLessThan %21 %60 %61
146                OpBranchConditional %62 %54 %56
147          %56 = OpLabel
148                OpBranch %37
149          %37 = OpLabel
150          %63 = OpLoad %8 %33
151          %64 = OpIAdd %8 %63 %29
152                OpStore %33 %64
153                OpBranch %34
154          %36 = OpLabel
155                OpReturn
156                OpFunctionEnd
157           %6 = OpFunction %2 None %3
158           %7 = OpLabel
159          %10 = OpVariable %9 Function
160          %12 = OpVariable %9 Function
161                OpStore %10 %11
162                OpStore %12 %13
163                OpBranch %14
164          %14 = OpLabel
165                OpLoopMerge %16 %17 None
166                OpBranch %18
167          %18 = OpLabel
168          %19 = OpLoad %8 %12
169          %22 = OpSLessThan %21 %19 %20
170                OpBranchConditional %22 %15 %16
171          %15 = OpLabel
172          %23 = OpLoad %8 %12
173          %24 = OpLoad %8 %10
174          %25 = OpIAdd %8 %24 %23
175                OpStore %10 %25
176          %26 = OpLoad %8 %10
177          %27 = OpIMul %8 %26 %11
178                OpStore %10 %27
179                OpBranch %17
180          %17 = OpLabel
181          %28 = OpLoad %8 %12
182          %30 = OpIAdd %8 %28 %29
183                OpStore %12 %30
184                OpBranch %14
185          %16 = OpLabel
186                OpReturn
187                OpFunctionEnd
188   )";
189 
190 // The SPIR-V came from this GLSL, which was then optimized using spirv-opt
191 // with the -O argument:
192 //
193 // #version 310 es
194 //
195 // precision highp float;
196 //
197 // layout(location = 0) out vec4 _GLF_color;
198 //
199 // layout(set = 0, binding = 0) uniform buf0 {
200 //  vec2 injectionSwitch;
201 // };
202 // layout(set = 0, binding = 1) uniform buf1 {
203 //  vec2 resolution;
204 // };
205 // bool checkSwap(float a, float b)
206 // {
207 //  return gl_FragCoord.y < resolution.y / 2.0 ? a > b : a < b;
208 // }
209 // void main()
210 // {
211 //  float data[10];
212 //  for(int i = 0; i < 10; i++)
213 //   {
214 //    data[i] = float(10 - i) * injectionSwitch.y;
215 //   }
216 //  for(int i = 0; i < 9; i++)
217 //   {
218 //    for(int j = 0; j < 10; j++)
219 //     {
220 //      if(j < i + 1)
221 //       {
222 //        continue;
223 //       }
224 //      bool doSwap = checkSwap(data[i], data[j]);
225 //      if(doSwap)
226 //       {
227 //        float temp = data[i];
228 //        data[i] = data[j];
229 //        data[j] = temp;
230 //       }
231 //     }
232 //   }
233 //  if(gl_FragCoord.x < resolution.x / 2.0)
234 //   {
235 //    _GLF_color = vec4(data[0] / 10.0, data[5] / 10.0, data[9] / 10.0, 1.0);
236 //   }
237 //  else
238 //   {
239 //    _GLF_color = vec4(data[5] / 10.0, data[9] / 10.0, data[0] / 10.0, 1.0);
240 //   }
241 // }
242 
243 const std::string kTestShader2 = R"(
244                OpCapability Shader
245           %1 = OpExtInstImport "GLSL.std.450"
246                OpMemoryModel Logical GLSL450
247                OpEntryPoint Fragment %4 "main" %16 %139 %25 %68
248                OpExecutionMode %4 OriginUpperLeft
249                OpSource ESSL 310
250                OpName %4 "main"
251                OpName %16 "gl_FragCoord"
252                OpName %23 "buf1"
253                OpMemberName %23 0 "resolution"
254                OpName %25 ""
255                OpName %61 "data"
256                OpName %66 "buf0"
257                OpMemberName %66 0 "injectionSwitch"
258                OpName %68 ""
259                OpName %139 "_GLF_color"
260                OpDecorate %16 BuiltIn FragCoord
261                OpMemberDecorate %23 0 Offset 0
262                OpDecorate %23 Block
263                OpDecorate %25 DescriptorSet 0
264                OpDecorate %25 Binding 1
265                OpDecorate %64 RelaxedPrecision
266                OpMemberDecorate %66 0 Offset 0
267                OpDecorate %66 Block
268                OpDecorate %68 DescriptorSet 0
269                OpDecorate %68 Binding 0
270                OpDecorate %75 RelaxedPrecision
271                OpDecorate %95 RelaxedPrecision
272                OpDecorate %126 RelaxedPrecision
273                OpDecorate %128 RelaxedPrecision
274                OpDecorate %139 Location 0
275                OpDecorate %182 RelaxedPrecision
276                OpDecorate %183 RelaxedPrecision
277                OpDecorate %184 RelaxedPrecision
278           %2 = OpTypeVoid
279           %3 = OpTypeFunction %2
280           %6 = OpTypeFloat 32
281           %7 = OpTypePointer Function %6
282           %8 = OpTypeBool
283          %14 = OpTypeVector %6 4
284          %15 = OpTypePointer Input %14
285          %16 = OpVariable %15 Input
286          %17 = OpTypeInt 32 0
287          %18 = OpConstant %17 1
288          %19 = OpTypePointer Input %6
289          %22 = OpTypeVector %6 2
290          %23 = OpTypeStruct %22
291          %24 = OpTypePointer Uniform %23
292          %25 = OpVariable %24 Uniform
293          %26 = OpTypeInt 32 1
294          %27 = OpConstant %26 0
295          %28 = OpTypePointer Uniform %6
296          %56 = OpConstant %26 10
297          %58 = OpConstant %17 10
298          %59 = OpTypeArray %6 %58
299          %60 = OpTypePointer Function %59
300          %66 = OpTypeStruct %22
301          %67 = OpTypePointer Uniform %66
302          %68 = OpVariable %67 Uniform
303          %74 = OpConstant %26 1
304          %83 = OpConstant %26 9
305         %129 = OpConstant %17 0
306         %138 = OpTypePointer Output %14
307         %139 = OpVariable %138 Output
308         %144 = OpConstant %26 5
309         %151 = OpConstant %6 1
310         %194 = OpConstant %6 0.5
311         %195 = OpConstant %6 0.100000001
312           %4 = OpFunction %2 None %3
313           %5 = OpLabel
314          %61 = OpVariable %60 Function
315                OpBranch %50
316          %50 = OpLabel
317         %182 = OpPhi %26 %27 %5 %75 %51
318          %57 = OpSLessThan %8 %182 %56
319                OpLoopMerge %52 %51 None
320                OpBranchConditional %57 %51 %52
321          %51 = OpLabel
322          %64 = OpISub %26 %56 %182
323          %65 = OpConvertSToF %6 %64
324          %69 = OpAccessChain %28 %68 %27 %18
325          %70 = OpLoad %6 %69
326          %71 = OpFMul %6 %65 %70
327          %72 = OpAccessChain %7 %61 %182
328                OpStore %72 %71
329          %75 = OpIAdd %26 %182 %74
330                OpBranch %50
331          %52 = OpLabel
332                OpBranch %77
333          %77 = OpLabel
334         %183 = OpPhi %26 %27 %52 %128 %88
335          %84 = OpSLessThan %8 %183 %83
336                OpLoopMerge %79 %88 None
337                OpBranchConditional %84 %78 %79
338          %78 = OpLabel
339                OpBranch %86
340          %86 = OpLabel
341         %184 = OpPhi %26 %27 %78 %126 %89
342          %92 = OpSLessThan %8 %184 %56
343                OpLoopMerge %1000 %89 None
344                OpBranchConditional %92 %87 %1000
345          %87 = OpLabel
346          %95 = OpIAdd %26 %183 %74
347          %96 = OpSLessThan %8 %184 %95
348                OpSelectionMerge %98 None
349                OpBranchConditional %96 %97 %98
350          %97 = OpLabel
351                OpBranch %89
352          %98 = OpLabel
353         %104 = OpAccessChain %7 %61 %183
354         %105 = OpLoad %6 %104
355         %107 = OpAccessChain %7 %61 %184
356         %108 = OpLoad %6 %107
357         %166 = OpAccessChain %19 %16 %18
358         %167 = OpLoad %6 %166
359         %168 = OpAccessChain %28 %25 %27 %18
360         %169 = OpLoad %6 %168
361         %170 = OpFMul %6 %169 %194
362         %171 = OpFOrdLessThan %8 %167 %170
363                OpSelectionMerge %172 None
364                OpBranchConditional %171 %173 %174
365         %173 = OpLabel
366         %177 = OpFOrdGreaterThan %8 %105 %108
367                OpBranch %172
368         %174 = OpLabel
369         %180 = OpFOrdLessThan %8 %105 %108
370                OpBranch %172
371         %172 = OpLabel
372         %186 = OpPhi %8 %177 %173 %180 %174
373                OpSelectionMerge %112 None
374                OpBranchConditional %186 %111 %112
375         %111 = OpLabel
376         %116 = OpLoad %6 %104
377         %120 = OpLoad %6 %107
378                OpStore %104 %120
379                OpStore %107 %116
380                OpBranch %112
381         %112 = OpLabel
382                OpBranch %89
383          %89 = OpLabel
384         %126 = OpIAdd %26 %184 %74
385                OpBranch %86
386        %1000 = OpLabel
387                OpBranch %88
388          %88 = OpLabel
389         %128 = OpIAdd %26 %183 %74
390                OpBranch %77
391          %79 = OpLabel
392         %130 = OpAccessChain %19 %16 %129
393         %131 = OpLoad %6 %130
394         %132 = OpAccessChain %28 %25 %27 %129
395         %133 = OpLoad %6 %132
396         %134 = OpFMul %6 %133 %194
397         %135 = OpFOrdLessThan %8 %131 %134
398                OpSelectionMerge %137 None
399                OpBranchConditional %135 %136 %153
400         %136 = OpLabel
401         %140 = OpAccessChain %7 %61 %27
402         %141 = OpLoad %6 %140
403         %143 = OpFMul %6 %141 %195
404         %145 = OpAccessChain %7 %61 %144
405         %146 = OpLoad %6 %145
406         %147 = OpFMul %6 %146 %195
407         %148 = OpAccessChain %7 %61 %83
408         %149 = OpLoad %6 %148
409         %150 = OpFMul %6 %149 %195
410         %152 = OpCompositeConstruct %14 %143 %147 %150 %151
411                OpStore %139 %152
412                OpBranch %137
413         %153 = OpLabel
414         %154 = OpAccessChain %7 %61 %144
415         %155 = OpLoad %6 %154
416         %156 = OpFMul %6 %155 %195
417         %157 = OpAccessChain %7 %61 %83
418         %158 = OpLoad %6 %157
419         %159 = OpFMul %6 %158 %195
420         %160 = OpAccessChain %7 %61 %27
421         %161 = OpLoad %6 %160
422         %162 = OpFMul %6 %161 %195
423         %163 = OpCompositeConstruct %14 %156 %159 %162 %151
424                OpStore %139 %163
425                OpBranch %137
426         %137 = OpLabel
427                OpReturn
428                OpFunctionEnd
429   )";
430 
431 // The SPIR-V came from this GLSL, which was then optimized using spirv-opt
432 // with the -O argument:
433 //
434 // #version 310 es
435 //
436 // precision highp float;
437 //
438 // layout(location = 0) out vec4 _GLF_color;
439 //
440 // layout(set = 0, binding = 0) uniform buf0 {
441 //  vec2 resolution;
442 // };
443 // void main(void)
444 // {
445 //  float A[50];
446 //  for(
447 //      int i = 0;
448 //      i < 200;
449 //      i ++
450 //  )
451 //   {
452 //    if(i >= int(resolution.x))
453 //     {
454 //      break;
455 //     }
456 //    if((4 * (i / 4)) == i)
457 //     {
458 //      A[i / 4] = float(i);
459 //     }
460 //   }
461 //  for(
462 //      int i = 0;
463 //      i < 50;
464 //      i ++
465 //  )
466 //   {
467 //    if(i < int(gl_FragCoord.x))
468 //     {
469 //      break;
470 //     }
471 //    if(i > 0)
472 //     {
473 //      A[i] += A[i - 1];
474 //     }
475 //   }
476 //  if(int(gl_FragCoord.x) < 20)
477 //   {
478 //    _GLF_color = vec4(A[0] / resolution.x, A[4] / resolution.y, 1.0, 1.0);
479 //   }
480 //  else
481 //   if(int(gl_FragCoord.x) < 40)
482 //    {
483 //     _GLF_color = vec4(A[5] / resolution.x, A[9] / resolution.y, 1.0, 1.0);
484 //    }
485 //   else
486 //    if(int(gl_FragCoord.x) < 60)
487 //     {
488 //      _GLF_color = vec4(A[10] / resolution.x, A[14] / resolution.y,
489 //      1.0, 1.0);
490 //     }
491 //    else
492 //     if(int(gl_FragCoord.x) < 80)
493 //      {
494 //       _GLF_color = vec4(A[15] / resolution.x, A[19] / resolution.y,
495 //       1.0, 1.0);
496 //      }
497 //     else
498 //      if(int(gl_FragCoord.x) < 100)
499 //       {
500 //        _GLF_color = vec4(A[20] / resolution.x, A[24] / resolution.y,
501 //        1.0, 1.0);
502 //       }
503 //      else
504 //       if(int(gl_FragCoord.x) < 120)
505 //        {
506 //         _GLF_color = vec4(A[25] / resolution.x, A[29] / resolution.y,
507 //         1.0, 1.0);
508 //        }
509 //       else
510 //        if(int(gl_FragCoord.x) < 140)
511 //         {
512 //          _GLF_color = vec4(A[30] / resolution.x, A[34] / resolution.y,
513 //          1.0, 1.0);
514 //         }
515 //        else
516 //         if(int(gl_FragCoord.x) < 160)
517 //          {
518 //           _GLF_color = vec4(A[35] / resolution.x, A[39] /
519 //           resolution.y, 1.0, 1.0);
520 //          }
521 //         else
522 //          if(int(gl_FragCoord.x) < 180)
523 //           {
524 //            _GLF_color = vec4(A[40] / resolution.x, A[44] /
525 //            resolution.y, 1.0, 1.0);
526 //           }
527 //          else
528 //           if(int(gl_FragCoord.x) < 180)
529 //            {
530 //             _GLF_color = vec4(A[45] / resolution.x, A[49] /
531 //             resolution.y, 1.0, 1.0);
532 //            }
533 //           else
534 //            {
535 //             discard;
536 //            }
537 // }
538 
539 const std::string kTestShader3 = R"(
540                OpCapability Shader
541           %1 = OpExtInstImport "GLSL.std.450"
542                OpMemoryModel Logical GLSL450
543                OpEntryPoint Fragment %4 "main" %68 %100 %24
544                OpExecutionMode %4 OriginUpperLeft
545                OpSource ESSL 310
546                OpName %4 "main"
547                OpName %22 "buf0"
548                OpMemberName %22 0 "resolution"
549                OpName %24 ""
550                OpName %46 "A"
551                OpName %68 "gl_FragCoord"
552                OpName %100 "_GLF_color"
553                OpMemberDecorate %22 0 Offset 0
554                OpDecorate %22 Block
555                OpDecorate %24 DescriptorSet 0
556                OpDecorate %24 Binding 0
557                OpDecorate %37 RelaxedPrecision
558                OpDecorate %38 RelaxedPrecision
559                OpDecorate %55 RelaxedPrecision
560                OpDecorate %68 BuiltIn FragCoord
561                OpDecorate %83 RelaxedPrecision
562                OpDecorate %91 RelaxedPrecision
563                OpDecorate %100 Location 0
564                OpDecorate %302 RelaxedPrecision
565                OpDecorate %304 RelaxedPrecision
566           %2 = OpTypeVoid
567           %3 = OpTypeFunction %2
568           %6 = OpTypeInt 32 1
569           %9 = OpConstant %6 0
570          %16 = OpConstant %6 200
571          %17 = OpTypeBool
572          %20 = OpTypeFloat 32
573          %21 = OpTypeVector %20 2
574          %22 = OpTypeStruct %21
575          %23 = OpTypePointer Uniform %22
576          %24 = OpVariable %23 Uniform
577          %25 = OpTypeInt 32 0
578          %26 = OpConstant %25 0
579          %27 = OpTypePointer Uniform %20
580          %35 = OpConstant %6 4
581          %43 = OpConstant %25 50
582          %44 = OpTypeArray %20 %43
583          %45 = OpTypePointer Function %44
584          %51 = OpTypePointer Function %20
585          %54 = OpConstant %6 1
586          %63 = OpConstant %6 50
587          %66 = OpTypeVector %20 4
588          %67 = OpTypePointer Input %66
589          %68 = OpVariable %67 Input
590          %69 = OpTypePointer Input %20
591          %95 = OpConstant %6 20
592          %99 = OpTypePointer Output %66
593         %100 = OpVariable %99 Output
594         %108 = OpConstant %25 1
595         %112 = OpConstant %20 1
596         %118 = OpConstant %6 40
597         %122 = OpConstant %6 5
598         %128 = OpConstant %6 9
599         %139 = OpConstant %6 60
600         %143 = OpConstant %6 10
601         %149 = OpConstant %6 14
602         %160 = OpConstant %6 80
603         %164 = OpConstant %6 15
604         %170 = OpConstant %6 19
605         %181 = OpConstant %6 100
606         %190 = OpConstant %6 24
607         %201 = OpConstant %6 120
608         %205 = OpConstant %6 25
609         %211 = OpConstant %6 29
610         %222 = OpConstant %6 140
611         %226 = OpConstant %6 30
612         %232 = OpConstant %6 34
613         %243 = OpConstant %6 160
614         %247 = OpConstant %6 35
615         %253 = OpConstant %6 39
616         %264 = OpConstant %6 180
617         %273 = OpConstant %6 44
618         %287 = OpConstant %6 45
619         %293 = OpConstant %6 49
620           %4 = OpFunction %2 None %3
621           %5 = OpLabel
622          %46 = OpVariable %45 Function
623                OpBranch %10
624          %10 = OpLabel
625         %302 = OpPhi %6 %9 %5 %55 %42
626          %18 = OpSLessThan %17 %302 %16
627                OpLoopMerge %12 %42 None
628                OpBranchConditional %18 %11 %12
629          %11 = OpLabel
630          %28 = OpAccessChain %27 %24 %9 %26
631          %29 = OpLoad %20 %28
632          %30 = OpConvertFToS %6 %29
633          %31 = OpSGreaterThanEqual %17 %302 %30
634                OpSelectionMerge %33 None
635                OpBranchConditional %31 %32 %33
636          %32 = OpLabel
637                OpBranch %12
638          %33 = OpLabel
639          %37 = OpSDiv %6 %302 %35
640          %38 = OpIMul %6 %35 %37
641          %40 = OpIEqual %17 %38 %302
642                OpBranchConditional %40 %41 %42
643          %41 = OpLabel
644          %50 = OpConvertSToF %20 %302
645          %52 = OpAccessChain %51 %46 %37
646                OpStore %52 %50
647                OpBranch %42
648          %42 = OpLabel
649          %55 = OpIAdd %6 %302 %54
650                OpBranch %10
651          %12 = OpLabel
652                OpBranch %57
653          %57 = OpLabel
654         %304 = OpPhi %6 %9 %12 %91 %80
655          %64 = OpSLessThan %17 %304 %63
656                OpLoopMerge %59 %80 None
657                OpBranchConditional %64 %58 %59
658          %58 = OpLabel
659          %70 = OpAccessChain %69 %68 %26
660          %71 = OpLoad %20 %70
661          %72 = OpConvertFToS %6 %71
662          %73 = OpSLessThan %17 %304 %72
663                OpSelectionMerge %75 None
664                OpBranchConditional %73 %74 %75
665          %74 = OpLabel
666                OpBranch %59
667          %75 = OpLabel
668          %78 = OpSGreaterThan %17 %304 %9
669                OpBranchConditional %78 %79 %80
670          %79 = OpLabel
671          %83 = OpISub %6 %304 %54
672          %84 = OpAccessChain %51 %46 %83
673          %85 = OpLoad %20 %84
674          %86 = OpAccessChain %51 %46 %304
675          %87 = OpLoad %20 %86
676          %88 = OpFAdd %20 %87 %85
677                OpStore %86 %88
678                OpBranch %80
679          %80 = OpLabel
680          %91 = OpIAdd %6 %304 %54
681                OpBranch %57
682          %59 = OpLabel
683          %92 = OpAccessChain %69 %68 %26
684          %93 = OpLoad %20 %92
685          %94 = OpConvertFToS %6 %93
686          %96 = OpSLessThan %17 %94 %95
687                OpSelectionMerge %98 None
688                OpBranchConditional %96 %97 %114
689          %97 = OpLabel
690         %101 = OpAccessChain %51 %46 %9
691         %102 = OpLoad %20 %101
692         %103 = OpAccessChain %27 %24 %9 %26
693         %104 = OpLoad %20 %103
694         %105 = OpFDiv %20 %102 %104
695         %106 = OpAccessChain %51 %46 %35
696         %107 = OpLoad %20 %106
697         %109 = OpAccessChain %27 %24 %9 %108
698         %110 = OpLoad %20 %109
699         %111 = OpFDiv %20 %107 %110
700         %113 = OpCompositeConstruct %66 %105 %111 %112 %112
701                OpStore %100 %113
702                OpBranch %98
703         %114 = OpLabel
704         %119 = OpSLessThan %17 %94 %118
705                OpSelectionMerge %121 None
706                OpBranchConditional %119 %120 %135
707         %120 = OpLabel
708         %123 = OpAccessChain %51 %46 %122
709         %124 = OpLoad %20 %123
710         %125 = OpAccessChain %27 %24 %9 %26
711         %126 = OpLoad %20 %125
712         %127 = OpFDiv %20 %124 %126
713         %129 = OpAccessChain %51 %46 %128
714         %130 = OpLoad %20 %129
715         %131 = OpAccessChain %27 %24 %9 %108
716         %132 = OpLoad %20 %131
717         %133 = OpFDiv %20 %130 %132
718         %134 = OpCompositeConstruct %66 %127 %133 %112 %112
719                OpStore %100 %134
720                OpBranch %121
721         %135 = OpLabel
722         %140 = OpSLessThan %17 %94 %139
723                OpSelectionMerge %142 None
724                OpBranchConditional %140 %141 %156
725         %141 = OpLabel
726         %144 = OpAccessChain %51 %46 %143
727         %145 = OpLoad %20 %144
728         %146 = OpAccessChain %27 %24 %9 %26
729         %147 = OpLoad %20 %146
730         %148 = OpFDiv %20 %145 %147
731         %150 = OpAccessChain %51 %46 %149
732         %151 = OpLoad %20 %150
733         %152 = OpAccessChain %27 %24 %9 %108
734         %153 = OpLoad %20 %152
735         %154 = OpFDiv %20 %151 %153
736         %155 = OpCompositeConstruct %66 %148 %154 %112 %112
737                OpStore %100 %155
738                OpBranch %142
739         %156 = OpLabel
740         %161 = OpSLessThan %17 %94 %160
741                OpSelectionMerge %163 None
742                OpBranchConditional %161 %162 %177
743         %162 = OpLabel
744         %165 = OpAccessChain %51 %46 %164
745         %166 = OpLoad %20 %165
746         %167 = OpAccessChain %27 %24 %9 %26
747         %168 = OpLoad %20 %167
748         %169 = OpFDiv %20 %166 %168
749         %171 = OpAccessChain %51 %46 %170
750         %172 = OpLoad %20 %171
751         %173 = OpAccessChain %27 %24 %9 %108
752         %174 = OpLoad %20 %173
753         %175 = OpFDiv %20 %172 %174
754         %176 = OpCompositeConstruct %66 %169 %175 %112 %112
755                OpStore %100 %176
756                OpBranch %163
757         %177 = OpLabel
758         %182 = OpSLessThan %17 %94 %181
759                OpSelectionMerge %184 None
760                OpBranchConditional %182 %183 %197
761         %183 = OpLabel
762         %185 = OpAccessChain %51 %46 %95
763         %186 = OpLoad %20 %185
764         %187 = OpAccessChain %27 %24 %9 %26
765         %188 = OpLoad %20 %187
766         %189 = OpFDiv %20 %186 %188
767         %191 = OpAccessChain %51 %46 %190
768         %192 = OpLoad %20 %191
769         %193 = OpAccessChain %27 %24 %9 %108
770         %194 = OpLoad %20 %193
771         %195 = OpFDiv %20 %192 %194
772         %196 = OpCompositeConstruct %66 %189 %195 %112 %112
773                OpStore %100 %196
774                OpBranch %184
775         %197 = OpLabel
776         %202 = OpSLessThan %17 %94 %201
777                OpSelectionMerge %204 None
778                OpBranchConditional %202 %203 %218
779         %203 = OpLabel
780         %206 = OpAccessChain %51 %46 %205
781         %207 = OpLoad %20 %206
782         %208 = OpAccessChain %27 %24 %9 %26
783         %209 = OpLoad %20 %208
784         %210 = OpFDiv %20 %207 %209
785         %212 = OpAccessChain %51 %46 %211
786         %213 = OpLoad %20 %212
787         %214 = OpAccessChain %27 %24 %9 %108
788         %215 = OpLoad %20 %214
789         %216 = OpFDiv %20 %213 %215
790         %217 = OpCompositeConstruct %66 %210 %216 %112 %112
791                OpStore %100 %217
792                OpBranch %204
793         %218 = OpLabel
794         %223 = OpSLessThan %17 %94 %222
795                OpSelectionMerge %225 None
796                OpBranchConditional %223 %224 %239
797         %224 = OpLabel
798         %227 = OpAccessChain %51 %46 %226
799         %228 = OpLoad %20 %227
800         %229 = OpAccessChain %27 %24 %9 %26
801         %230 = OpLoad %20 %229
802         %231 = OpFDiv %20 %228 %230
803         %233 = OpAccessChain %51 %46 %232
804         %234 = OpLoad %20 %233
805         %235 = OpAccessChain %27 %24 %9 %108
806         %236 = OpLoad %20 %235
807         %237 = OpFDiv %20 %234 %236
808         %238 = OpCompositeConstruct %66 %231 %237 %112 %112
809                OpStore %100 %238
810                OpBranch %225
811         %239 = OpLabel
812         %244 = OpSLessThan %17 %94 %243
813                OpSelectionMerge %246 None
814                OpBranchConditional %244 %245 %260
815         %245 = OpLabel
816         %248 = OpAccessChain %51 %46 %247
817         %249 = OpLoad %20 %248
818         %250 = OpAccessChain %27 %24 %9 %26
819         %251 = OpLoad %20 %250
820         %252 = OpFDiv %20 %249 %251
821         %254 = OpAccessChain %51 %46 %253
822         %255 = OpLoad %20 %254
823         %256 = OpAccessChain %27 %24 %9 %108
824         %257 = OpLoad %20 %256
825         %258 = OpFDiv %20 %255 %257
826         %259 = OpCompositeConstruct %66 %252 %258 %112 %112
827                OpStore %100 %259
828                OpBranch %246
829         %260 = OpLabel
830         %265 = OpSLessThan %17 %94 %264
831                OpSelectionMerge %267 None
832                OpBranchConditional %265 %266 %280
833         %266 = OpLabel
834         %268 = OpAccessChain %51 %46 %118
835         %269 = OpLoad %20 %268
836         %270 = OpAccessChain %27 %24 %9 %26
837         %271 = OpLoad %20 %270
838         %272 = OpFDiv %20 %269 %271
839         %274 = OpAccessChain %51 %46 %273
840         %275 = OpLoad %20 %274
841         %276 = OpAccessChain %27 %24 %9 %108
842         %277 = OpLoad %20 %276
843         %278 = OpFDiv %20 %275 %277
844         %279 = OpCompositeConstruct %66 %272 %278 %112 %112
845                OpStore %100 %279
846                OpBranch %267
847         %280 = OpLabel
848                OpSelectionMerge %285 None
849                OpBranchConditional %265 %285 %300
850         %285 = OpLabel
851         %288 = OpAccessChain %51 %46 %287
852         %289 = OpLoad %20 %288
853         %290 = OpAccessChain %27 %24 %9 %26
854         %291 = OpLoad %20 %290
855         %292 = OpFDiv %20 %289 %291
856         %294 = OpAccessChain %51 %46 %293
857         %295 = OpLoad %20 %294
858         %296 = OpAccessChain %27 %24 %9 %108
859         %297 = OpLoad %20 %296
860         %298 = OpFDiv %20 %295 %297
861         %299 = OpCompositeConstruct %66 %292 %298 %112 %112
862                OpStore %100 %299
863                OpBranch %267
864         %300 = OpLabel
865                OpKill
866         %267 = OpLabel
867                OpBranch %246
868         %246 = OpLabel
869                OpBranch %225
870         %225 = OpLabel
871                OpBranch %204
872         %204 = OpLabel
873                OpBranch %184
874         %184 = OpLabel
875                OpBranch %163
876         %163 = OpLabel
877                OpBranch %142
878         %142 = OpLabel
879                OpBranch %121
880         %121 = OpLabel
881                OpBranch %98
882          %98 = OpLabel
883                OpReturn
884                OpFunctionEnd
885   )";
886 
887 // The SPIR-V comes from the 'matrices_smart_loops' GLSL shader that ships
888 // with GraphicsFuzz.
889 
890 const std::string kTestShader4 = R"(
891                OpCapability Shader
892           %1 = OpExtInstImport "GLSL.std.450"
893                OpMemoryModel Logical GLSL450
894                OpEntryPoint Fragment %4 "main" %327 %363 %65 %70 %80 %90 %99 %108 %117 %126 %135 %144 %333
895                OpExecutionMode %4 OriginUpperLeft
896                OpSource ESSL 310
897                OpName %4 "main"
898                OpName %8 "matrix_number"
899                OpName %12 "cols"
900                OpName %23 "rows"
901                OpName %31 "c"
902                OpName %41 "r"
903                OpName %65 "m22"
904                OpName %68 "buf0"
905                OpMemberName %68 0 "one"
906                OpName %70 ""
907                OpName %80 "m23"
908                OpName %90 "m24"
909                OpName %99 "m32"
910                OpName %108 "m33"
911                OpName %117 "m34"
912                OpName %126 "m42"
913                OpName %135 "m43"
914                OpName %144 "m44"
915                OpName %164 "sum_index"
916                OpName %165 "cols"
917                OpName %173 "rows"
918                OpName %184 "sums"
919                OpName %189 "c"
920                OpName %198 "r"
921                OpName %325 "region_x"
922                OpName %327 "gl_FragCoord"
923                OpName %331 "buf1"
924                OpMemberName %331 0 "resolution"
925                OpName %333 ""
926                OpName %340 "region_y"
927                OpName %348 "overall_region"
928                OpName %363 "_GLF_color"
929                OpDecorate %8 RelaxedPrecision
930                OpDecorate %12 RelaxedPrecision
931                OpDecorate %19 RelaxedPrecision
932                OpDecorate %23 RelaxedPrecision
933                OpDecorate %29 RelaxedPrecision
934                OpDecorate %31 RelaxedPrecision
935                OpDecorate %38 RelaxedPrecision
936                OpDecorate %39 RelaxedPrecision
937                OpDecorate %41 RelaxedPrecision
938                OpDecorate %47 RelaxedPrecision
939                OpDecorate %48 RelaxedPrecision
940                OpDecorate %50 RelaxedPrecision
941                OpDecorate %66 RelaxedPrecision
942                OpDecorate %67 RelaxedPrecision
943                OpMemberDecorate %68 0 Offset 0
944                OpDecorate %68 Block
945                OpDecorate %70 DescriptorSet 0
946                OpDecorate %70 Binding 0
947                OpDecorate %81 RelaxedPrecision
948                OpDecorate %82 RelaxedPrecision
949                OpDecorate %91 RelaxedPrecision
950                OpDecorate %92 RelaxedPrecision
951                OpDecorate %100 RelaxedPrecision
952                OpDecorate %101 RelaxedPrecision
953                OpDecorate %109 RelaxedPrecision
954                OpDecorate %110 RelaxedPrecision
955                OpDecorate %118 RelaxedPrecision
956                OpDecorate %119 RelaxedPrecision
957                OpDecorate %127 RelaxedPrecision
958                OpDecorate %128 RelaxedPrecision
959                OpDecorate %136 RelaxedPrecision
960                OpDecorate %137 RelaxedPrecision
961                OpDecorate %145 RelaxedPrecision
962                OpDecorate %146 RelaxedPrecision
963                OpDecorate %152 RelaxedPrecision
964                OpDecorate %154 RelaxedPrecision
965                OpDecorate %155 RelaxedPrecision
966                OpDecorate %156 RelaxedPrecision
967                OpDecorate %157 RelaxedPrecision
968                OpDecorate %159 RelaxedPrecision
969                OpDecorate %160 RelaxedPrecision
970                OpDecorate %161 RelaxedPrecision
971                OpDecorate %162 RelaxedPrecision
972                OpDecorate %163 RelaxedPrecision
973                OpDecorate %164 RelaxedPrecision
974                OpDecorate %165 RelaxedPrecision
975                OpDecorate %171 RelaxedPrecision
976                OpDecorate %173 RelaxedPrecision
977                OpDecorate %179 RelaxedPrecision
978                OpDecorate %185 RelaxedPrecision
979                OpDecorate %189 RelaxedPrecision
980                OpDecorate %195 RelaxedPrecision
981                OpDecorate %196 RelaxedPrecision
982                OpDecorate %198 RelaxedPrecision
983                OpDecorate %204 RelaxedPrecision
984                OpDecorate %205 RelaxedPrecision
985                OpDecorate %207 RelaxedPrecision
986                OpDecorate %218 RelaxedPrecision
987                OpDecorate %219 RelaxedPrecision
988                OpDecorate %220 RelaxedPrecision
989                OpDecorate %228 RelaxedPrecision
990                OpDecorate %229 RelaxedPrecision
991                OpDecorate %230 RelaxedPrecision
992                OpDecorate %238 RelaxedPrecision
993                OpDecorate %239 RelaxedPrecision
994                OpDecorate %240 RelaxedPrecision
995                OpDecorate %248 RelaxedPrecision
996                OpDecorate %249 RelaxedPrecision
997                OpDecorate %250 RelaxedPrecision
998                OpDecorate %258 RelaxedPrecision
999                OpDecorate %259 RelaxedPrecision
1000                OpDecorate %260 RelaxedPrecision
1001                OpDecorate %268 RelaxedPrecision
1002                OpDecorate %269 RelaxedPrecision
1003                OpDecorate %270 RelaxedPrecision
1004                OpDecorate %278 RelaxedPrecision
1005                OpDecorate %279 RelaxedPrecision
1006                OpDecorate %280 RelaxedPrecision
1007                OpDecorate %288 RelaxedPrecision
1008                OpDecorate %289 RelaxedPrecision
1009                OpDecorate %290 RelaxedPrecision
1010                OpDecorate %298 RelaxedPrecision
1011                OpDecorate %299 RelaxedPrecision
1012                OpDecorate %300 RelaxedPrecision
1013                OpDecorate %309 RelaxedPrecision
1014                OpDecorate %310 RelaxedPrecision
1015                OpDecorate %311 RelaxedPrecision
1016                OpDecorate %312 RelaxedPrecision
1017                OpDecorate %313 RelaxedPrecision
1018                OpDecorate %319 RelaxedPrecision
1019                OpDecorate %320 RelaxedPrecision
1020                OpDecorate %321 RelaxedPrecision
1021                OpDecorate %322 RelaxedPrecision
1022                OpDecorate %323 RelaxedPrecision
1023                OpDecorate %324 RelaxedPrecision
1024                OpDecorate %325 RelaxedPrecision
1025                OpDecorate %327 BuiltIn FragCoord
1026                OpMemberDecorate %331 0 Offset 0
1027                OpDecorate %331 Block
1028                OpDecorate %333 DescriptorSet 0
1029                OpDecorate %333 Binding 1
1030                OpDecorate %339 RelaxedPrecision
1031                OpDecorate %340 RelaxedPrecision
1032                OpDecorate %347 RelaxedPrecision
1033                OpDecorate %348 RelaxedPrecision
1034                OpDecorate %349 RelaxedPrecision
1035                OpDecorate %351 RelaxedPrecision
1036                OpDecorate %352 RelaxedPrecision
1037                OpDecorate %353 RelaxedPrecision
1038                OpDecorate %354 RelaxedPrecision
1039                OpDecorate %356 RelaxedPrecision
1040                OpDecorate %363 Location 0
1041                OpDecorate %364 RelaxedPrecision
1042           %2 = OpTypeVoid
1043           %3 = OpTypeFunction %2
1044           %6 = OpTypeInt 32 0
1045           %7 = OpTypePointer Function %6
1046           %9 = OpConstant %6 0
1047          %10 = OpTypeInt 32 1
1048          %11 = OpTypePointer Function %10
1049          %13 = OpConstant %10 2
1050          %20 = OpConstant %10 4
1051          %21 = OpTypeBool
1052          %32 = OpConstant %10 0
1053          %61 = OpTypeFloat 32
1054          %62 = OpTypeVector %61 2
1055          %63 = OpTypeMatrix %62 2
1056          %64 = OpTypePointer Private %63
1057          %65 = OpVariable %64 Private
1058          %68 = OpTypeStruct %61
1059          %69 = OpTypePointer Uniform %68
1060          %70 = OpVariable %69 Uniform
1061          %71 = OpTypePointer Uniform %61
1062          %74 = OpTypePointer Private %61
1063          %77 = OpTypeVector %61 3
1064          %78 = OpTypeMatrix %77 2
1065          %79 = OpTypePointer Private %78
1066          %80 = OpVariable %79 Private
1067          %87 = OpTypeVector %61 4
1068          %88 = OpTypeMatrix %87 2
1069          %89 = OpTypePointer Private %88
1070          %90 = OpVariable %89 Private
1071          %97 = OpTypeMatrix %62 3
1072          %98 = OpTypePointer Private %97
1073          %99 = OpVariable %98 Private
1074         %106 = OpTypeMatrix %77 3
1075         %107 = OpTypePointer Private %106
1076         %108 = OpVariable %107 Private
1077         %115 = OpTypeMatrix %87 3
1078         %116 = OpTypePointer Private %115
1079         %117 = OpVariable %116 Private
1080         %124 = OpTypeMatrix %62 4
1081         %125 = OpTypePointer Private %124
1082         %126 = OpVariable %125 Private
1083         %133 = OpTypeMatrix %77 4
1084         %134 = OpTypePointer Private %133
1085         %135 = OpVariable %134 Private
1086         %142 = OpTypeMatrix %87 4
1087         %143 = OpTypePointer Private %142
1088         %144 = OpVariable %143 Private
1089         %153 = OpConstant %10 1
1090         %158 = OpConstant %6 1
1091         %181 = OpConstant %6 9
1092         %182 = OpTypeArray %61 %181
1093         %183 = OpTypePointer Function %182
1094         %186 = OpConstant %61 0
1095         %187 = OpTypePointer Function %61
1096         %314 = OpConstant %61 16
1097         %326 = OpTypePointer Input %87
1098         %327 = OpVariable %326 Input
1099         %328 = OpTypePointer Input %61
1100         %331 = OpTypeStruct %62
1101         %332 = OpTypePointer Uniform %331
1102         %333 = OpVariable %332 Uniform
1103         %336 = OpConstant %61 3
1104         %350 = OpConstant %10 3
1105         %357 = OpConstant %10 9
1106         %362 = OpTypePointer Output %87
1107         %363 = OpVariable %362 Output
1108         %368 = OpConstant %61 1
1109         %374 = OpConstantComposite %87 %186 %186 %186 %368
1110           %4 = OpFunction %2 None %3
1111           %5 = OpLabel
1112           %8 = OpVariable %7 Function
1113          %12 = OpVariable %11 Function
1114          %23 = OpVariable %11 Function
1115          %31 = OpVariable %11 Function
1116          %41 = OpVariable %11 Function
1117         %164 = OpVariable %11 Function
1118         %165 = OpVariable %11 Function
1119         %173 = OpVariable %11 Function
1120         %184 = OpVariable %183 Function
1121         %189 = OpVariable %11 Function
1122         %198 = OpVariable %11 Function
1123         %325 = OpVariable %11 Function
1124         %340 = OpVariable %11 Function
1125         %348 = OpVariable %11 Function
1126                OpStore %8 %9
1127                OpStore %12 %13
1128                OpBranch %14
1129          %14 = OpLabel
1130                OpLoopMerge %16 %17 None
1131                OpBranch %18
1132          %18 = OpLabel
1133          %19 = OpLoad %10 %12
1134          %22 = OpSLessThanEqual %21 %19 %20
1135                OpBranchConditional %22 %15 %16
1136          %15 = OpLabel
1137                OpStore %23 %13
1138                OpBranch %24
1139          %24 = OpLabel
1140                OpLoopMerge %26 %27 None
1141                OpBranch %28
1142          %28 = OpLabel
1143          %29 = OpLoad %10 %23
1144          %30 = OpSLessThanEqual %21 %29 %20
1145                OpBranchConditional %30 %25 %26
1146          %25 = OpLabel
1147                OpStore %31 %32
1148                OpBranch %33
1149          %33 = OpLabel
1150                OpLoopMerge %35 %36 None
1151                OpBranch %37
1152          %37 = OpLabel
1153          %38 = OpLoad %10 %31
1154          %39 = OpLoad %10 %12
1155          %40 = OpSLessThan %21 %38 %39
1156                OpBranchConditional %40 %34 %35
1157          %34 = OpLabel
1158                OpStore %41 %32
1159                OpBranch %42
1160          %42 = OpLabel
1161                OpLoopMerge %44 %45 None
1162                OpBranch %46
1163          %46 = OpLabel
1164          %47 = OpLoad %10 %41
1165          %48 = OpLoad %10 %23
1166          %49 = OpSLessThan %21 %47 %48
1167                OpBranchConditional %49 %43 %44
1168          %43 = OpLabel
1169          %50 = OpLoad %6 %8
1170                OpSelectionMerge %60 None
1171                OpSwitch %50 %60 0 %51 1 %52 2 %53 3 %54 4 %55 5 %56 6 %57 7 %58 8 %59
1172          %51 = OpLabel
1173          %66 = OpLoad %10 %31
1174          %67 = OpLoad %10 %41
1175          %72 = OpAccessChain %71 %70 %32
1176          %73 = OpLoad %61 %72
1177          %75 = OpAccessChain %74 %65 %66 %67
1178                OpStore %75 %73
1179                OpBranch %60
1180          %52 = OpLabel
1181          %81 = OpLoad %10 %31
1182          %82 = OpLoad %10 %41
1183          %83 = OpAccessChain %71 %70 %32
1184          %84 = OpLoad %61 %83
1185          %85 = OpAccessChain %74 %80 %81 %82
1186                OpStore %85 %84
1187                OpBranch %60
1188          %53 = OpLabel
1189          %91 = OpLoad %10 %31
1190          %92 = OpLoad %10 %41
1191          %93 = OpAccessChain %71 %70 %32
1192          %94 = OpLoad %61 %93
1193          %95 = OpAccessChain %74 %90 %91 %92
1194                OpStore %95 %94
1195                OpBranch %60
1196          %54 = OpLabel
1197         %100 = OpLoad %10 %31
1198         %101 = OpLoad %10 %41
1199         %102 = OpAccessChain %71 %70 %32
1200         %103 = OpLoad %61 %102
1201         %104 = OpAccessChain %74 %99 %100 %101
1202                OpStore %104 %103
1203                OpBranch %60
1204          %55 = OpLabel
1205         %109 = OpLoad %10 %31
1206         %110 = OpLoad %10 %41
1207         %111 = OpAccessChain %71 %70 %32
1208         %112 = OpLoad %61 %111
1209         %113 = OpAccessChain %74 %108 %109 %110
1210                OpStore %113 %112
1211                OpBranch %60
1212          %56 = OpLabel
1213         %118 = OpLoad %10 %31
1214         %119 = OpLoad %10 %41
1215         %120 = OpAccessChain %71 %70 %32
1216         %121 = OpLoad %61 %120
1217         %122 = OpAccessChain %74 %117 %118 %119
1218                OpStore %122 %121
1219                OpBranch %60
1220          %57 = OpLabel
1221         %127 = OpLoad %10 %31
1222         %128 = OpLoad %10 %41
1223         %129 = OpAccessChain %71 %70 %32
1224         %130 = OpLoad %61 %129
1225         %131 = OpAccessChain %74 %126 %127 %128
1226                OpStore %131 %130
1227                OpBranch %60
1228          %58 = OpLabel
1229         %136 = OpLoad %10 %31
1230         %137 = OpLoad %10 %41
1231         %138 = OpAccessChain %71 %70 %32
1232         %139 = OpLoad %61 %138
1233         %140 = OpAccessChain %74 %135 %136 %137
1234                OpStore %140 %139
1235                OpBranch %60
1236          %59 = OpLabel
1237         %145 = OpLoad %10 %31
1238         %146 = OpLoad %10 %41
1239         %147 = OpAccessChain %71 %70 %32
1240         %148 = OpLoad %61 %147
1241         %149 = OpAccessChain %74 %144 %145 %146
1242                OpStore %149 %148
1243                OpBranch %60
1244          %60 = OpLabel
1245                OpBranch %45
1246          %45 = OpLabel
1247         %152 = OpLoad %10 %41
1248         %154 = OpIAdd %10 %152 %153
1249                OpStore %41 %154
1250                OpBranch %42
1251          %44 = OpLabel
1252                OpBranch %36
1253          %36 = OpLabel
1254         %155 = OpLoad %10 %31
1255         %156 = OpIAdd %10 %155 %153
1256                OpStore %31 %156
1257                OpBranch %33
1258          %35 = OpLabel
1259         %157 = OpLoad %6 %8
1260         %159 = OpIAdd %6 %157 %158
1261                OpStore %8 %159
1262                OpBranch %27
1263          %27 = OpLabel
1264         %160 = OpLoad %10 %23
1265         %161 = OpIAdd %10 %160 %153
1266                OpStore %23 %161
1267                OpBranch %24
1268          %26 = OpLabel
1269                OpBranch %17
1270          %17 = OpLabel
1271         %162 = OpLoad %10 %12
1272         %163 = OpIAdd %10 %162 %153
1273                OpStore %12 %163
1274                OpBranch %14
1275          %16 = OpLabel
1276                OpStore %164 %32
1277                OpStore %165 %13
1278                OpBranch %166
1279         %166 = OpLabel
1280                OpLoopMerge %168 %169 None
1281                OpBranch %170
1282         %170 = OpLabel
1283         %171 = OpLoad %10 %165
1284         %172 = OpSLessThanEqual %21 %171 %20
1285                OpBranchConditional %172 %167 %168
1286         %167 = OpLabel
1287                OpStore %173 %13
1288                OpBranch %174
1289         %174 = OpLabel
1290                OpLoopMerge %176 %177 None
1291                OpBranch %178
1292         %178 = OpLabel
1293         %179 = OpLoad %10 %173
1294         %180 = OpSLessThanEqual %21 %179 %20
1295                OpBranchConditional %180 %175 %176
1296         %175 = OpLabel
1297         %185 = OpLoad %10 %164
1298         %188 = OpAccessChain %187 %184 %185
1299                OpStore %188 %186
1300                OpStore %189 %32
1301                OpBranch %190
1302         %190 = OpLabel
1303                OpLoopMerge %192 %193 None
1304                OpBranch %194
1305         %194 = OpLabel
1306         %195 = OpLoad %10 %189
1307         %196 = OpLoad %10 %165
1308         %197 = OpSLessThan %21 %195 %196
1309                OpBranchConditional %197 %191 %192
1310         %191 = OpLabel
1311                OpStore %198 %32
1312                OpBranch %199
1313         %199 = OpLabel
1314                OpLoopMerge %201 %202 None
1315                OpBranch %203
1316         %203 = OpLabel
1317         %204 = OpLoad %10 %198
1318         %205 = OpLoad %10 %173
1319         %206 = OpSLessThan %21 %204 %205
1320                OpBranchConditional %206 %200 %201
1321         %200 = OpLabel
1322         %207 = OpLoad %10 %164
1323                OpSelectionMerge %217 None
1324                OpSwitch %207 %217 0 %208 1 %209 2 %210 3 %211 4 %212 5 %213 6 %214 7 %215 8 %216
1325         %208 = OpLabel
1326         %218 = OpLoad %10 %164
1327         %219 = OpLoad %10 %189
1328         %220 = OpLoad %10 %198
1329         %221 = OpAccessChain %74 %65 %219 %220
1330         %222 = OpLoad %61 %221
1331         %223 = OpAccessChain %187 %184 %218
1332         %224 = OpLoad %61 %223
1333         %225 = OpFAdd %61 %224 %222
1334         %226 = OpAccessChain %187 %184 %218
1335                OpStore %226 %225
1336                OpBranch %217
1337         %209 = OpLabel
1338         %228 = OpLoad %10 %164
1339         %229 = OpLoad %10 %189
1340         %230 = OpLoad %10 %198
1341         %231 = OpAccessChain %74 %80 %229 %230
1342         %232 = OpLoad %61 %231
1343         %233 = OpAccessChain %187 %184 %228
1344         %234 = OpLoad %61 %233
1345         %235 = OpFAdd %61 %234 %232
1346         %236 = OpAccessChain %187 %184 %228
1347                OpStore %236 %235
1348                OpBranch %217
1349         %210 = OpLabel
1350         %238 = OpLoad %10 %164
1351         %239 = OpLoad %10 %189
1352         %240 = OpLoad %10 %198
1353         %241 = OpAccessChain %74 %90 %239 %240
1354         %242 = OpLoad %61 %241
1355         %243 = OpAccessChain %187 %184 %238
1356         %244 = OpLoad %61 %243
1357         %245 = OpFAdd %61 %244 %242
1358         %246 = OpAccessChain %187 %184 %238
1359                OpStore %246 %245
1360                OpBranch %217
1361         %211 = OpLabel
1362         %248 = OpLoad %10 %164
1363         %249 = OpLoad %10 %189
1364         %250 = OpLoad %10 %198
1365         %251 = OpAccessChain %74 %99 %249 %250
1366         %252 = OpLoad %61 %251
1367         %253 = OpAccessChain %187 %184 %248
1368         %254 = OpLoad %61 %253
1369         %255 = OpFAdd %61 %254 %252
1370         %256 = OpAccessChain %187 %184 %248
1371                OpStore %256 %255
1372                OpBranch %217
1373         %212 = OpLabel
1374         %258 = OpLoad %10 %164
1375         %259 = OpLoad %10 %189
1376         %260 = OpLoad %10 %198
1377         %261 = OpAccessChain %74 %108 %259 %260
1378         %262 = OpLoad %61 %261
1379         %263 = OpAccessChain %187 %184 %258
1380         %264 = OpLoad %61 %263
1381         %265 = OpFAdd %61 %264 %262
1382         %266 = OpAccessChain %187 %184 %258
1383                OpStore %266 %265
1384                OpBranch %217
1385         %213 = OpLabel
1386         %268 = OpLoad %10 %164
1387         %269 = OpLoad %10 %189
1388         %270 = OpLoad %10 %198
1389         %271 = OpAccessChain %74 %117 %269 %270
1390         %272 = OpLoad %61 %271
1391         %273 = OpAccessChain %187 %184 %268
1392         %274 = OpLoad %61 %273
1393         %275 = OpFAdd %61 %274 %272
1394         %276 = OpAccessChain %187 %184 %268
1395                OpStore %276 %275
1396                OpBranch %217
1397         %214 = OpLabel
1398         %278 = OpLoad %10 %164
1399         %279 = OpLoad %10 %189
1400         %280 = OpLoad %10 %198
1401         %281 = OpAccessChain %74 %126 %279 %280
1402         %282 = OpLoad %61 %281
1403         %283 = OpAccessChain %187 %184 %278
1404         %284 = OpLoad %61 %283
1405         %285 = OpFAdd %61 %284 %282
1406         %286 = OpAccessChain %187 %184 %278
1407                OpStore %286 %285
1408                OpBranch %217
1409         %215 = OpLabel
1410         %288 = OpLoad %10 %164
1411         %289 = OpLoad %10 %189
1412         %290 = OpLoad %10 %198
1413         %291 = OpAccessChain %74 %135 %289 %290
1414         %292 = OpLoad %61 %291
1415         %293 = OpAccessChain %187 %184 %288
1416         %294 = OpLoad %61 %293
1417         %295 = OpFAdd %61 %294 %292
1418         %296 = OpAccessChain %187 %184 %288
1419                OpStore %296 %295
1420                OpBranch %217
1421         %216 = OpLabel
1422         %298 = OpLoad %10 %164
1423         %299 = OpLoad %10 %189
1424         %300 = OpLoad %10 %198
1425         %301 = OpAccessChain %74 %144 %299 %300
1426         %302 = OpLoad %61 %301
1427         %303 = OpAccessChain %187 %184 %298
1428         %304 = OpLoad %61 %303
1429         %305 = OpFAdd %61 %304 %302
1430         %306 = OpAccessChain %187 %184 %298
1431                OpStore %306 %305
1432                OpBranch %217
1433         %217 = OpLabel
1434                OpBranch %202
1435         %202 = OpLabel
1436         %309 = OpLoad %10 %198
1437         %310 = OpIAdd %10 %309 %153
1438                OpStore %198 %310
1439                OpBranch %199
1440         %201 = OpLabel
1441                OpBranch %193
1442         %193 = OpLabel
1443         %311 = OpLoad %10 %189
1444         %312 = OpIAdd %10 %311 %153
1445                OpStore %189 %312
1446                OpBranch %190
1447         %192 = OpLabel
1448         %313 = OpLoad %10 %164
1449         %315 = OpAccessChain %187 %184 %313
1450         %316 = OpLoad %61 %315
1451         %317 = OpFDiv %61 %316 %314
1452         %318 = OpAccessChain %187 %184 %313
1453                OpStore %318 %317
1454         %319 = OpLoad %10 %164
1455         %320 = OpIAdd %10 %319 %153
1456                OpStore %164 %320
1457                OpBranch %177
1458         %177 = OpLabel
1459         %321 = OpLoad %10 %173
1460         %322 = OpIAdd %10 %321 %153
1461                OpStore %173 %322
1462                OpBranch %174
1463         %176 = OpLabel
1464                OpBranch %169
1465         %169 = OpLabel
1466         %323 = OpLoad %10 %165
1467         %324 = OpIAdd %10 %323 %153
1468                OpStore %165 %324
1469                OpBranch %166
1470         %168 = OpLabel
1471         %329 = OpAccessChain %328 %327 %9
1472         %330 = OpLoad %61 %329
1473         %334 = OpAccessChain %71 %333 %32 %9
1474         %335 = OpLoad %61 %334
1475         %337 = OpFDiv %61 %335 %336
1476         %338 = OpFDiv %61 %330 %337
1477         %339 = OpConvertFToS %10 %338
1478                OpStore %325 %339
1479         %341 = OpAccessChain %328 %327 %158
1480         %342 = OpLoad %61 %341
1481         %343 = OpAccessChain %71 %333 %32 %9
1482         %344 = OpLoad %61 %343
1483         %345 = OpFDiv %61 %344 %336
1484         %346 = OpFDiv %61 %342 %345
1485         %347 = OpConvertFToS %10 %346
1486                OpStore %340 %347
1487         %349 = OpLoad %10 %340
1488         %351 = OpIMul %10 %349 %350
1489         %352 = OpLoad %10 %325
1490         %353 = OpIAdd %10 %351 %352
1491                OpStore %348 %353
1492         %354 = OpLoad %10 %348
1493         %355 = OpSGreaterThan %21 %354 %32
1494         %356 = OpLoad %10 %348
1495         %358 = OpSLessThan %21 %356 %357
1496         %359 = OpLogicalAnd %21 %355 %358
1497                OpSelectionMerge %361 None
1498                OpBranchConditional %359 %360 %373
1499         %360 = OpLabel
1500         %364 = OpLoad %10 %348
1501         %365 = OpAccessChain %187 %184 %364
1502         %366 = OpLoad %61 %365
1503         %367 = OpCompositeConstruct %77 %366 %366 %366
1504         %369 = OpCompositeExtract %61 %367 0
1505         %370 = OpCompositeExtract %61 %367 1
1506         %371 = OpCompositeExtract %61 %367 2
1507         %372 = OpCompositeConstruct %87 %369 %370 %371 %368
1508                OpStore %363 %372
1509                OpBranch %361
1510         %373 = OpLabel
1511                OpStore %363 %374
1512                OpBranch %361
1513         %361 = OpLabel
1514                OpReturn
1515                OpFunctionEnd
1516   )";
1517 
AddConstantUniformFact(protobufs::FactSequence * facts,uint32_t descriptor_set,uint32_t binding,std::vector<uint32_t> && indices,uint32_t value)1518 void AddConstantUniformFact(protobufs::FactSequence* facts,
1519                             uint32_t descriptor_set, uint32_t binding,
1520                             std::vector<uint32_t>&& indices, uint32_t value) {
1521   protobufs::FactConstantUniform fact;
1522   *fact.mutable_uniform_buffer_element_descriptor() =
1523       MakeUniformBufferElementDescriptor(descriptor_set, binding,
1524                                          std::move(indices));
1525   *fact.mutable_constant_word()->Add() = value;
1526   protobufs::Fact temp;
1527   *temp.mutable_constant_uniform_fact() = fact;
1528   *facts->mutable_fact()->Add() = temp;
1529 }
1530 
1531 // Reinterpret the bits of |value| as a 32-bit unsigned int
FloatBitsAsUint(float value)1532 uint32_t FloatBitsAsUint(float value) {
1533   uint32_t result;
1534   memcpy(&result, &value, sizeof(float));
1535   return result;
1536 }
1537 
1538 // Assembles the given |shader| text, and then runs the fuzzer |num_runs|
1539 // times, using successive seeds starting from |initial_seed|.  Checks that
1540 // the binary produced after each fuzzer run is valid, and that replaying
1541 // the transformations that were applied during fuzzing leads to an
1542 // identical binary.
RunFuzzerAndReplayer(const std::string & shader,const protobufs::FactSequence & initial_facts,uint32_t initial_seed,uint32_t num_runs)1543 void RunFuzzerAndReplayer(const std::string& shader,
1544                           const protobufs::FactSequence& initial_facts,
1545                           uint32_t initial_seed, uint32_t num_runs) {
1546   const auto env = SPV_ENV_UNIVERSAL_1_5;
1547 
1548   std::vector<uint32_t> binary_in;
1549   SpirvTools t(env);
1550   t.SetMessageConsumer(kConsoleMessageConsumer);
1551   ASSERT_TRUE(t.Assemble(shader, &binary_in, kFuzzAssembleOption));
1552   ASSERT_TRUE(t.Validate(binary_in));
1553 
1554   std::vector<fuzzerutil::ModuleSupplier> donor_suppliers;
1555   for (auto donor :
1556        {&kTestShader1, &kTestShader2, &kTestShader3, &kTestShader4}) {
1557     donor_suppliers.emplace_back([donor]() {
1558       return BuildModule(env, kConsoleMessageConsumer, *donor,
1559                          kFuzzAssembleOption);
1560     });
1561   }
1562 
1563   for (uint32_t seed = initial_seed; seed < initial_seed + num_runs; seed++) {
1564     std::vector<uint32_t> fuzzer_binary_out;
1565     protobufs::TransformationSequence fuzzer_transformation_sequence_out;
1566 
1567     Fuzzer fuzzer(env, seed, true);
1568     fuzzer.SetMessageConsumer(kSilentConsumer);
1569     auto fuzzer_result_status =
1570         fuzzer.Run(binary_in, initial_facts, donor_suppliers,
1571                    &fuzzer_binary_out, &fuzzer_transformation_sequence_out);
1572     ASSERT_EQ(Fuzzer::FuzzerResultStatus::kComplete, fuzzer_result_status);
1573     ASSERT_TRUE(t.Validate(fuzzer_binary_out));
1574 
1575     std::vector<uint32_t> replayer_binary_out;
1576     protobufs::TransformationSequence replayer_transformation_sequence_out;
1577 
1578     Replayer replayer(env, false);
1579     replayer.SetMessageConsumer(kSilentConsumer);
1580     auto replayer_result_status = replayer.Run(
1581         binary_in, initial_facts, fuzzer_transformation_sequence_out,
1582         &replayer_binary_out, &replayer_transformation_sequence_out);
1583     ASSERT_EQ(Replayer::ReplayerResultStatus::kComplete,
1584               replayer_result_status);
1585 
1586     // After replaying the transformations applied by the fuzzer, exactly those
1587     // transformations should have been applied, and the binary resulting from
1588     // replay should be identical to that which resulted from fuzzing.
1589     std::string fuzzer_transformations_string;
1590     std::string replayer_transformations_string;
1591     fuzzer_transformation_sequence_out.SerializeToString(
1592         &fuzzer_transformations_string);
1593     replayer_transformation_sequence_out.SerializeToString(
1594         &replayer_transformations_string);
1595     ASSERT_EQ(fuzzer_transformations_string, replayer_transformations_string);
1596     ASSERT_EQ(fuzzer_binary_out, replayer_binary_out);
1597   }
1598 }
1599 
TEST(FuzzerReplayerTest,Miscellaneous1)1600 TEST(FuzzerReplayerTest, Miscellaneous1) {
1601   // Do some fuzzer runs, starting from an initial seed of 0 (seed value chosen
1602   // arbitrarily).
1603   RunFuzzerAndReplayer(kTestShader1, protobufs::FactSequence(), 0,
1604                        kNumFuzzerRuns);
1605 }
1606 
TEST(FuzzerReplayerTest,Miscellaneous2)1607 TEST(FuzzerReplayerTest, Miscellaneous2) {
1608   // Do some fuzzer runs, starting from an initial seed of 10 (seed value chosen
1609   // arbitrarily).
1610   RunFuzzerAndReplayer(kTestShader2, protobufs::FactSequence(), 10,
1611                        kNumFuzzerRuns);
1612 }
1613 
TEST(FuzzerReplayerTest,Miscellaneous3)1614 TEST(FuzzerReplayerTest, Miscellaneous3) {
1615   // Add the facts "resolution.x == 250" and "resolution.y == 100".
1616   protobufs::FactSequence facts;
1617   AddConstantUniformFact(&facts, 0, 0, {0, 0}, 250);
1618   AddConstantUniformFact(&facts, 0, 0, {0, 1}, 100);
1619 
1620   // Do some fuzzer runs, starting from an initial seed of 94 (seed value chosen
1621   // arbitrarily).
1622   RunFuzzerAndReplayer(kTestShader3, facts, 94, kNumFuzzerRuns);
1623 }
1624 
TEST(FuzzerReplayerTest,Miscellaneous4)1625 TEST(FuzzerReplayerTest, Miscellaneous4) {
1626   // Add the facts:
1627   //  - "one == 1.0"
1628   //  - "resolution.y == 256.0",
1629   protobufs::FactSequence facts;
1630   AddConstantUniformFact(&facts, 0, 0, {0}, FloatBitsAsUint(1.0));
1631   AddConstantUniformFact(&facts, 0, 1, {0, 0}, FloatBitsAsUint(256.0));
1632   AddConstantUniformFact(&facts, 0, 1, {0, 1}, FloatBitsAsUint(256.0));
1633 
1634   // Do some fuzzer runs, starting from an initial seed of 14 (seed value chosen
1635   // arbitrarily).
1636   RunFuzzerAndReplayer(kTestShader4, facts, 14, kNumFuzzerRuns);
1637 }
1638 
1639 }  // namespace
1640 }  // namespace fuzz
1641 }  // namespace spvtools
1642