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