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 1599 // A virtually empty piece of SPIR-V. 1600 1601 const std::string kTestShader7 = R"( 1602 OpCapability Shader 1603 %1 = OpExtInstImport "GLSL.std.450" 1604 OpMemoryModel Logical GLSL450 1605 OpEntryPoint Fragment %4 "main" 1606 OpExecutionMode %4 OriginUpperLeft 1607 OpSource ESSL 320 1608 %2 = OpTypeVoid 1609 %3 = OpTypeFunction %2 1610 %4 = OpFunction %2 None %3 1611 %5 = OpLabel 1612 OpReturn 1613 OpFunctionEnd 1614 )"; 1615 1616 void AddConstantUniformFact(protobufs::FactSequence* facts, 1617 uint32_t descriptor_set, uint32_t binding, 1618 std::vector<uint32_t>&& indices, uint32_t value) { 1619 protobufs::FactConstantUniform fact; 1620 *fact.mutable_uniform_buffer_element_descriptor() = 1621 MakeUniformBufferElementDescriptor(descriptor_set, binding, 1622 std::move(indices)); 1623 *fact.mutable_constant_word()->Add() = value; 1624 protobufs::Fact temp; 1625 *temp.mutable_constant_uniform_fact() = fact; 1626 *facts->mutable_fact()->Add() = temp; 1627 } 1628 1629 // Reinterpret the bits of |value| as a 32-bit unsigned int 1630 uint32_t FloatBitsAsUint(float value) { 1631 uint32_t result; 1632 memcpy(&result, &value, sizeof(float)); 1633 return result; 1634 } 1635 1636 // Assembles the given |shader| text, and then runs the fuzzer |num_runs| 1637 // times, using successive seeds starting from |initial_seed|. Checks that 1638 // the binary produced after each fuzzer run is valid, and that replaying 1639 // the transformations that were applied during fuzzing leads to an 1640 // identical binary. 1641 void RunFuzzerAndReplayer(const std::string& shader, 1642 const protobufs::FactSequence& initial_facts, 1643 uint32_t initial_seed, uint32_t num_runs) { 1644 const auto env = SPV_ENV_UNIVERSAL_1_5; 1645 1646 std::vector<uint32_t> binary_in; 1647 SpirvTools t(env); 1648 t.SetMessageConsumer(kConsoleMessageConsumer); 1649 ASSERT_TRUE(t.Assemble(shader, &binary_in, kFuzzAssembleOption)); 1650 ASSERT_TRUE(t.Validate(binary_in)); 1651 1652 std::vector<fuzzerutil::ModuleSupplier> donor_suppliers; 1653 for (auto donor : {&kTestShader1, &kTestShader2, &kTestShader3, &kTestShader4, 1654 &kTestShader5, &kTestShader6}) { 1655 donor_suppliers.emplace_back([donor]() { 1656 return BuildModule(env, kConsoleMessageConsumer, *donor, 1657 kFuzzAssembleOption); 1658 }); 1659 } 1660 1661 std::vector<RepeatedPassStrategy> strategies{ 1662 RepeatedPassStrategy::kSimple, 1663 RepeatedPassStrategy::kLoopedWithRecommendations, 1664 RepeatedPassStrategy::kRandomWithRecommendations}; 1665 uint32_t strategy_index = 0; 1666 for (uint32_t seed = initial_seed; seed < initial_seed + num_runs; seed++) { 1667 spvtools::ValidatorOptions validator_options; 1668 1669 std::unique_ptr<opt::IRContext> ir_context; 1670 ASSERT_TRUE(fuzzerutil::BuildIRContext(env, kConsoleMessageConsumer, 1671 binary_in, validator_options, 1672 &ir_context)); 1673 1674 auto fuzzer_context = MakeUnique<FuzzerContext>( 1675 MakeUnique<PseudoRandomGenerator>(seed), 1676 FuzzerContext::GetMinFreshId(ir_context.get()), false); 1677 1678 auto transformation_context = MakeUnique<TransformationContext>( 1679 MakeUnique<FactManager>(ir_context.get()), validator_options); 1680 transformation_context->GetFactManager()->AddInitialFacts( 1681 kConsoleMessageConsumer, initial_facts); 1682 1683 // Every 4th time we run the fuzzer, enable all fuzzer passes. 1684 bool enable_all_passes = (seed % 4) == 0; 1685 Fuzzer fuzzer(std::move(ir_context), std::move(transformation_context), 1686 std::move(fuzzer_context), kConsoleMessageConsumer, 1687 donor_suppliers, enable_all_passes, 1688 strategies[strategy_index], true, validator_options, false); 1689 auto fuzzer_result = fuzzer.Run(0); 1690 1691 // Cycle the repeated pass strategy so that we try a different one next time 1692 // we run the fuzzer. 1693 strategy_index = 1694 (strategy_index + 1) % static_cast<uint32_t>(strategies.size()); 1695 1696 ASSERT_NE(Fuzzer::Status::kFuzzerPassLedToInvalidModule, 1697 fuzzer_result.status); 1698 std::vector<uint32_t> transformed_binary; 1699 fuzzer.GetIRContext()->module()->ToBinary(&transformed_binary, true); 1700 ASSERT_TRUE(t.Validate(transformed_binary)); 1701 1702 auto replayer_result = 1703 Replayer(env, kConsoleMessageConsumer, binary_in, initial_facts, 1704 fuzzer.GetTransformationSequence(), 1705 static_cast<uint32_t>( 1706 fuzzer.GetTransformationSequence().transformation_size()), 1707 false, validator_options) 1708 .Run(); 1709 ASSERT_EQ(Replayer::ReplayerResultStatus::kComplete, 1710 replayer_result.status); 1711 1712 // After replaying the transformations applied by the fuzzer, exactly those 1713 // transformations should have been applied, and the binary resulting from 1714 // replay should be identical to that which resulted from fuzzing. 1715 std::string fuzzer_transformations_string; 1716 std::string replayer_transformations_string; 1717 fuzzer.GetTransformationSequence().SerializeToString( 1718 &fuzzer_transformations_string); 1719 replayer_result.applied_transformations.SerializeToString( 1720 &replayer_transformations_string); 1721 ASSERT_EQ(fuzzer_transformations_string, replayer_transformations_string); 1722 ASSERT_TRUE(IsEqual(env, transformed_binary, 1723 replayer_result.transformed_module.get())); 1724 } 1725 } 1726 1727 TEST(FuzzerReplayerTest, Miscellaneous1) { 1728 // Do some fuzzer runs, starting from an initial seed of 0 (seed value chosen 1729 // arbitrarily). 1730 RunFuzzerAndReplayer(kTestShader1, protobufs::FactSequence(), 0, 1731 kNumFuzzerRuns); 1732 } 1733 1734 TEST(FuzzerReplayerTest, Miscellaneous2) { 1735 // Do some fuzzer runs, starting from an initial seed of 10 (seed value chosen 1736 // arbitrarily). 1737 RunFuzzerAndReplayer(kTestShader2, protobufs::FactSequence(), 10, 1738 kNumFuzzerRuns); 1739 } 1740 1741 TEST(FuzzerReplayerTest, Miscellaneous3) { 1742 // Add the facts "resolution.x == 250" and "resolution.y == 100". 1743 protobufs::FactSequence facts; 1744 AddConstantUniformFact(&facts, 0, 0, {0, 0}, 250); 1745 AddConstantUniformFact(&facts, 0, 0, {0, 1}, 100); 1746 1747 // Do some fuzzer runs, starting from an initial seed of 94 (seed value chosen 1748 // arbitrarily). 1749 RunFuzzerAndReplayer(kTestShader3, facts, 94, kNumFuzzerRuns); 1750 } 1751 1752 TEST(FuzzerReplayerTest, Miscellaneous4) { 1753 // Add the facts: 1754 // - "one == 1.0" 1755 // - "resolution.y == 256.0", 1756 protobufs::FactSequence facts; 1757 AddConstantUniformFact(&facts, 0, 0, {0}, FloatBitsAsUint(1.0)); 1758 AddConstantUniformFact(&facts, 0, 1, {0, 0}, FloatBitsAsUint(256.0)); 1759 AddConstantUniformFact(&facts, 0, 1, {0, 1}, FloatBitsAsUint(256.0)); 1760 1761 // Do some fuzzer runs, starting from an initial seed of 14 (seed value chosen 1762 // arbitrarily). 1763 RunFuzzerAndReplayer(kTestShader4, facts, 14, kNumFuzzerRuns); 1764 } 1765 1766 TEST(FuzzerReplayerTest, Miscellaneous5) { 1767 // Do some fuzzer runs, starting from an initial seed of 29 (seed value chosen 1768 // arbitrarily). 1769 RunFuzzerAndReplayer(kTestShader5, protobufs::FactSequence(), 29, 1770 kNumFuzzerRuns); 1771 } 1772 1773 TEST(FuzzerReplayerTest, Miscellaneous6) { 1774 // Do some fuzzer runs, starting from an initial seed of 57 (seed value chosen 1775 // arbitrarily). 1776 RunFuzzerAndReplayer(kTestShader6, protobufs::FactSequence(), 57, 1777 kNumFuzzerRuns); 1778 } 1779 1780 TEST(FuzzerReplayerTest, Miscellaneous7) { 1781 // Do some fuzzer runs, starting from an initial seed of 1 (seed value chosen 1782 // arbitrarily). 1783 RunFuzzerAndReplayer(kTestShader7, protobufs::FactSequence(), 1, 1784 kNumFuzzerRuns); 1785 } 1786 1787 } // namespace 1788 } // namespace fuzz 1789 } // namespace spvtools 1790