// Copyright (c) 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #include "source/fuzz/fuzzer.h" #include "source/fuzz/fuzzer_util.h" #include "source/fuzz/replayer.h" #include "source/fuzz/uniform_buffer_element_descriptor.h" #include "test/fuzz/fuzz_test_util.h" namespace spvtools { namespace fuzz { namespace { const uint32_t kNumFuzzerRuns = 20; // The SPIR-V came from this GLSL: // // #version 310 es // // void foo() { // int x; // x = 2; // for (int i = 0; i < 100; i++) { // x += i; // x = x * 2; // } // return; // } // // void main() { // foo(); // for (int i = 0; i < 10; i++) { // int j = 20; // while(j > 0) { // foo(); // j--; // } // do { // i++; // } while(i < 4); // } // } const std::string kTestShader1 = R"( OpCapability Shader %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 OpEntryPoint Fragment %4 "main" OpExecutionMode %4 OriginUpperLeft OpSource ESSL 310 OpName %4 "main" OpName %6 "foo(" OpName %10 "x" OpName %12 "i" OpName %33 "i" OpName %42 "j" OpDecorate %10 RelaxedPrecision OpDecorate %12 RelaxedPrecision OpDecorate %19 RelaxedPrecision OpDecorate %23 RelaxedPrecision OpDecorate %24 RelaxedPrecision OpDecorate %25 RelaxedPrecision OpDecorate %26 RelaxedPrecision OpDecorate %27 RelaxedPrecision OpDecorate %28 RelaxedPrecision OpDecorate %30 RelaxedPrecision OpDecorate %33 RelaxedPrecision OpDecorate %39 RelaxedPrecision OpDecorate %42 RelaxedPrecision OpDecorate %49 RelaxedPrecision OpDecorate %52 RelaxedPrecision OpDecorate %53 RelaxedPrecision OpDecorate %58 RelaxedPrecision OpDecorate %59 RelaxedPrecision OpDecorate %60 RelaxedPrecision OpDecorate %63 RelaxedPrecision OpDecorate %64 RelaxedPrecision %2 = OpTypeVoid %3 = OpTypeFunction %2 %8 = OpTypeInt 32 1 %9 = OpTypePointer Function %8 %11 = OpConstant %8 2 %13 = OpConstant %8 0 %20 = OpConstant %8 100 %21 = OpTypeBool %29 = OpConstant %8 1 %40 = OpConstant %8 10 %43 = OpConstant %8 20 %61 = OpConstant %8 4 %4 = OpFunction %2 None %3 %5 = OpLabel %33 = OpVariable %9 Function %42 = OpVariable %9 Function %32 = OpFunctionCall %2 %6 OpStore %33 %13 OpBranch %34 %34 = OpLabel OpLoopMerge %36 %37 None OpBranch %38 %38 = OpLabel %39 = OpLoad %8 %33 %41 = OpSLessThan %21 %39 %40 OpBranchConditional %41 %35 %36 %35 = OpLabel OpStore %42 %43 OpBranch %44 %44 = OpLabel OpLoopMerge %46 %47 None OpBranch %48 %48 = OpLabel %49 = OpLoad %8 %42 %50 = OpSGreaterThan %21 %49 %13 OpBranchConditional %50 %45 %46 %45 = OpLabel %51 = OpFunctionCall %2 %6 %52 = OpLoad %8 %42 %53 = OpISub %8 %52 %29 OpStore %42 %53 OpBranch %47 %47 = OpLabel OpBranch %44 %46 = OpLabel OpBranch %54 %54 = OpLabel OpLoopMerge %56 %57 None OpBranch %55 %55 = OpLabel %58 = OpLoad %8 %33 %59 = OpIAdd %8 %58 %29 OpStore %33 %59 OpBranch %57 %57 = OpLabel %60 = OpLoad %8 %33 %62 = OpSLessThan %21 %60 %61 OpBranchConditional %62 %54 %56 %56 = OpLabel OpBranch %37 %37 = OpLabel %63 = OpLoad %8 %33 %64 = OpIAdd %8 %63 %29 OpStore %33 %64 OpBranch %34 %36 = OpLabel OpReturn OpFunctionEnd %6 = OpFunction %2 None %3 %7 = OpLabel %10 = OpVariable %9 Function %12 = OpVariable %9 Function OpStore %10 %11 OpStore %12 %13 OpBranch %14 %14 = OpLabel OpLoopMerge %16 %17 None OpBranch %18 %18 = OpLabel %19 = OpLoad %8 %12 %22 = OpSLessThan %21 %19 %20 OpBranchConditional %22 %15 %16 %15 = OpLabel %23 = OpLoad %8 %12 %24 = OpLoad %8 %10 %25 = OpIAdd %8 %24 %23 OpStore %10 %25 %26 = OpLoad %8 %10 %27 = OpIMul %8 %26 %11 OpStore %10 %27 OpBranch %17 %17 = OpLabel %28 = OpLoad %8 %12 %30 = OpIAdd %8 %28 %29 OpStore %12 %30 OpBranch %14 %16 = OpLabel OpReturn OpFunctionEnd )"; // The SPIR-V came from this GLSL, which was then optimized using spirv-opt // with the -O argument: // // #version 310 es // // precision highp float; // // layout(location = 0) out vec4 _GLF_color; // // layout(set = 0, binding = 0) uniform buf0 { // vec2 injectionSwitch; // }; // layout(set = 0, binding = 1) uniform buf1 { // vec2 resolution; // }; // bool checkSwap(float a, float b) // { // return gl_FragCoord.y < resolution.y / 2.0 ? a > b : a < b; // } // void main() // { // float data[10]; // for(int i = 0; i < 10; i++) // { // data[i] = float(10 - i) * injectionSwitch.y; // } // for(int i = 0; i < 9; i++) // { // for(int j = 0; j < 10; j++) // { // if(j < i + 1) // { // continue; // } // bool doSwap = checkSwap(data[i], data[j]); // if(doSwap) // { // float temp = data[i]; // data[i] = data[j]; // data[j] = temp; // } // } // } // if(gl_FragCoord.x < resolution.x / 2.0) // { // _GLF_color = vec4(data[0] / 10.0, data[5] / 10.0, data[9] / 10.0, 1.0); // } // else // { // _GLF_color = vec4(data[5] / 10.0, data[9] / 10.0, data[0] / 10.0, 1.0); // } // } const std::string kTestShader2 = R"( OpCapability Shader %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 OpEntryPoint Fragment %4 "main" %16 %139 %25 %68 OpExecutionMode %4 OriginUpperLeft OpSource ESSL 310 OpName %4 "main" OpName %16 "gl_FragCoord" OpName %23 "buf1" OpMemberName %23 0 "resolution" OpName %25 "" OpName %61 "data" OpName %66 "buf0" OpMemberName %66 0 "injectionSwitch" OpName %68 "" OpName %139 "_GLF_color" OpDecorate %16 BuiltIn FragCoord OpMemberDecorate %23 0 Offset 0 OpDecorate %23 Block OpDecorate %25 DescriptorSet 0 OpDecorate %25 Binding 1 OpDecorate %64 RelaxedPrecision OpMemberDecorate %66 0 Offset 0 OpDecorate %66 Block OpDecorate %68 DescriptorSet 0 OpDecorate %68 Binding 0 OpDecorate %75 RelaxedPrecision OpDecorate %95 RelaxedPrecision OpDecorate %126 RelaxedPrecision OpDecorate %128 RelaxedPrecision OpDecorate %139 Location 0 OpDecorate %182 RelaxedPrecision OpDecorate %183 RelaxedPrecision OpDecorate %184 RelaxedPrecision %2 = OpTypeVoid %3 = OpTypeFunction %2 %6 = OpTypeFloat 32 %7 = OpTypePointer Function %6 %8 = OpTypeBool %14 = OpTypeVector %6 4 %15 = OpTypePointer Input %14 %16 = OpVariable %15 Input %17 = OpTypeInt 32 0 %18 = OpConstant %17 1 %19 = OpTypePointer Input %6 %22 = OpTypeVector %6 2 %23 = OpTypeStruct %22 %24 = OpTypePointer Uniform %23 %25 = OpVariable %24 Uniform %26 = OpTypeInt 32 1 %27 = OpConstant %26 0 %28 = OpTypePointer Uniform %6 %56 = OpConstant %26 10 %58 = OpConstant %17 10 %59 = OpTypeArray %6 %58 %60 = OpTypePointer Function %59 %66 = OpTypeStruct %22 %67 = OpTypePointer Uniform %66 %68 = OpVariable %67 Uniform %74 = OpConstant %26 1 %83 = OpConstant %26 9 %129 = OpConstant %17 0 %138 = OpTypePointer Output %14 %139 = OpVariable %138 Output %144 = OpConstant %26 5 %151 = OpConstant %6 1 %194 = OpConstant %6 0.5 %195 = OpConstant %6 0.100000001 %4 = OpFunction %2 None %3 %5 = OpLabel %61 = OpVariable %60 Function OpBranch %50 %50 = OpLabel %182 = OpPhi %26 %27 %5 %75 %51 %57 = OpSLessThan %8 %182 %56 OpLoopMerge %52 %51 None OpBranchConditional %57 %51 %52 %51 = OpLabel %64 = OpISub %26 %56 %182 %65 = OpConvertSToF %6 %64 %69 = OpAccessChain %28 %68 %27 %18 %70 = OpLoad %6 %69 %71 = OpFMul %6 %65 %70 %72 = OpAccessChain %7 %61 %182 OpStore %72 %71 %75 = OpIAdd %26 %182 %74 OpBranch %50 %52 = OpLabel OpBranch %77 %77 = OpLabel %183 = OpPhi %26 %27 %52 %128 %88 %84 = OpSLessThan %8 %183 %83 OpLoopMerge %79 %88 None OpBranchConditional %84 %78 %79 %78 = OpLabel OpBranch %86 %86 = OpLabel %184 = OpPhi %26 %27 %78 %126 %89 %92 = OpSLessThan %8 %184 %56 OpLoopMerge %1000 %89 None OpBranchConditional %92 %87 %1000 %87 = OpLabel %95 = OpIAdd %26 %183 %74 %96 = OpSLessThan %8 %184 %95 OpSelectionMerge %98 None OpBranchConditional %96 %97 %98 %97 = OpLabel OpBranch %89 %98 = OpLabel %104 = OpAccessChain %7 %61 %183 %105 = OpLoad %6 %104 %107 = OpAccessChain %7 %61 %184 %108 = OpLoad %6 %107 %166 = OpAccessChain %19 %16 %18 %167 = OpLoad %6 %166 %168 = OpAccessChain %28 %25 %27 %18 %169 = OpLoad %6 %168 %170 = OpFMul %6 %169 %194 %171 = OpFOrdLessThan %8 %167 %170 OpSelectionMerge %172 None OpBranchConditional %171 %173 %174 %173 = OpLabel %177 = OpFOrdGreaterThan %8 %105 %108 OpBranch %172 %174 = OpLabel %180 = OpFOrdLessThan %8 %105 %108 OpBranch %172 %172 = OpLabel %186 = OpPhi %8 %177 %173 %180 %174 OpSelectionMerge %112 None OpBranchConditional %186 %111 %112 %111 = OpLabel %116 = OpLoad %6 %104 %120 = OpLoad %6 %107 OpStore %104 %120 OpStore %107 %116 OpBranch %112 %112 = OpLabel OpBranch %89 %89 = OpLabel %126 = OpIAdd %26 %184 %74 OpBranch %86 %1000 = OpLabel OpBranch %88 %88 = OpLabel %128 = OpIAdd %26 %183 %74 OpBranch %77 %79 = OpLabel %130 = OpAccessChain %19 %16 %129 %131 = OpLoad %6 %130 %132 = OpAccessChain %28 %25 %27 %129 %133 = OpLoad %6 %132 %134 = OpFMul %6 %133 %194 %135 = OpFOrdLessThan %8 %131 %134 OpSelectionMerge %137 None OpBranchConditional %135 %136 %153 %136 = OpLabel %140 = OpAccessChain %7 %61 %27 %141 = OpLoad %6 %140 %143 = OpFMul %6 %141 %195 %145 = OpAccessChain %7 %61 %144 %146 = OpLoad %6 %145 %147 = OpFMul %6 %146 %195 %148 = OpAccessChain %7 %61 %83 %149 = OpLoad %6 %148 %150 = OpFMul %6 %149 %195 %152 = OpCompositeConstruct %14 %143 %147 %150 %151 OpStore %139 %152 OpBranch %137 %153 = OpLabel %154 = OpAccessChain %7 %61 %144 %155 = OpLoad %6 %154 %156 = OpFMul %6 %155 %195 %157 = OpAccessChain %7 %61 %83 %158 = OpLoad %6 %157 %159 = OpFMul %6 %158 %195 %160 = OpAccessChain %7 %61 %27 %161 = OpLoad %6 %160 %162 = OpFMul %6 %161 %195 %163 = OpCompositeConstruct %14 %156 %159 %162 %151 OpStore %139 %163 OpBranch %137 %137 = OpLabel OpReturn OpFunctionEnd )"; // The SPIR-V came from this GLSL, which was then optimized using spirv-opt // with the -O argument: // // #version 310 es // // precision highp float; // // layout(location = 0) out vec4 _GLF_color; // // layout(set = 0, binding = 0) uniform buf0 { // vec2 resolution; // }; // void main(void) // { // float A[50]; // for( // int i = 0; // i < 200; // i ++ // ) // { // if(i >= int(resolution.x)) // { // break; // } // if((4 * (i / 4)) == i) // { // A[i / 4] = float(i); // } // } // for( // int i = 0; // i < 50; // i ++ // ) // { // if(i < int(gl_FragCoord.x)) // { // break; // } // if(i > 0) // { // A[i] += A[i - 1]; // } // } // if(int(gl_FragCoord.x) < 20) // { // _GLF_color = vec4(A[0] / resolution.x, A[4] / resolution.y, 1.0, 1.0); // } // else // if(int(gl_FragCoord.x) < 40) // { // _GLF_color = vec4(A[5] / resolution.x, A[9] / resolution.y, 1.0, 1.0); // } // else // if(int(gl_FragCoord.x) < 60) // { // _GLF_color = vec4(A[10] / resolution.x, A[14] / resolution.y, // 1.0, 1.0); // } // else // if(int(gl_FragCoord.x) < 80) // { // _GLF_color = vec4(A[15] / resolution.x, A[19] / resolution.y, // 1.0, 1.0); // } // else // if(int(gl_FragCoord.x) < 100) // { // _GLF_color = vec4(A[20] / resolution.x, A[24] / resolution.y, // 1.0, 1.0); // } // else // if(int(gl_FragCoord.x) < 120) // { // _GLF_color = vec4(A[25] / resolution.x, A[29] / resolution.y, // 1.0, 1.0); // } // else // if(int(gl_FragCoord.x) < 140) // { // _GLF_color = vec4(A[30] / resolution.x, A[34] / resolution.y, // 1.0, 1.0); // } // else // if(int(gl_FragCoord.x) < 160) // { // _GLF_color = vec4(A[35] / resolution.x, A[39] / // resolution.y, 1.0, 1.0); // } // else // if(int(gl_FragCoord.x) < 180) // { // _GLF_color = vec4(A[40] / resolution.x, A[44] / // resolution.y, 1.0, 1.0); // } // else // if(int(gl_FragCoord.x) < 180) // { // _GLF_color = vec4(A[45] / resolution.x, A[49] / // resolution.y, 1.0, 1.0); // } // else // { // discard; // } // } const std::string kTestShader3 = R"( OpCapability Shader %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 OpEntryPoint Fragment %4 "main" %68 %100 %24 OpExecutionMode %4 OriginUpperLeft OpSource ESSL 310 OpName %4 "main" OpName %22 "buf0" OpMemberName %22 0 "resolution" OpName %24 "" OpName %46 "A" OpName %68 "gl_FragCoord" OpName %100 "_GLF_color" OpMemberDecorate %22 0 Offset 0 OpDecorate %22 Block OpDecorate %24 DescriptorSet 0 OpDecorate %24 Binding 0 OpDecorate %37 RelaxedPrecision OpDecorate %38 RelaxedPrecision OpDecorate %55 RelaxedPrecision OpDecorate %68 BuiltIn FragCoord OpDecorate %83 RelaxedPrecision OpDecorate %91 RelaxedPrecision OpDecorate %100 Location 0 OpDecorate %302 RelaxedPrecision OpDecorate %304 RelaxedPrecision %2 = OpTypeVoid %3 = OpTypeFunction %2 %6 = OpTypeInt 32 1 %9 = OpConstant %6 0 %16 = OpConstant %6 200 %17 = OpTypeBool %20 = OpTypeFloat 32 %21 = OpTypeVector %20 2 %22 = OpTypeStruct %21 %23 = OpTypePointer Uniform %22 %24 = OpVariable %23 Uniform %25 = OpTypeInt 32 0 %26 = OpConstant %25 0 %27 = OpTypePointer Uniform %20 %35 = OpConstant %6 4 %43 = OpConstant %25 50 %44 = OpTypeArray %20 %43 %45 = OpTypePointer Function %44 %51 = OpTypePointer Function %20 %54 = OpConstant %6 1 %63 = OpConstant %6 50 %66 = OpTypeVector %20 4 %67 = OpTypePointer Input %66 %68 = OpVariable %67 Input %69 = OpTypePointer Input %20 %95 = OpConstant %6 20 %99 = OpTypePointer Output %66 %100 = OpVariable %99 Output %108 = OpConstant %25 1 %112 = OpConstant %20 1 %118 = OpConstant %6 40 %122 = OpConstant %6 5 %128 = OpConstant %6 9 %139 = OpConstant %6 60 %143 = OpConstant %6 10 %149 = OpConstant %6 14 %160 = OpConstant %6 80 %164 = OpConstant %6 15 %170 = OpConstant %6 19 %181 = OpConstant %6 100 %190 = OpConstant %6 24 %201 = OpConstant %6 120 %205 = OpConstant %6 25 %211 = OpConstant %6 29 %222 = OpConstant %6 140 %226 = OpConstant %6 30 %232 = OpConstant %6 34 %243 = OpConstant %6 160 %247 = OpConstant %6 35 %253 = OpConstant %6 39 %264 = OpConstant %6 180 %273 = OpConstant %6 44 %287 = OpConstant %6 45 %293 = OpConstant %6 49 %4 = OpFunction %2 None %3 %5 = OpLabel %46 = OpVariable %45 Function OpBranch %10 %10 = OpLabel %302 = OpPhi %6 %9 %5 %55 %42 %18 = OpSLessThan %17 %302 %16 OpLoopMerge %12 %42 None OpBranchConditional %18 %11 %12 %11 = OpLabel %28 = OpAccessChain %27 %24 %9 %26 %29 = OpLoad %20 %28 %30 = OpConvertFToS %6 %29 %31 = OpSGreaterThanEqual %17 %302 %30 OpSelectionMerge %33 None OpBranchConditional %31 %32 %33 %32 = OpLabel OpBranch %12 %33 = OpLabel %37 = OpSDiv %6 %302 %35 %38 = OpIMul %6 %35 %37 %40 = OpIEqual %17 %38 %302 OpBranchConditional %40 %41 %42 %41 = OpLabel %50 = OpConvertSToF %20 %302 %52 = OpAccessChain %51 %46 %37 OpStore %52 %50 OpBranch %42 %42 = OpLabel %55 = OpIAdd %6 %302 %54 OpBranch %10 %12 = OpLabel OpBranch %57 %57 = OpLabel %304 = OpPhi %6 %9 %12 %91 %80 %64 = OpSLessThan %17 %304 %63 OpLoopMerge %59 %80 None OpBranchConditional %64 %58 %59 %58 = OpLabel %70 = OpAccessChain %69 %68 %26 %71 = OpLoad %20 %70 %72 = OpConvertFToS %6 %71 %73 = OpSLessThan %17 %304 %72 OpSelectionMerge %75 None OpBranchConditional %73 %74 %75 %74 = OpLabel OpBranch %59 %75 = OpLabel %78 = OpSGreaterThan %17 %304 %9 OpBranchConditional %78 %79 %80 %79 = OpLabel %83 = OpISub %6 %304 %54 %84 = OpAccessChain %51 %46 %83 %85 = OpLoad %20 %84 %86 = OpAccessChain %51 %46 %304 %87 = OpLoad %20 %86 %88 = OpFAdd %20 %87 %85 OpStore %86 %88 OpBranch %80 %80 = OpLabel %91 = OpIAdd %6 %304 %54 OpBranch %57 %59 = OpLabel %92 = OpAccessChain %69 %68 %26 %93 = OpLoad %20 %92 %94 = OpConvertFToS %6 %93 %96 = OpSLessThan %17 %94 %95 OpSelectionMerge %98 None OpBranchConditional %96 %97 %114 %97 = OpLabel %101 = OpAccessChain %51 %46 %9 %102 = OpLoad %20 %101 %103 = OpAccessChain %27 %24 %9 %26 %104 = OpLoad %20 %103 %105 = OpFDiv %20 %102 %104 %106 = OpAccessChain %51 %46 %35 %107 = OpLoad %20 %106 %109 = OpAccessChain %27 %24 %9 %108 %110 = OpLoad %20 %109 %111 = OpFDiv %20 %107 %110 %113 = OpCompositeConstruct %66 %105 %111 %112 %112 OpStore %100 %113 OpBranch %98 %114 = OpLabel %119 = OpSLessThan %17 %94 %118 OpSelectionMerge %121 None OpBranchConditional %119 %120 %135 %120 = OpLabel %123 = OpAccessChain %51 %46 %122 %124 = OpLoad %20 %123 %125 = OpAccessChain %27 %24 %9 %26 %126 = OpLoad %20 %125 %127 = OpFDiv %20 %124 %126 %129 = OpAccessChain %51 %46 %128 %130 = OpLoad %20 %129 %131 = OpAccessChain %27 %24 %9 %108 %132 = OpLoad %20 %131 %133 = OpFDiv %20 %130 %132 %134 = OpCompositeConstruct %66 %127 %133 %112 %112 OpStore %100 %134 OpBranch %121 %135 = OpLabel %140 = OpSLessThan %17 %94 %139 OpSelectionMerge %142 None OpBranchConditional %140 %141 %156 %141 = OpLabel %144 = OpAccessChain %51 %46 %143 %145 = OpLoad %20 %144 %146 = OpAccessChain %27 %24 %9 %26 %147 = OpLoad %20 %146 %148 = OpFDiv %20 %145 %147 %150 = OpAccessChain %51 %46 %149 %151 = OpLoad %20 %150 %152 = OpAccessChain %27 %24 %9 %108 %153 = OpLoad %20 %152 %154 = OpFDiv %20 %151 %153 %155 = OpCompositeConstruct %66 %148 %154 %112 %112 OpStore %100 %155 OpBranch %142 %156 = OpLabel %161 = OpSLessThan %17 %94 %160 OpSelectionMerge %163 None OpBranchConditional %161 %162 %177 %162 = OpLabel %165 = OpAccessChain %51 %46 %164 %166 = OpLoad %20 %165 %167 = OpAccessChain %27 %24 %9 %26 %168 = OpLoad %20 %167 %169 = OpFDiv %20 %166 %168 %171 = OpAccessChain %51 %46 %170 %172 = OpLoad %20 %171 %173 = OpAccessChain %27 %24 %9 %108 %174 = OpLoad %20 %173 %175 = OpFDiv %20 %172 %174 %176 = OpCompositeConstruct %66 %169 %175 %112 %112 OpStore %100 %176 OpBranch %163 %177 = OpLabel %182 = OpSLessThan %17 %94 %181 OpSelectionMerge %184 None OpBranchConditional %182 %183 %197 %183 = OpLabel %185 = OpAccessChain %51 %46 %95 %186 = OpLoad %20 %185 %187 = OpAccessChain %27 %24 %9 %26 %188 = OpLoad %20 %187 %189 = OpFDiv %20 %186 %188 %191 = OpAccessChain %51 %46 %190 %192 = OpLoad %20 %191 %193 = OpAccessChain %27 %24 %9 %108 %194 = OpLoad %20 %193 %195 = OpFDiv %20 %192 %194 %196 = OpCompositeConstruct %66 %189 %195 %112 %112 OpStore %100 %196 OpBranch %184 %197 = OpLabel %202 = OpSLessThan %17 %94 %201 OpSelectionMerge %204 None OpBranchConditional %202 %203 %218 %203 = OpLabel %206 = OpAccessChain %51 %46 %205 %207 = OpLoad %20 %206 %208 = OpAccessChain %27 %24 %9 %26 %209 = OpLoad %20 %208 %210 = OpFDiv %20 %207 %209 %212 = OpAccessChain %51 %46 %211 %213 = OpLoad %20 %212 %214 = OpAccessChain %27 %24 %9 %108 %215 = OpLoad %20 %214 %216 = OpFDiv %20 %213 %215 %217 = OpCompositeConstruct %66 %210 %216 %112 %112 OpStore %100 %217 OpBranch %204 %218 = OpLabel %223 = OpSLessThan %17 %94 %222 OpSelectionMerge %225 None OpBranchConditional %223 %224 %239 %224 = OpLabel %227 = OpAccessChain %51 %46 %226 %228 = OpLoad %20 %227 %229 = OpAccessChain %27 %24 %9 %26 %230 = OpLoad %20 %229 %231 = OpFDiv %20 %228 %230 %233 = OpAccessChain %51 %46 %232 %234 = OpLoad %20 %233 %235 = OpAccessChain %27 %24 %9 %108 %236 = OpLoad %20 %235 %237 = OpFDiv %20 %234 %236 %238 = OpCompositeConstruct %66 %231 %237 %112 %112 OpStore %100 %238 OpBranch %225 %239 = OpLabel %244 = OpSLessThan %17 %94 %243 OpSelectionMerge %246 None OpBranchConditional %244 %245 %260 %245 = OpLabel %248 = OpAccessChain %51 %46 %247 %249 = OpLoad %20 %248 %250 = OpAccessChain %27 %24 %9 %26 %251 = OpLoad %20 %250 %252 = OpFDiv %20 %249 %251 %254 = OpAccessChain %51 %46 %253 %255 = OpLoad %20 %254 %256 = OpAccessChain %27 %24 %9 %108 %257 = OpLoad %20 %256 %258 = OpFDiv %20 %255 %257 %259 = OpCompositeConstruct %66 %252 %258 %112 %112 OpStore %100 %259 OpBranch %246 %260 = OpLabel %265 = OpSLessThan %17 %94 %264 OpSelectionMerge %267 None OpBranchConditional %265 %266 %280 %266 = OpLabel %268 = OpAccessChain %51 %46 %118 %269 = OpLoad %20 %268 %270 = OpAccessChain %27 %24 %9 %26 %271 = OpLoad %20 %270 %272 = OpFDiv %20 %269 %271 %274 = OpAccessChain %51 %46 %273 %275 = OpLoad %20 %274 %276 = OpAccessChain %27 %24 %9 %108 %277 = OpLoad %20 %276 %278 = OpFDiv %20 %275 %277 %279 = OpCompositeConstruct %66 %272 %278 %112 %112 OpStore %100 %279 OpBranch %267 %280 = OpLabel OpSelectionMerge %285 None OpBranchConditional %265 %285 %300 %285 = OpLabel %288 = OpAccessChain %51 %46 %287 %289 = OpLoad %20 %288 %290 = OpAccessChain %27 %24 %9 %26 %291 = OpLoad %20 %290 %292 = OpFDiv %20 %289 %291 %294 = OpAccessChain %51 %46 %293 %295 = OpLoad %20 %294 %296 = OpAccessChain %27 %24 %9 %108 %297 = OpLoad %20 %296 %298 = OpFDiv %20 %295 %297 %299 = OpCompositeConstruct %66 %292 %298 %112 %112 OpStore %100 %299 OpBranch %267 %300 = OpLabel OpKill %267 = OpLabel OpBranch %246 %246 = OpLabel OpBranch %225 %225 = OpLabel OpBranch %204 %204 = OpLabel OpBranch %184 %184 = OpLabel OpBranch %163 %163 = OpLabel OpBranch %142 %142 = OpLabel OpBranch %121 %121 = OpLabel OpBranch %98 %98 = OpLabel OpReturn OpFunctionEnd )"; // The SPIR-V comes from the 'matrices_smart_loops' GLSL shader that ships // with GraphicsFuzz. const std::string kTestShader4 = R"( OpCapability Shader %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 OpEntryPoint Fragment %4 "main" %327 %363 %65 %70 %80 %90 %99 %108 %117 %126 %135 %144 %333 OpExecutionMode %4 OriginUpperLeft OpSource ESSL 310 OpName %4 "main" OpName %8 "matrix_number" OpName %12 "cols" OpName %23 "rows" OpName %31 "c" OpName %41 "r" OpName %65 "m22" OpName %68 "buf0" OpMemberName %68 0 "one" OpName %70 "" OpName %80 "m23" OpName %90 "m24" OpName %99 "m32" OpName %108 "m33" OpName %117 "m34" OpName %126 "m42" OpName %135 "m43" OpName %144 "m44" OpName %164 "sum_index" OpName %165 "cols" OpName %173 "rows" OpName %184 "sums" OpName %189 "c" OpName %198 "r" OpName %325 "region_x" OpName %327 "gl_FragCoord" OpName %331 "buf1" OpMemberName %331 0 "resolution" OpName %333 "" OpName %340 "region_y" OpName %348 "overall_region" OpName %363 "_GLF_color" OpDecorate %8 RelaxedPrecision OpDecorate %12 RelaxedPrecision OpDecorate %19 RelaxedPrecision OpDecorate %23 RelaxedPrecision OpDecorate %29 RelaxedPrecision OpDecorate %31 RelaxedPrecision OpDecorate %38 RelaxedPrecision OpDecorate %39 RelaxedPrecision OpDecorate %41 RelaxedPrecision OpDecorate %47 RelaxedPrecision OpDecorate %48 RelaxedPrecision OpDecorate %50 RelaxedPrecision OpDecorate %66 RelaxedPrecision OpDecorate %67 RelaxedPrecision OpMemberDecorate %68 0 Offset 0 OpDecorate %68 Block OpDecorate %70 DescriptorSet 0 OpDecorate %70 Binding 0 OpDecorate %81 RelaxedPrecision OpDecorate %82 RelaxedPrecision OpDecorate %91 RelaxedPrecision OpDecorate %92 RelaxedPrecision OpDecorate %100 RelaxedPrecision OpDecorate %101 RelaxedPrecision OpDecorate %109 RelaxedPrecision OpDecorate %110 RelaxedPrecision OpDecorate %118 RelaxedPrecision OpDecorate %119 RelaxedPrecision OpDecorate %127 RelaxedPrecision OpDecorate %128 RelaxedPrecision OpDecorate %136 RelaxedPrecision OpDecorate %137 RelaxedPrecision OpDecorate %145 RelaxedPrecision OpDecorate %146 RelaxedPrecision OpDecorate %152 RelaxedPrecision OpDecorate %154 RelaxedPrecision OpDecorate %155 RelaxedPrecision OpDecorate %156 RelaxedPrecision OpDecorate %157 RelaxedPrecision OpDecorate %159 RelaxedPrecision OpDecorate %160 RelaxedPrecision OpDecorate %161 RelaxedPrecision OpDecorate %162 RelaxedPrecision OpDecorate %163 RelaxedPrecision OpDecorate %164 RelaxedPrecision OpDecorate %165 RelaxedPrecision OpDecorate %171 RelaxedPrecision OpDecorate %173 RelaxedPrecision OpDecorate %179 RelaxedPrecision OpDecorate %185 RelaxedPrecision OpDecorate %189 RelaxedPrecision OpDecorate %195 RelaxedPrecision OpDecorate %196 RelaxedPrecision OpDecorate %198 RelaxedPrecision OpDecorate %204 RelaxedPrecision OpDecorate %205 RelaxedPrecision OpDecorate %207 RelaxedPrecision OpDecorate %218 RelaxedPrecision OpDecorate %219 RelaxedPrecision OpDecorate %220 RelaxedPrecision OpDecorate %228 RelaxedPrecision OpDecorate %229 RelaxedPrecision OpDecorate %230 RelaxedPrecision OpDecorate %238 RelaxedPrecision OpDecorate %239 RelaxedPrecision OpDecorate %240 RelaxedPrecision OpDecorate %248 RelaxedPrecision OpDecorate %249 RelaxedPrecision OpDecorate %250 RelaxedPrecision OpDecorate %258 RelaxedPrecision OpDecorate %259 RelaxedPrecision OpDecorate %260 RelaxedPrecision OpDecorate %268 RelaxedPrecision OpDecorate %269 RelaxedPrecision OpDecorate %270 RelaxedPrecision OpDecorate %278 RelaxedPrecision OpDecorate %279 RelaxedPrecision OpDecorate %280 RelaxedPrecision OpDecorate %288 RelaxedPrecision OpDecorate %289 RelaxedPrecision OpDecorate %290 RelaxedPrecision OpDecorate %298 RelaxedPrecision OpDecorate %299 RelaxedPrecision OpDecorate %300 RelaxedPrecision OpDecorate %309 RelaxedPrecision OpDecorate %310 RelaxedPrecision OpDecorate %311 RelaxedPrecision OpDecorate %312 RelaxedPrecision OpDecorate %313 RelaxedPrecision OpDecorate %319 RelaxedPrecision OpDecorate %320 RelaxedPrecision OpDecorate %321 RelaxedPrecision OpDecorate %322 RelaxedPrecision OpDecorate %323 RelaxedPrecision OpDecorate %324 RelaxedPrecision OpDecorate %325 RelaxedPrecision OpDecorate %327 BuiltIn FragCoord OpMemberDecorate %331 0 Offset 0 OpDecorate %331 Block OpDecorate %333 DescriptorSet 0 OpDecorate %333 Binding 1 OpDecorate %339 RelaxedPrecision OpDecorate %340 RelaxedPrecision OpDecorate %347 RelaxedPrecision OpDecorate %348 RelaxedPrecision OpDecorate %349 RelaxedPrecision OpDecorate %351 RelaxedPrecision OpDecorate %352 RelaxedPrecision OpDecorate %353 RelaxedPrecision OpDecorate %354 RelaxedPrecision OpDecorate %356 RelaxedPrecision OpDecorate %363 Location 0 OpDecorate %364 RelaxedPrecision %2 = OpTypeVoid %3 = OpTypeFunction %2 %6 = OpTypeInt 32 0 %7 = OpTypePointer Function %6 %9 = OpConstant %6 0 %10 = OpTypeInt 32 1 %11 = OpTypePointer Function %10 %13 = OpConstant %10 2 %20 = OpConstant %10 4 %21 = OpTypeBool %32 = OpConstant %10 0 %61 = OpTypeFloat 32 %62 = OpTypeVector %61 2 %63 = OpTypeMatrix %62 2 %64 = OpTypePointer Private %63 %65 = OpVariable %64 Private %68 = OpTypeStruct %61 %69 = OpTypePointer Uniform %68 %70 = OpVariable %69 Uniform %71 = OpTypePointer Uniform %61 %74 = OpTypePointer Private %61 %77 = OpTypeVector %61 3 %78 = OpTypeMatrix %77 2 %79 = OpTypePointer Private %78 %80 = OpVariable %79 Private %87 = OpTypeVector %61 4 %88 = OpTypeMatrix %87 2 %89 = OpTypePointer Private %88 %90 = OpVariable %89 Private %97 = OpTypeMatrix %62 3 %98 = OpTypePointer Private %97 %99 = OpVariable %98 Private %106 = OpTypeMatrix %77 3 %107 = OpTypePointer Private %106 %108 = OpVariable %107 Private %115 = OpTypeMatrix %87 3 %116 = OpTypePointer Private %115 %117 = OpVariable %116 Private %124 = OpTypeMatrix %62 4 %125 = OpTypePointer Private %124 %126 = OpVariable %125 Private %133 = OpTypeMatrix %77 4 %134 = OpTypePointer Private %133 %135 = OpVariable %134 Private %142 = OpTypeMatrix %87 4 %143 = OpTypePointer Private %142 %144 = OpVariable %143 Private %153 = OpConstant %10 1 %158 = OpConstant %6 1 %181 = OpConstant %6 9 %182 = OpTypeArray %61 %181 %183 = OpTypePointer Function %182 %186 = OpConstant %61 0 %187 = OpTypePointer Function %61 %314 = OpConstant %61 16 %326 = OpTypePointer Input %87 %327 = OpVariable %326 Input %328 = OpTypePointer Input %61 %331 = OpTypeStruct %62 %332 = OpTypePointer Uniform %331 %333 = OpVariable %332 Uniform %336 = OpConstant %61 3 %350 = OpConstant %10 3 %357 = OpConstant %10 9 %362 = OpTypePointer Output %87 %363 = OpVariable %362 Output %368 = OpConstant %61 1 %374 = OpConstantComposite %87 %186 %186 %186 %368 %4 = OpFunction %2 None %3 %5 = OpLabel %8 = OpVariable %7 Function %12 = OpVariable %11 Function %23 = OpVariable %11 Function %31 = OpVariable %11 Function %41 = OpVariable %11 Function %164 = OpVariable %11 Function %165 = OpVariable %11 Function %173 = OpVariable %11 Function %184 = OpVariable %183 Function %189 = OpVariable %11 Function %198 = OpVariable %11 Function %325 = OpVariable %11 Function %340 = OpVariable %11 Function %348 = OpVariable %11 Function OpStore %8 %9 OpStore %12 %13 OpBranch %14 %14 = OpLabel OpLoopMerge %16 %17 None OpBranch %18 %18 = OpLabel %19 = OpLoad %10 %12 %22 = OpSLessThanEqual %21 %19 %20 OpBranchConditional %22 %15 %16 %15 = OpLabel OpStore %23 %13 OpBranch %24 %24 = OpLabel OpLoopMerge %26 %27 None OpBranch %28 %28 = OpLabel %29 = OpLoad %10 %23 %30 = OpSLessThanEqual %21 %29 %20 OpBranchConditional %30 %25 %26 %25 = OpLabel OpStore %31 %32 OpBranch %33 %33 = OpLabel OpLoopMerge %35 %36 None OpBranch %37 %37 = OpLabel %38 = OpLoad %10 %31 %39 = OpLoad %10 %12 %40 = OpSLessThan %21 %38 %39 OpBranchConditional %40 %34 %35 %34 = OpLabel OpStore %41 %32 OpBranch %42 %42 = OpLabel OpLoopMerge %44 %45 None OpBranch %46 %46 = OpLabel %47 = OpLoad %10 %41 %48 = OpLoad %10 %23 %49 = OpSLessThan %21 %47 %48 OpBranchConditional %49 %43 %44 %43 = OpLabel %50 = OpLoad %6 %8 OpSelectionMerge %60 None OpSwitch %50 %60 0 %51 1 %52 2 %53 3 %54 4 %55 5 %56 6 %57 7 %58 8 %59 %51 = OpLabel %66 = OpLoad %10 %31 %67 = OpLoad %10 %41 %72 = OpAccessChain %71 %70 %32 %73 = OpLoad %61 %72 %75 = OpAccessChain %74 %65 %66 %67 OpStore %75 %73 OpBranch %60 %52 = OpLabel %81 = OpLoad %10 %31 %82 = OpLoad %10 %41 %83 = OpAccessChain %71 %70 %32 %84 = OpLoad %61 %83 %85 = OpAccessChain %74 %80 %81 %82 OpStore %85 %84 OpBranch %60 %53 = OpLabel %91 = OpLoad %10 %31 %92 = OpLoad %10 %41 %93 = OpAccessChain %71 %70 %32 %94 = OpLoad %61 %93 %95 = OpAccessChain %74 %90 %91 %92 OpStore %95 %94 OpBranch %60 %54 = OpLabel %100 = OpLoad %10 %31 %101 = OpLoad %10 %41 %102 = OpAccessChain %71 %70 %32 %103 = OpLoad %61 %102 %104 = OpAccessChain %74 %99 %100 %101 OpStore %104 %103 OpBranch %60 %55 = OpLabel %109 = OpLoad %10 %31 %110 = OpLoad %10 %41 %111 = OpAccessChain %71 %70 %32 %112 = OpLoad %61 %111 %113 = OpAccessChain %74 %108 %109 %110 OpStore %113 %112 OpBranch %60 %56 = OpLabel %118 = OpLoad %10 %31 %119 = OpLoad %10 %41 %120 = OpAccessChain %71 %70 %32 %121 = OpLoad %61 %120 %122 = OpAccessChain %74 %117 %118 %119 OpStore %122 %121 OpBranch %60 %57 = OpLabel %127 = OpLoad %10 %31 %128 = OpLoad %10 %41 %129 = OpAccessChain %71 %70 %32 %130 = OpLoad %61 %129 %131 = OpAccessChain %74 %126 %127 %128 OpStore %131 %130 OpBranch %60 %58 = OpLabel %136 = OpLoad %10 %31 %137 = OpLoad %10 %41 %138 = OpAccessChain %71 %70 %32 %139 = OpLoad %61 %138 %140 = OpAccessChain %74 %135 %136 %137 OpStore %140 %139 OpBranch %60 %59 = OpLabel %145 = OpLoad %10 %31 %146 = OpLoad %10 %41 %147 = OpAccessChain %71 %70 %32 %148 = OpLoad %61 %147 %149 = OpAccessChain %74 %144 %145 %146 OpStore %149 %148 OpBranch %60 %60 = OpLabel OpBranch %45 %45 = OpLabel %152 = OpLoad %10 %41 %154 = OpIAdd %10 %152 %153 OpStore %41 %154 OpBranch %42 %44 = OpLabel OpBranch %36 %36 = OpLabel %155 = OpLoad %10 %31 %156 = OpIAdd %10 %155 %153 OpStore %31 %156 OpBranch %33 %35 = OpLabel %157 = OpLoad %6 %8 %159 = OpIAdd %6 %157 %158 OpStore %8 %159 OpBranch %27 %27 = OpLabel %160 = OpLoad %10 %23 %161 = OpIAdd %10 %160 %153 OpStore %23 %161 OpBranch %24 %26 = OpLabel OpBranch %17 %17 = OpLabel %162 = OpLoad %10 %12 %163 = OpIAdd %10 %162 %153 OpStore %12 %163 OpBranch %14 %16 = OpLabel OpStore %164 %32 OpStore %165 %13 OpBranch %166 %166 = OpLabel OpLoopMerge %168 %169 None OpBranch %170 %170 = OpLabel %171 = OpLoad %10 %165 %172 = OpSLessThanEqual %21 %171 %20 OpBranchConditional %172 %167 %168 %167 = OpLabel OpStore %173 %13 OpBranch %174 %174 = OpLabel OpLoopMerge %176 %177 None OpBranch %178 %178 = OpLabel %179 = OpLoad %10 %173 %180 = OpSLessThanEqual %21 %179 %20 OpBranchConditional %180 %175 %176 %175 = OpLabel %185 = OpLoad %10 %164 %188 = OpAccessChain %187 %184 %185 OpStore %188 %186 OpStore %189 %32 OpBranch %190 %190 = OpLabel OpLoopMerge %192 %193 None OpBranch %194 %194 = OpLabel %195 = OpLoad %10 %189 %196 = OpLoad %10 %165 %197 = OpSLessThan %21 %195 %196 OpBranchConditional %197 %191 %192 %191 = OpLabel OpStore %198 %32 OpBranch %199 %199 = OpLabel OpLoopMerge %201 %202 None OpBranch %203 %203 = OpLabel %204 = OpLoad %10 %198 %205 = OpLoad %10 %173 %206 = OpSLessThan %21 %204 %205 OpBranchConditional %206 %200 %201 %200 = OpLabel %207 = OpLoad %10 %164 OpSelectionMerge %217 None OpSwitch %207 %217 0 %208 1 %209 2 %210 3 %211 4 %212 5 %213 6 %214 7 %215 8 %216 %208 = OpLabel %218 = OpLoad %10 %164 %219 = OpLoad %10 %189 %220 = OpLoad %10 %198 %221 = OpAccessChain %74 %65 %219 %220 %222 = OpLoad %61 %221 %223 = OpAccessChain %187 %184 %218 %224 = OpLoad %61 %223 %225 = OpFAdd %61 %224 %222 %226 = OpAccessChain %187 %184 %218 OpStore %226 %225 OpBranch %217 %209 = OpLabel %228 = OpLoad %10 %164 %229 = OpLoad %10 %189 %230 = OpLoad %10 %198 %231 = OpAccessChain %74 %80 %229 %230 %232 = OpLoad %61 %231 %233 = OpAccessChain %187 %184 %228 %234 = OpLoad %61 %233 %235 = OpFAdd %61 %234 %232 %236 = OpAccessChain %187 %184 %228 OpStore %236 %235 OpBranch %217 %210 = OpLabel %238 = OpLoad %10 %164 %239 = OpLoad %10 %189 %240 = OpLoad %10 %198 %241 = OpAccessChain %74 %90 %239 %240 %242 = OpLoad %61 %241 %243 = OpAccessChain %187 %184 %238 %244 = OpLoad %61 %243 %245 = OpFAdd %61 %244 %242 %246 = OpAccessChain %187 %184 %238 OpStore %246 %245 OpBranch %217 %211 = OpLabel %248 = OpLoad %10 %164 %249 = OpLoad %10 %189 %250 = OpLoad %10 %198 %251 = OpAccessChain %74 %99 %249 %250 %252 = OpLoad %61 %251 %253 = OpAccessChain %187 %184 %248 %254 = OpLoad %61 %253 %255 = OpFAdd %61 %254 %252 %256 = OpAccessChain %187 %184 %248 OpStore %256 %255 OpBranch %217 %212 = OpLabel %258 = OpLoad %10 %164 %259 = OpLoad %10 %189 %260 = OpLoad %10 %198 %261 = OpAccessChain %74 %108 %259 %260 %262 = OpLoad %61 %261 %263 = OpAccessChain %187 %184 %258 %264 = OpLoad %61 %263 %265 = OpFAdd %61 %264 %262 %266 = OpAccessChain %187 %184 %258 OpStore %266 %265 OpBranch %217 %213 = OpLabel %268 = OpLoad %10 %164 %269 = OpLoad %10 %189 %270 = OpLoad %10 %198 %271 = OpAccessChain %74 %117 %269 %270 %272 = OpLoad %61 %271 %273 = OpAccessChain %187 %184 %268 %274 = OpLoad %61 %273 %275 = OpFAdd %61 %274 %272 %276 = OpAccessChain %187 %184 %268 OpStore %276 %275 OpBranch %217 %214 = OpLabel %278 = OpLoad %10 %164 %279 = OpLoad %10 %189 %280 = OpLoad %10 %198 %281 = OpAccessChain %74 %126 %279 %280 %282 = OpLoad %61 %281 %283 = OpAccessChain %187 %184 %278 %284 = OpLoad %61 %283 %285 = OpFAdd %61 %284 %282 %286 = OpAccessChain %187 %184 %278 OpStore %286 %285 OpBranch %217 %215 = OpLabel %288 = OpLoad %10 %164 %289 = OpLoad %10 %189 %290 = OpLoad %10 %198 %291 = OpAccessChain %74 %135 %289 %290 %292 = OpLoad %61 %291 %293 = OpAccessChain %187 %184 %288 %294 = OpLoad %61 %293 %295 = OpFAdd %61 %294 %292 %296 = OpAccessChain %187 %184 %288 OpStore %296 %295 OpBranch %217 %216 = OpLabel %298 = OpLoad %10 %164 %299 = OpLoad %10 %189 %300 = OpLoad %10 %198 %301 = OpAccessChain %74 %144 %299 %300 %302 = OpLoad %61 %301 %303 = OpAccessChain %187 %184 %298 %304 = OpLoad %61 %303 %305 = OpFAdd %61 %304 %302 %306 = OpAccessChain %187 %184 %298 OpStore %306 %305 OpBranch %217 %217 = OpLabel OpBranch %202 %202 = OpLabel %309 = OpLoad %10 %198 %310 = OpIAdd %10 %309 %153 OpStore %198 %310 OpBranch %199 %201 = OpLabel OpBranch %193 %193 = OpLabel %311 = OpLoad %10 %189 %312 = OpIAdd %10 %311 %153 OpStore %189 %312 OpBranch %190 %192 = OpLabel %313 = OpLoad %10 %164 %315 = OpAccessChain %187 %184 %313 %316 = OpLoad %61 %315 %317 = OpFDiv %61 %316 %314 %318 = OpAccessChain %187 %184 %313 OpStore %318 %317 %319 = OpLoad %10 %164 %320 = OpIAdd %10 %319 %153 OpStore %164 %320 OpBranch %177 %177 = OpLabel %321 = OpLoad %10 %173 %322 = OpIAdd %10 %321 %153 OpStore %173 %322 OpBranch %174 %176 = OpLabel OpBranch %169 %169 = OpLabel %323 = OpLoad %10 %165 %324 = OpIAdd %10 %323 %153 OpStore %165 %324 OpBranch %166 %168 = OpLabel %329 = OpAccessChain %328 %327 %9 %330 = OpLoad %61 %329 %334 = OpAccessChain %71 %333 %32 %9 %335 = OpLoad %61 %334 %337 = OpFDiv %61 %335 %336 %338 = OpFDiv %61 %330 %337 %339 = OpConvertFToS %10 %338 OpStore %325 %339 %341 = OpAccessChain %328 %327 %158 %342 = OpLoad %61 %341 %343 = OpAccessChain %71 %333 %32 %9 %344 = OpLoad %61 %343 %345 = OpFDiv %61 %344 %336 %346 = OpFDiv %61 %342 %345 %347 = OpConvertFToS %10 %346 OpStore %340 %347 %349 = OpLoad %10 %340 %351 = OpIMul %10 %349 %350 %352 = OpLoad %10 %325 %353 = OpIAdd %10 %351 %352 OpStore %348 %353 %354 = OpLoad %10 %348 %355 = OpSGreaterThan %21 %354 %32 %356 = OpLoad %10 %348 %358 = OpSLessThan %21 %356 %357 %359 = OpLogicalAnd %21 %355 %358 OpSelectionMerge %361 None OpBranchConditional %359 %360 %373 %360 = OpLabel %364 = OpLoad %10 %348 %365 = OpAccessChain %187 %184 %364 %366 = OpLoad %61 %365 %367 = OpCompositeConstruct %77 %366 %366 %366 %369 = OpCompositeExtract %61 %367 0 %370 = OpCompositeExtract %61 %367 1 %371 = OpCompositeExtract %61 %367 2 %372 = OpCompositeConstruct %87 %369 %370 %371 %368 OpStore %363 %372 OpBranch %361 %373 = OpLabel OpStore %363 %374 OpBranch %361 %361 = OpLabel OpReturn OpFunctionEnd )"; // The SPIR-V comes from the following GLSL: // // #version 310 es // precision highp float; // // layout(location = 0) out vec4 color; // // void main() // { // color = vec4(1.0, 0.0, 0.0, 1.0); // } const std::string kTestShader5 = R"( OpCapability Shader %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 OpEntryPoint Fragment %4 "main" %9 OpExecutionMode %4 OriginUpperLeft OpSource ESSL 310 OpName %4 "main" OpName %9 "color" OpDecorate %9 Location 0 %2 = OpTypeVoid %3 = OpTypeFunction %2 %6 = OpTypeFloat 32 %7 = OpTypeVector %6 4 %8 = OpTypePointer Output %7 %9 = OpVariable %8 Output %10 = OpConstant %6 1 %11 = OpConstant %6 0 %12 = OpConstantComposite %7 %10 %11 %11 %10 %4 = OpFunction %2 None %3 %5 = OpLabel OpStore %9 %12 OpReturn OpFunctionEnd )"; // Some miscellaneous SPIR-V. const std::string kTestShader6 = R"( OpCapability Shader OpCapability SampledBuffer OpCapability ImageBuffer %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 OpEntryPoint Fragment %2 "main" %40 %41 OpExecutionMode %2 OriginUpperLeft OpSource GLSL 450 OpDecorate %40 DescriptorSet 0 OpDecorate %40 Binding 69 OpDecorate %41 DescriptorSet 0 OpDecorate %41 Binding 1 %54 = OpTypeFloat 32 %76 = OpTypeVector %54 4 %55 = OpConstant %54 0 %56 = OpTypeVector %54 3 %94 = OpTypeVector %54 2 %112 = OpConstantComposite %94 %55 %55 %57 = OpConstantComposite %56 %55 %55 %55 %15 = OpTypeImage %54 2D 2 0 0 1 Unknown %114 = OpTypePointer UniformConstant %15 %38 = OpTypeSampler %125 = OpTypePointer UniformConstant %38 %132 = OpTypeVoid %133 = OpTypeFunction %132 %45 = OpTypeSampledImage %15 %40 = OpVariable %114 UniformConstant %41 = OpVariable %125 UniformConstant %2 = OpFunction %132 None %133 %164 = OpLabel %184 = OpLoad %15 %40 %213 = OpLoad %38 %41 %216 = OpSampledImage %45 %184 %213 %217 = OpImageSampleImplicitLod %76 %216 %112 Bias %55 OpReturn OpFunctionEnd )"; void AddConstantUniformFact(protobufs::FactSequence* facts, uint32_t descriptor_set, uint32_t binding, std::vector&& indices, uint32_t value) { protobufs::FactConstantUniform fact; *fact.mutable_uniform_buffer_element_descriptor() = MakeUniformBufferElementDescriptor(descriptor_set, binding, std::move(indices)); *fact.mutable_constant_word()->Add() = value; protobufs::Fact temp; *temp.mutable_constant_uniform_fact() = fact; *facts->mutable_fact()->Add() = temp; } // Reinterpret the bits of |value| as a 32-bit unsigned int uint32_t FloatBitsAsUint(float value) { uint32_t result; memcpy(&result, &value, sizeof(float)); return result; } // Assembles the given |shader| text, and then runs the fuzzer |num_runs| // times, using successive seeds starting from |initial_seed|. Checks that // the binary produced after each fuzzer run is valid, and that replaying // the transformations that were applied during fuzzing leads to an // identical binary. void RunFuzzerAndReplayer(const std::string& shader, const protobufs::FactSequence& initial_facts, uint32_t initial_seed, uint32_t num_runs) { const auto env = SPV_ENV_UNIVERSAL_1_5; std::vector binary_in; SpirvTools t(env); t.SetMessageConsumer(kConsoleMessageConsumer); ASSERT_TRUE(t.Assemble(shader, &binary_in, kFuzzAssembleOption)); ASSERT_TRUE(t.Validate(binary_in)); std::vector donor_suppliers; for (auto donor : {&kTestShader1, &kTestShader2, &kTestShader3, &kTestShader4, &kTestShader5, &kTestShader6}) { donor_suppliers.emplace_back([donor]() { return BuildModule(env, kConsoleMessageConsumer, *donor, kFuzzAssembleOption); }); } for (uint32_t seed = initial_seed; seed < initial_seed + num_runs; seed++) { std::vector fuzzer_binary_out; protobufs::TransformationSequence fuzzer_transformation_sequence_out; spvtools::ValidatorOptions validator_options; Fuzzer fuzzer(env, seed, true, validator_options); fuzzer.SetMessageConsumer(kConsoleMessageConsumer); auto fuzzer_result_status = fuzzer.Run(binary_in, initial_facts, donor_suppliers, &fuzzer_binary_out, &fuzzer_transformation_sequence_out); ASSERT_EQ(Fuzzer::FuzzerResultStatus::kComplete, fuzzer_result_status); ASSERT_TRUE(t.Validate(fuzzer_binary_out)); std::vector replayer_binary_out; protobufs::TransformationSequence replayer_transformation_sequence_out; Replayer replayer(env, false, validator_options); replayer.SetMessageConsumer(kConsoleMessageConsumer); auto replayer_result_status = replayer.Run( binary_in, initial_facts, fuzzer_transformation_sequence_out, &replayer_binary_out, &replayer_transformation_sequence_out); ASSERT_EQ(Replayer::ReplayerResultStatus::kComplete, replayer_result_status); // After replaying the transformations applied by the fuzzer, exactly those // transformations should have been applied, and the binary resulting from // replay should be identical to that which resulted from fuzzing. std::string fuzzer_transformations_string; std::string replayer_transformations_string; fuzzer_transformation_sequence_out.SerializeToString( &fuzzer_transformations_string); replayer_transformation_sequence_out.SerializeToString( &replayer_transformations_string); ASSERT_EQ(fuzzer_transformations_string, replayer_transformations_string); ASSERT_EQ(fuzzer_binary_out, replayer_binary_out); } } TEST(FuzzerReplayerTest, Miscellaneous1) { // Do some fuzzer runs, starting from an initial seed of 0 (seed value chosen // arbitrarily). RunFuzzerAndReplayer(kTestShader1, protobufs::FactSequence(), 0, kNumFuzzerRuns); } TEST(FuzzerReplayerTest, Miscellaneous2) { // Do some fuzzer runs, starting from an initial seed of 10 (seed value chosen // arbitrarily). RunFuzzerAndReplayer(kTestShader2, protobufs::FactSequence(), 10, kNumFuzzerRuns); } TEST(FuzzerReplayerTest, Miscellaneous3) { // Add the facts "resolution.x == 250" and "resolution.y == 100". protobufs::FactSequence facts; AddConstantUniformFact(&facts, 0, 0, {0, 0}, 250); AddConstantUniformFact(&facts, 0, 0, {0, 1}, 100); // Do some fuzzer runs, starting from an initial seed of 94 (seed value chosen // arbitrarily). RunFuzzerAndReplayer(kTestShader3, facts, 94, kNumFuzzerRuns); } TEST(FuzzerReplayerTest, Miscellaneous4) { // Add the facts: // - "one == 1.0" // - "resolution.y == 256.0", protobufs::FactSequence facts; AddConstantUniformFact(&facts, 0, 0, {0}, FloatBitsAsUint(1.0)); AddConstantUniformFact(&facts, 0, 1, {0, 0}, FloatBitsAsUint(256.0)); AddConstantUniformFact(&facts, 0, 1, {0, 1}, FloatBitsAsUint(256.0)); // Do some fuzzer runs, starting from an initial seed of 14 (seed value chosen // arbitrarily). RunFuzzerAndReplayer(kTestShader4, facts, 14, kNumFuzzerRuns); } TEST(FuzzerReplayerTest, Miscellaneous5) { // Do some fuzzer runs, starting from an initial seed of 29 (seed value chosen // arbitrarily). RunFuzzerAndReplayer(kTestShader5, protobufs::FactSequence(), 29, kNumFuzzerRuns); } TEST(FuzzerReplayerTest, Miscellaneous6) { // Do some fuzzer runs, starting from an initial seed of 57 (seed value chosen // arbitrarily). RunFuzzerAndReplayer(kTestShader6, protobufs::FactSequence(), 57, kNumFuzzerRuns); } } // namespace } // namespace fuzz } // namespace spvtools