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