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