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