1fd4e5da5Sopenharmony_ci// Copyright (c) 2019 Google LLC 2fd4e5da5Sopenharmony_ci// 3fd4e5da5Sopenharmony_ci// Licensed under the Apache License, Version 2.0 (the "License"); 4fd4e5da5Sopenharmony_ci// you may not use this file except in compliance with the License. 5fd4e5da5Sopenharmony_ci// You may obtain a copy of the License at 6fd4e5da5Sopenharmony_ci// 7fd4e5da5Sopenharmony_ci// http://www.apache.org/licenses/LICENSE-2.0 8fd4e5da5Sopenharmony_ci// 9fd4e5da5Sopenharmony_ci// Unless required by applicable law or agreed to in writing, software 10fd4e5da5Sopenharmony_ci// distributed under the License is distributed on an "AS IS" BASIS, 11fd4e5da5Sopenharmony_ci// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12fd4e5da5Sopenharmony_ci// See the License for the specific language governing permissions and 13fd4e5da5Sopenharmony_ci// limitations under the License. 14fd4e5da5Sopenharmony_ci 15fd4e5da5Sopenharmony_ci#include <functional> 16fd4e5da5Sopenharmony_ci#include <vector> 17fd4e5da5Sopenharmony_ci 18fd4e5da5Sopenharmony_ci#include "gtest/gtest.h" 19fd4e5da5Sopenharmony_ci#include "source/fuzz/fuzzer.h" 20fd4e5da5Sopenharmony_ci#include "source/fuzz/fuzzer_util.h" 21fd4e5da5Sopenharmony_ci#include "source/fuzz/pseudo_random_generator.h" 22fd4e5da5Sopenharmony_ci#include "source/fuzz/shrinker.h" 23fd4e5da5Sopenharmony_ci#include "source/fuzz/uniform_buffer_element_descriptor.h" 24fd4e5da5Sopenharmony_ci#include "test/fuzz/fuzz_test_util.h" 25fd4e5da5Sopenharmony_ci 26fd4e5da5Sopenharmony_cinamespace spvtools { 27fd4e5da5Sopenharmony_cinamespace fuzz { 28fd4e5da5Sopenharmony_cinamespace { 29fd4e5da5Sopenharmony_ci 30fd4e5da5Sopenharmony_ci// The following SPIR-V came from this GLSL: 31fd4e5da5Sopenharmony_ci// 32fd4e5da5Sopenharmony_ci// #version 310 es 33fd4e5da5Sopenharmony_ci// 34fd4e5da5Sopenharmony_ci// void foo() { 35fd4e5da5Sopenharmony_ci// int x; 36fd4e5da5Sopenharmony_ci// x = 2; 37fd4e5da5Sopenharmony_ci// for (int i = 0; i < 100; i++) { 38fd4e5da5Sopenharmony_ci// x += i; 39fd4e5da5Sopenharmony_ci// x = x * 2; 40fd4e5da5Sopenharmony_ci// } 41fd4e5da5Sopenharmony_ci// return; 42fd4e5da5Sopenharmony_ci// } 43fd4e5da5Sopenharmony_ci// 44fd4e5da5Sopenharmony_ci// void main() { 45fd4e5da5Sopenharmony_ci// foo(); 46fd4e5da5Sopenharmony_ci// for (int i = 0; i < 10; i++) { 47fd4e5da5Sopenharmony_ci// int j = 20; 48fd4e5da5Sopenharmony_ci// while(j > 0) { 49fd4e5da5Sopenharmony_ci// foo(); 50fd4e5da5Sopenharmony_ci// j--; 51fd4e5da5Sopenharmony_ci// } 52fd4e5da5Sopenharmony_ci// do { 53fd4e5da5Sopenharmony_ci// i++; 54fd4e5da5Sopenharmony_ci// } while(i < 4); 55fd4e5da5Sopenharmony_ci// } 56fd4e5da5Sopenharmony_ci// } 57fd4e5da5Sopenharmony_ci 58fd4e5da5Sopenharmony_ciconst std::string kTestShader1 = R"( 59fd4e5da5Sopenharmony_ci OpCapability Shader 60fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 61fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 62fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 63fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 64fd4e5da5Sopenharmony_ci OpSource ESSL 310 65fd4e5da5Sopenharmony_ci OpName %4 "main" 66fd4e5da5Sopenharmony_ci OpName %6 "foo(" 67fd4e5da5Sopenharmony_ci OpName %10 "x" 68fd4e5da5Sopenharmony_ci OpName %12 "i" 69fd4e5da5Sopenharmony_ci OpName %33 "i" 70fd4e5da5Sopenharmony_ci OpName %42 "j" 71fd4e5da5Sopenharmony_ci OpDecorate %10 RelaxedPrecision 72fd4e5da5Sopenharmony_ci OpDecorate %12 RelaxedPrecision 73fd4e5da5Sopenharmony_ci OpDecorate %19 RelaxedPrecision 74fd4e5da5Sopenharmony_ci OpDecorate %23 RelaxedPrecision 75fd4e5da5Sopenharmony_ci OpDecorate %24 RelaxedPrecision 76fd4e5da5Sopenharmony_ci OpDecorate %25 RelaxedPrecision 77fd4e5da5Sopenharmony_ci OpDecorate %26 RelaxedPrecision 78fd4e5da5Sopenharmony_ci OpDecorate %27 RelaxedPrecision 79fd4e5da5Sopenharmony_ci OpDecorate %28 RelaxedPrecision 80fd4e5da5Sopenharmony_ci OpDecorate %30 RelaxedPrecision 81fd4e5da5Sopenharmony_ci OpDecorate %33 RelaxedPrecision 82fd4e5da5Sopenharmony_ci OpDecorate %39 RelaxedPrecision 83fd4e5da5Sopenharmony_ci OpDecorate %42 RelaxedPrecision 84fd4e5da5Sopenharmony_ci OpDecorate %49 RelaxedPrecision 85fd4e5da5Sopenharmony_ci OpDecorate %52 RelaxedPrecision 86fd4e5da5Sopenharmony_ci OpDecorate %53 RelaxedPrecision 87fd4e5da5Sopenharmony_ci OpDecorate %58 RelaxedPrecision 88fd4e5da5Sopenharmony_ci OpDecorate %59 RelaxedPrecision 89fd4e5da5Sopenharmony_ci OpDecorate %60 RelaxedPrecision 90fd4e5da5Sopenharmony_ci OpDecorate %63 RelaxedPrecision 91fd4e5da5Sopenharmony_ci OpDecorate %64 RelaxedPrecision 92fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 93fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 94fd4e5da5Sopenharmony_ci %8 = OpTypeInt 32 1 95fd4e5da5Sopenharmony_ci %9 = OpTypePointer Function %8 96fd4e5da5Sopenharmony_ci %11 = OpConstant %8 2 97fd4e5da5Sopenharmony_ci %13 = OpConstant %8 0 98fd4e5da5Sopenharmony_ci %20 = OpConstant %8 100 99fd4e5da5Sopenharmony_ci %21 = OpTypeBool 100fd4e5da5Sopenharmony_ci %29 = OpConstant %8 1 101fd4e5da5Sopenharmony_ci %40 = OpConstant %8 10 102fd4e5da5Sopenharmony_ci %43 = OpConstant %8 20 103fd4e5da5Sopenharmony_ci %61 = OpConstant %8 4 104fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 105fd4e5da5Sopenharmony_ci %5 = OpLabel 106fd4e5da5Sopenharmony_ci %33 = OpVariable %9 Function 107fd4e5da5Sopenharmony_ci %42 = OpVariable %9 Function 108fd4e5da5Sopenharmony_ci %32 = OpFunctionCall %2 %6 109fd4e5da5Sopenharmony_ci OpStore %33 %13 110fd4e5da5Sopenharmony_ci OpBranch %34 111fd4e5da5Sopenharmony_ci %34 = OpLabel 112fd4e5da5Sopenharmony_ci OpLoopMerge %36 %37 None 113fd4e5da5Sopenharmony_ci OpBranch %38 114fd4e5da5Sopenharmony_ci %38 = OpLabel 115fd4e5da5Sopenharmony_ci %39 = OpLoad %8 %33 116fd4e5da5Sopenharmony_ci %41 = OpSLessThan %21 %39 %40 117fd4e5da5Sopenharmony_ci OpBranchConditional %41 %35 %36 118fd4e5da5Sopenharmony_ci %35 = OpLabel 119fd4e5da5Sopenharmony_ci OpStore %42 %43 120fd4e5da5Sopenharmony_ci OpBranch %44 121fd4e5da5Sopenharmony_ci %44 = OpLabel 122fd4e5da5Sopenharmony_ci OpLoopMerge %46 %47 None 123fd4e5da5Sopenharmony_ci OpBranch %48 124fd4e5da5Sopenharmony_ci %48 = OpLabel 125fd4e5da5Sopenharmony_ci %49 = OpLoad %8 %42 126fd4e5da5Sopenharmony_ci %50 = OpSGreaterThan %21 %49 %13 127fd4e5da5Sopenharmony_ci OpBranchConditional %50 %45 %46 128fd4e5da5Sopenharmony_ci %45 = OpLabel 129fd4e5da5Sopenharmony_ci %51 = OpFunctionCall %2 %6 130fd4e5da5Sopenharmony_ci %52 = OpLoad %8 %42 131fd4e5da5Sopenharmony_ci %53 = OpISub %8 %52 %29 132fd4e5da5Sopenharmony_ci OpStore %42 %53 133fd4e5da5Sopenharmony_ci OpBranch %47 134fd4e5da5Sopenharmony_ci %47 = OpLabel 135fd4e5da5Sopenharmony_ci OpBranch %44 136fd4e5da5Sopenharmony_ci %46 = OpLabel 137fd4e5da5Sopenharmony_ci OpBranch %54 138fd4e5da5Sopenharmony_ci %54 = OpLabel 139fd4e5da5Sopenharmony_ci OpLoopMerge %56 %57 None 140fd4e5da5Sopenharmony_ci OpBranch %55 141fd4e5da5Sopenharmony_ci %55 = OpLabel 142fd4e5da5Sopenharmony_ci %58 = OpLoad %8 %33 143fd4e5da5Sopenharmony_ci %59 = OpIAdd %8 %58 %29 144fd4e5da5Sopenharmony_ci OpStore %33 %59 145fd4e5da5Sopenharmony_ci OpBranch %57 146fd4e5da5Sopenharmony_ci %57 = OpLabel 147fd4e5da5Sopenharmony_ci %60 = OpLoad %8 %33 148fd4e5da5Sopenharmony_ci %62 = OpSLessThan %21 %60 %61 149fd4e5da5Sopenharmony_ci OpBranchConditional %62 %54 %56 150fd4e5da5Sopenharmony_ci %56 = OpLabel 151fd4e5da5Sopenharmony_ci OpBranch %37 152fd4e5da5Sopenharmony_ci %37 = OpLabel 153fd4e5da5Sopenharmony_ci %63 = OpLoad %8 %33 154fd4e5da5Sopenharmony_ci %64 = OpIAdd %8 %63 %29 155fd4e5da5Sopenharmony_ci OpStore %33 %64 156fd4e5da5Sopenharmony_ci OpBranch %34 157fd4e5da5Sopenharmony_ci %36 = OpLabel 158fd4e5da5Sopenharmony_ci OpReturn 159fd4e5da5Sopenharmony_ci OpFunctionEnd 160fd4e5da5Sopenharmony_ci %6 = OpFunction %2 None %3 161fd4e5da5Sopenharmony_ci %7 = OpLabel 162fd4e5da5Sopenharmony_ci %10 = OpVariable %9 Function 163fd4e5da5Sopenharmony_ci %12 = OpVariable %9 Function 164fd4e5da5Sopenharmony_ci OpStore %10 %11 165fd4e5da5Sopenharmony_ci OpStore %12 %13 166fd4e5da5Sopenharmony_ci OpBranch %14 167fd4e5da5Sopenharmony_ci %14 = OpLabel 168fd4e5da5Sopenharmony_ci OpLoopMerge %16 %17 None 169fd4e5da5Sopenharmony_ci OpBranch %18 170fd4e5da5Sopenharmony_ci %18 = OpLabel 171fd4e5da5Sopenharmony_ci %19 = OpLoad %8 %12 172fd4e5da5Sopenharmony_ci %22 = OpSLessThan %21 %19 %20 173fd4e5da5Sopenharmony_ci OpBranchConditional %22 %15 %16 174fd4e5da5Sopenharmony_ci %15 = OpLabel 175fd4e5da5Sopenharmony_ci %23 = OpLoad %8 %12 176fd4e5da5Sopenharmony_ci %24 = OpLoad %8 %10 177fd4e5da5Sopenharmony_ci %25 = OpIAdd %8 %24 %23 178fd4e5da5Sopenharmony_ci OpStore %10 %25 179fd4e5da5Sopenharmony_ci %26 = OpLoad %8 %10 180fd4e5da5Sopenharmony_ci %27 = OpIMul %8 %26 %11 181fd4e5da5Sopenharmony_ci OpStore %10 %27 182fd4e5da5Sopenharmony_ci OpBranch %17 183fd4e5da5Sopenharmony_ci %17 = OpLabel 184fd4e5da5Sopenharmony_ci %28 = OpLoad %8 %12 185fd4e5da5Sopenharmony_ci %30 = OpIAdd %8 %28 %29 186fd4e5da5Sopenharmony_ci OpStore %12 %30 187fd4e5da5Sopenharmony_ci OpBranch %14 188fd4e5da5Sopenharmony_ci %16 = OpLabel 189fd4e5da5Sopenharmony_ci OpReturn 190fd4e5da5Sopenharmony_ci OpFunctionEnd 191fd4e5da5Sopenharmony_ci 192fd4e5da5Sopenharmony_ci )"; 193fd4e5da5Sopenharmony_ci 194fd4e5da5Sopenharmony_ci// The following SPIR-V came from this GLSL, which was then optimized using 195fd4e5da5Sopenharmony_ci// spirv-opt with the -O argument: 196fd4e5da5Sopenharmony_ci// 197fd4e5da5Sopenharmony_ci// #version 310 es 198fd4e5da5Sopenharmony_ci// 199fd4e5da5Sopenharmony_ci// precision highp float; 200fd4e5da5Sopenharmony_ci// 201fd4e5da5Sopenharmony_ci// layout(location = 0) out vec4 _GLF_color; 202fd4e5da5Sopenharmony_ci// 203fd4e5da5Sopenharmony_ci// layout(set = 0, binding = 0) uniform buf0 { 204fd4e5da5Sopenharmony_ci// vec2 injectionSwitch; 205fd4e5da5Sopenharmony_ci// }; 206fd4e5da5Sopenharmony_ci// layout(set = 0, binding = 1) uniform buf1 { 207fd4e5da5Sopenharmony_ci// vec2 resolution; 208fd4e5da5Sopenharmony_ci// }; 209fd4e5da5Sopenharmony_ci// bool checkSwap(float a, float b) 210fd4e5da5Sopenharmony_ci// { 211fd4e5da5Sopenharmony_ci// return gl_FragCoord.y < resolution.y / 2.0 ? a > b : a < b; 212fd4e5da5Sopenharmony_ci// } 213fd4e5da5Sopenharmony_ci// void main() 214fd4e5da5Sopenharmony_ci// { 215fd4e5da5Sopenharmony_ci// float data[10]; 216fd4e5da5Sopenharmony_ci// for(int i = 0; i < 10; i++) 217fd4e5da5Sopenharmony_ci// { 218fd4e5da5Sopenharmony_ci// data[i] = float(10 - i) * injectionSwitch.y; 219fd4e5da5Sopenharmony_ci// } 220fd4e5da5Sopenharmony_ci// for(int i = 0; i < 9; i++) 221fd4e5da5Sopenharmony_ci// { 222fd4e5da5Sopenharmony_ci// for(int j = 0; j < 10; j++) 223fd4e5da5Sopenharmony_ci// { 224fd4e5da5Sopenharmony_ci// if(j < i + 1) 225fd4e5da5Sopenharmony_ci// { 226fd4e5da5Sopenharmony_ci// continue; 227fd4e5da5Sopenharmony_ci// } 228fd4e5da5Sopenharmony_ci// bool doSwap = checkSwap(data[i], data[j]); 229fd4e5da5Sopenharmony_ci// if(doSwap) 230fd4e5da5Sopenharmony_ci// { 231fd4e5da5Sopenharmony_ci// float temp = data[i]; 232fd4e5da5Sopenharmony_ci// data[i] = data[j]; 233fd4e5da5Sopenharmony_ci// data[j] = temp; 234fd4e5da5Sopenharmony_ci// } 235fd4e5da5Sopenharmony_ci// } 236fd4e5da5Sopenharmony_ci// } 237fd4e5da5Sopenharmony_ci// if(gl_FragCoord.x < resolution.x / 2.0) 238fd4e5da5Sopenharmony_ci// { 239fd4e5da5Sopenharmony_ci// _GLF_color = vec4(data[0] / 10.0, data[5] / 10.0, data[9] / 10.0, 1.0); 240fd4e5da5Sopenharmony_ci// } 241fd4e5da5Sopenharmony_ci// else 242fd4e5da5Sopenharmony_ci// { 243fd4e5da5Sopenharmony_ci// _GLF_color = vec4(data[5] / 10.0, data[9] / 10.0, data[0] / 10.0, 1.0); 244fd4e5da5Sopenharmony_ci// } 245fd4e5da5Sopenharmony_ci// } 246fd4e5da5Sopenharmony_ci 247fd4e5da5Sopenharmony_ciconst std::string kTestShader2 = R"( 248fd4e5da5Sopenharmony_ci OpCapability Shader 249fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 250fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 251fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" %16 %139 %25 %68 252fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 253fd4e5da5Sopenharmony_ci OpSource ESSL 310 254fd4e5da5Sopenharmony_ci OpName %4 "main" 255fd4e5da5Sopenharmony_ci OpName %16 "gl_FragCoord" 256fd4e5da5Sopenharmony_ci OpName %23 "buf1" 257fd4e5da5Sopenharmony_ci OpMemberName %23 0 "resolution" 258fd4e5da5Sopenharmony_ci OpName %25 "" 259fd4e5da5Sopenharmony_ci OpName %61 "data" 260fd4e5da5Sopenharmony_ci OpName %66 "buf0" 261fd4e5da5Sopenharmony_ci OpMemberName %66 0 "injectionSwitch" 262fd4e5da5Sopenharmony_ci OpName %68 "" 263fd4e5da5Sopenharmony_ci OpName %139 "_GLF_color" 264fd4e5da5Sopenharmony_ci OpDecorate %16 BuiltIn FragCoord 265fd4e5da5Sopenharmony_ci OpMemberDecorate %23 0 Offset 0 266fd4e5da5Sopenharmony_ci OpDecorate %23 Block 267fd4e5da5Sopenharmony_ci OpDecorate %25 DescriptorSet 0 268fd4e5da5Sopenharmony_ci OpDecorate %25 Binding 1 269fd4e5da5Sopenharmony_ci OpDecorate %64 RelaxedPrecision 270fd4e5da5Sopenharmony_ci OpMemberDecorate %66 0 Offset 0 271fd4e5da5Sopenharmony_ci OpDecorate %66 Block 272fd4e5da5Sopenharmony_ci OpDecorate %68 DescriptorSet 0 273fd4e5da5Sopenharmony_ci OpDecorate %68 Binding 0 274fd4e5da5Sopenharmony_ci OpDecorate %75 RelaxedPrecision 275fd4e5da5Sopenharmony_ci OpDecorate %95 RelaxedPrecision 276fd4e5da5Sopenharmony_ci OpDecorate %126 RelaxedPrecision 277fd4e5da5Sopenharmony_ci OpDecorate %128 RelaxedPrecision 278fd4e5da5Sopenharmony_ci OpDecorate %139 Location 0 279fd4e5da5Sopenharmony_ci OpDecorate %182 RelaxedPrecision 280fd4e5da5Sopenharmony_ci OpDecorate %183 RelaxedPrecision 281fd4e5da5Sopenharmony_ci OpDecorate %184 RelaxedPrecision 282fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 283fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 284fd4e5da5Sopenharmony_ci %6 = OpTypeFloat 32 285fd4e5da5Sopenharmony_ci %7 = OpTypePointer Function %6 286fd4e5da5Sopenharmony_ci %8 = OpTypeBool 287fd4e5da5Sopenharmony_ci %14 = OpTypeVector %6 4 288fd4e5da5Sopenharmony_ci %15 = OpTypePointer Input %14 289fd4e5da5Sopenharmony_ci %16 = OpVariable %15 Input 290fd4e5da5Sopenharmony_ci %17 = OpTypeInt 32 0 291fd4e5da5Sopenharmony_ci %18 = OpConstant %17 1 292fd4e5da5Sopenharmony_ci %19 = OpTypePointer Input %6 293fd4e5da5Sopenharmony_ci %22 = OpTypeVector %6 2 294fd4e5da5Sopenharmony_ci %23 = OpTypeStruct %22 295fd4e5da5Sopenharmony_ci %24 = OpTypePointer Uniform %23 296fd4e5da5Sopenharmony_ci %25 = OpVariable %24 Uniform 297fd4e5da5Sopenharmony_ci %26 = OpTypeInt 32 1 298fd4e5da5Sopenharmony_ci %27 = OpConstant %26 0 299fd4e5da5Sopenharmony_ci %28 = OpTypePointer Uniform %6 300fd4e5da5Sopenharmony_ci %56 = OpConstant %26 10 301fd4e5da5Sopenharmony_ci %58 = OpConstant %17 10 302fd4e5da5Sopenharmony_ci %59 = OpTypeArray %6 %58 303fd4e5da5Sopenharmony_ci %60 = OpTypePointer Function %59 304fd4e5da5Sopenharmony_ci %66 = OpTypeStruct %22 305fd4e5da5Sopenharmony_ci %67 = OpTypePointer Uniform %66 306fd4e5da5Sopenharmony_ci %68 = OpVariable %67 Uniform 307fd4e5da5Sopenharmony_ci %74 = OpConstant %26 1 308fd4e5da5Sopenharmony_ci %83 = OpConstant %26 9 309fd4e5da5Sopenharmony_ci %129 = OpConstant %17 0 310fd4e5da5Sopenharmony_ci %138 = OpTypePointer Output %14 311fd4e5da5Sopenharmony_ci %139 = OpVariable %138 Output 312fd4e5da5Sopenharmony_ci %144 = OpConstant %26 5 313fd4e5da5Sopenharmony_ci %151 = OpConstant %6 1 314fd4e5da5Sopenharmony_ci %194 = OpConstant %6 0.5 315fd4e5da5Sopenharmony_ci %195 = OpConstant %6 0.100000001 316fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 317fd4e5da5Sopenharmony_ci %5 = OpLabel 318fd4e5da5Sopenharmony_ci %61 = OpVariable %60 Function 319fd4e5da5Sopenharmony_ci OpBranch %50 320fd4e5da5Sopenharmony_ci %50 = OpLabel 321fd4e5da5Sopenharmony_ci %182 = OpPhi %26 %27 %5 %75 %51 322fd4e5da5Sopenharmony_ci %57 = OpSLessThan %8 %182 %56 323fd4e5da5Sopenharmony_ci OpLoopMerge %52 %51 None 324fd4e5da5Sopenharmony_ci OpBranchConditional %57 %51 %52 325fd4e5da5Sopenharmony_ci %51 = OpLabel 326fd4e5da5Sopenharmony_ci %64 = OpISub %26 %56 %182 327fd4e5da5Sopenharmony_ci %65 = OpConvertSToF %6 %64 328fd4e5da5Sopenharmony_ci %69 = OpAccessChain %28 %68 %27 %18 329fd4e5da5Sopenharmony_ci %70 = OpLoad %6 %69 330fd4e5da5Sopenharmony_ci %71 = OpFMul %6 %65 %70 331fd4e5da5Sopenharmony_ci %72 = OpAccessChain %7 %61 %182 332fd4e5da5Sopenharmony_ci OpStore %72 %71 333fd4e5da5Sopenharmony_ci %75 = OpIAdd %26 %182 %74 334fd4e5da5Sopenharmony_ci OpBranch %50 335fd4e5da5Sopenharmony_ci %52 = OpLabel 336fd4e5da5Sopenharmony_ci OpBranch %77 337fd4e5da5Sopenharmony_ci %77 = OpLabel 338fd4e5da5Sopenharmony_ci %183 = OpPhi %26 %27 %52 %128 %88 339fd4e5da5Sopenharmony_ci %84 = OpSLessThan %8 %183 %83 340fd4e5da5Sopenharmony_ci OpLoopMerge %79 %88 None 341fd4e5da5Sopenharmony_ci OpBranchConditional %84 %78 %79 342fd4e5da5Sopenharmony_ci %78 = OpLabel 343fd4e5da5Sopenharmony_ci OpBranch %86 344fd4e5da5Sopenharmony_ci %86 = OpLabel 345fd4e5da5Sopenharmony_ci %184 = OpPhi %26 %27 %78 %126 %89 346fd4e5da5Sopenharmony_ci %92 = OpSLessThan %8 %184 %56 347fd4e5da5Sopenharmony_ci OpLoopMerge %1000 %89 None 348fd4e5da5Sopenharmony_ci OpBranchConditional %92 %87 %1000 349fd4e5da5Sopenharmony_ci %87 = OpLabel 350fd4e5da5Sopenharmony_ci %95 = OpIAdd %26 %183 %74 351fd4e5da5Sopenharmony_ci %96 = OpSLessThan %8 %184 %95 352fd4e5da5Sopenharmony_ci OpSelectionMerge %98 None 353fd4e5da5Sopenharmony_ci OpBranchConditional %96 %97 %98 354fd4e5da5Sopenharmony_ci %97 = OpLabel 355fd4e5da5Sopenharmony_ci OpBranch %89 356fd4e5da5Sopenharmony_ci %98 = OpLabel 357fd4e5da5Sopenharmony_ci %104 = OpAccessChain %7 %61 %183 358fd4e5da5Sopenharmony_ci %105 = OpLoad %6 %104 359fd4e5da5Sopenharmony_ci %107 = OpAccessChain %7 %61 %184 360fd4e5da5Sopenharmony_ci %108 = OpLoad %6 %107 361fd4e5da5Sopenharmony_ci %166 = OpAccessChain %19 %16 %18 362fd4e5da5Sopenharmony_ci %167 = OpLoad %6 %166 363fd4e5da5Sopenharmony_ci %168 = OpAccessChain %28 %25 %27 %18 364fd4e5da5Sopenharmony_ci %169 = OpLoad %6 %168 365fd4e5da5Sopenharmony_ci %170 = OpFMul %6 %169 %194 366fd4e5da5Sopenharmony_ci %171 = OpFOrdLessThan %8 %167 %170 367fd4e5da5Sopenharmony_ci OpSelectionMerge %172 None 368fd4e5da5Sopenharmony_ci OpBranchConditional %171 %173 %174 369fd4e5da5Sopenharmony_ci %173 = OpLabel 370fd4e5da5Sopenharmony_ci %177 = OpFOrdGreaterThan %8 %105 %108 371fd4e5da5Sopenharmony_ci OpBranch %172 372fd4e5da5Sopenharmony_ci %174 = OpLabel 373fd4e5da5Sopenharmony_ci %180 = OpFOrdLessThan %8 %105 %108 374fd4e5da5Sopenharmony_ci OpBranch %172 375fd4e5da5Sopenharmony_ci %172 = OpLabel 376fd4e5da5Sopenharmony_ci %186 = OpPhi %8 %177 %173 %180 %174 377fd4e5da5Sopenharmony_ci OpSelectionMerge %112 None 378fd4e5da5Sopenharmony_ci OpBranchConditional %186 %111 %112 379fd4e5da5Sopenharmony_ci %111 = OpLabel 380fd4e5da5Sopenharmony_ci %116 = OpLoad %6 %104 381fd4e5da5Sopenharmony_ci %120 = OpLoad %6 %107 382fd4e5da5Sopenharmony_ci OpStore %104 %120 383fd4e5da5Sopenharmony_ci OpStore %107 %116 384fd4e5da5Sopenharmony_ci OpBranch %112 385fd4e5da5Sopenharmony_ci %112 = OpLabel 386fd4e5da5Sopenharmony_ci OpBranch %89 387fd4e5da5Sopenharmony_ci %89 = OpLabel 388fd4e5da5Sopenharmony_ci %126 = OpIAdd %26 %184 %74 389fd4e5da5Sopenharmony_ci OpBranch %86 390fd4e5da5Sopenharmony_ci %1000 = OpLabel 391fd4e5da5Sopenharmony_ci OpBranch %88 392fd4e5da5Sopenharmony_ci %88 = OpLabel 393fd4e5da5Sopenharmony_ci %128 = OpIAdd %26 %183 %74 394fd4e5da5Sopenharmony_ci OpBranch %77 395fd4e5da5Sopenharmony_ci %79 = OpLabel 396fd4e5da5Sopenharmony_ci %130 = OpAccessChain %19 %16 %129 397fd4e5da5Sopenharmony_ci %131 = OpLoad %6 %130 398fd4e5da5Sopenharmony_ci %132 = OpAccessChain %28 %25 %27 %129 399fd4e5da5Sopenharmony_ci %133 = OpLoad %6 %132 400fd4e5da5Sopenharmony_ci %134 = OpFMul %6 %133 %194 401fd4e5da5Sopenharmony_ci %135 = OpFOrdLessThan %8 %131 %134 402fd4e5da5Sopenharmony_ci OpSelectionMerge %137 None 403fd4e5da5Sopenharmony_ci OpBranchConditional %135 %136 %153 404fd4e5da5Sopenharmony_ci %136 = OpLabel 405fd4e5da5Sopenharmony_ci %140 = OpAccessChain %7 %61 %27 406fd4e5da5Sopenharmony_ci %141 = OpLoad %6 %140 407fd4e5da5Sopenharmony_ci %143 = OpFMul %6 %141 %195 408fd4e5da5Sopenharmony_ci %145 = OpAccessChain %7 %61 %144 409fd4e5da5Sopenharmony_ci %146 = OpLoad %6 %145 410fd4e5da5Sopenharmony_ci %147 = OpFMul %6 %146 %195 411fd4e5da5Sopenharmony_ci %148 = OpAccessChain %7 %61 %83 412fd4e5da5Sopenharmony_ci %149 = OpLoad %6 %148 413fd4e5da5Sopenharmony_ci %150 = OpFMul %6 %149 %195 414fd4e5da5Sopenharmony_ci %152 = OpCompositeConstruct %14 %143 %147 %150 %151 415fd4e5da5Sopenharmony_ci OpStore %139 %152 416fd4e5da5Sopenharmony_ci OpBranch %137 417fd4e5da5Sopenharmony_ci %153 = OpLabel 418fd4e5da5Sopenharmony_ci %154 = OpAccessChain %7 %61 %144 419fd4e5da5Sopenharmony_ci %155 = OpLoad %6 %154 420fd4e5da5Sopenharmony_ci %156 = OpFMul %6 %155 %195 421fd4e5da5Sopenharmony_ci %157 = OpAccessChain %7 %61 %83 422fd4e5da5Sopenharmony_ci %158 = OpLoad %6 %157 423fd4e5da5Sopenharmony_ci %159 = OpFMul %6 %158 %195 424fd4e5da5Sopenharmony_ci %160 = OpAccessChain %7 %61 %27 425fd4e5da5Sopenharmony_ci %161 = OpLoad %6 %160 426fd4e5da5Sopenharmony_ci %162 = OpFMul %6 %161 %195 427fd4e5da5Sopenharmony_ci %163 = OpCompositeConstruct %14 %156 %159 %162 %151 428fd4e5da5Sopenharmony_ci OpStore %139 %163 429fd4e5da5Sopenharmony_ci OpBranch %137 430fd4e5da5Sopenharmony_ci %137 = OpLabel 431fd4e5da5Sopenharmony_ci OpReturn 432fd4e5da5Sopenharmony_ci OpFunctionEnd 433fd4e5da5Sopenharmony_ci )"; 434fd4e5da5Sopenharmony_ci 435fd4e5da5Sopenharmony_ci// The following SPIR-V came from this GLSL, which was then optimized using 436fd4e5da5Sopenharmony_ci// spirv-opt with the -O argument: 437fd4e5da5Sopenharmony_ci// 438fd4e5da5Sopenharmony_ci// #version 310 es 439fd4e5da5Sopenharmony_ci// 440fd4e5da5Sopenharmony_ci// precision highp float; 441fd4e5da5Sopenharmony_ci// 442fd4e5da5Sopenharmony_ci// layout(location = 0) out vec4 _GLF_color; 443fd4e5da5Sopenharmony_ci// 444fd4e5da5Sopenharmony_ci// layout(set = 0, binding = 0) uniform buf0 { 445fd4e5da5Sopenharmony_ci// vec2 resolution; 446fd4e5da5Sopenharmony_ci// }; 447fd4e5da5Sopenharmony_ci// void main(void) 448fd4e5da5Sopenharmony_ci// { 449fd4e5da5Sopenharmony_ci// float A[50]; 450fd4e5da5Sopenharmony_ci// for( 451fd4e5da5Sopenharmony_ci// int i = 0; 452fd4e5da5Sopenharmony_ci// i < 200; 453fd4e5da5Sopenharmony_ci// i ++ 454fd4e5da5Sopenharmony_ci// ) 455fd4e5da5Sopenharmony_ci// { 456fd4e5da5Sopenharmony_ci// if(i >= int(resolution.x)) 457fd4e5da5Sopenharmony_ci// { 458fd4e5da5Sopenharmony_ci// break; 459fd4e5da5Sopenharmony_ci// } 460fd4e5da5Sopenharmony_ci// if((4 * (i / 4)) == i) 461fd4e5da5Sopenharmony_ci// { 462fd4e5da5Sopenharmony_ci// A[i / 4] = float(i); 463fd4e5da5Sopenharmony_ci// } 464fd4e5da5Sopenharmony_ci// } 465fd4e5da5Sopenharmony_ci// for( 466fd4e5da5Sopenharmony_ci// int i = 0; 467fd4e5da5Sopenharmony_ci// i < 50; 468fd4e5da5Sopenharmony_ci// i ++ 469fd4e5da5Sopenharmony_ci// ) 470fd4e5da5Sopenharmony_ci// { 471fd4e5da5Sopenharmony_ci// if(i < int(gl_FragCoord.x)) 472fd4e5da5Sopenharmony_ci// { 473fd4e5da5Sopenharmony_ci// break; 474fd4e5da5Sopenharmony_ci// } 475fd4e5da5Sopenharmony_ci// if(i > 0) 476fd4e5da5Sopenharmony_ci// { 477fd4e5da5Sopenharmony_ci// A[i] += A[i - 1]; 478fd4e5da5Sopenharmony_ci// } 479fd4e5da5Sopenharmony_ci// } 480fd4e5da5Sopenharmony_ci// if(int(gl_FragCoord.x) < 20) 481fd4e5da5Sopenharmony_ci// { 482fd4e5da5Sopenharmony_ci// _GLF_color = vec4(A[0] / resolution.x, A[4] / resolution.y, 1.0, 1.0); 483fd4e5da5Sopenharmony_ci// } 484fd4e5da5Sopenharmony_ci// else 485fd4e5da5Sopenharmony_ci// if(int(gl_FragCoord.x) < 40) 486fd4e5da5Sopenharmony_ci// { 487fd4e5da5Sopenharmony_ci// _GLF_color = vec4(A[5] / resolution.x, A[9] / resolution.y, 1.0, 1.0); 488fd4e5da5Sopenharmony_ci// } 489fd4e5da5Sopenharmony_ci// else 490fd4e5da5Sopenharmony_ci// if(int(gl_FragCoord.x) < 60) 491fd4e5da5Sopenharmony_ci// { 492fd4e5da5Sopenharmony_ci// _GLF_color = vec4(A[10] / resolution.x, A[14] / resolution.y, 493fd4e5da5Sopenharmony_ci// 1.0, 1.0); 494fd4e5da5Sopenharmony_ci// } 495fd4e5da5Sopenharmony_ci// else 496fd4e5da5Sopenharmony_ci// if(int(gl_FragCoord.x) < 80) 497fd4e5da5Sopenharmony_ci// { 498fd4e5da5Sopenharmony_ci// _GLF_color = vec4(A[15] / resolution.x, A[19] / resolution.y, 499fd4e5da5Sopenharmony_ci// 1.0, 1.0); 500fd4e5da5Sopenharmony_ci// } 501fd4e5da5Sopenharmony_ci// else 502fd4e5da5Sopenharmony_ci// if(int(gl_FragCoord.x) < 100) 503fd4e5da5Sopenharmony_ci// { 504fd4e5da5Sopenharmony_ci// _GLF_color = vec4(A[20] / resolution.x, A[24] / resolution.y, 505fd4e5da5Sopenharmony_ci// 1.0, 1.0); 506fd4e5da5Sopenharmony_ci// } 507fd4e5da5Sopenharmony_ci// else 508fd4e5da5Sopenharmony_ci// if(int(gl_FragCoord.x) < 120) 509fd4e5da5Sopenharmony_ci// { 510fd4e5da5Sopenharmony_ci// _GLF_color = vec4(A[25] / resolution.x, A[29] / resolution.y, 511fd4e5da5Sopenharmony_ci// 1.0, 1.0); 512fd4e5da5Sopenharmony_ci// } 513fd4e5da5Sopenharmony_ci// else 514fd4e5da5Sopenharmony_ci// if(int(gl_FragCoord.x) < 140) 515fd4e5da5Sopenharmony_ci// { 516fd4e5da5Sopenharmony_ci// _GLF_color = vec4(A[30] / resolution.x, A[34] / resolution.y, 517fd4e5da5Sopenharmony_ci// 1.0, 1.0); 518fd4e5da5Sopenharmony_ci// } 519fd4e5da5Sopenharmony_ci// else 520fd4e5da5Sopenharmony_ci// if(int(gl_FragCoord.x) < 160) 521fd4e5da5Sopenharmony_ci// { 522fd4e5da5Sopenharmony_ci// _GLF_color = vec4(A[35] / resolution.x, A[39] / 523fd4e5da5Sopenharmony_ci// resolution.y, 1.0, 1.0); 524fd4e5da5Sopenharmony_ci// } 525fd4e5da5Sopenharmony_ci// else 526fd4e5da5Sopenharmony_ci// if(int(gl_FragCoord.x) < 180) 527fd4e5da5Sopenharmony_ci// { 528fd4e5da5Sopenharmony_ci// _GLF_color = vec4(A[40] / resolution.x, A[44] / 529fd4e5da5Sopenharmony_ci// resolution.y, 1.0, 1.0); 530fd4e5da5Sopenharmony_ci// } 531fd4e5da5Sopenharmony_ci// else 532fd4e5da5Sopenharmony_ci// if(int(gl_FragCoord.x) < 180) 533fd4e5da5Sopenharmony_ci// { 534fd4e5da5Sopenharmony_ci// _GLF_color = vec4(A[45] / resolution.x, A[49] / 535fd4e5da5Sopenharmony_ci// resolution.y, 1.0, 1.0); 536fd4e5da5Sopenharmony_ci// } 537fd4e5da5Sopenharmony_ci// else 538fd4e5da5Sopenharmony_ci// { 539fd4e5da5Sopenharmony_ci// discard; 540fd4e5da5Sopenharmony_ci// } 541fd4e5da5Sopenharmony_ci// } 542fd4e5da5Sopenharmony_ci 543fd4e5da5Sopenharmony_ciconst std::string kTestShader3 = R"( 544fd4e5da5Sopenharmony_ci OpCapability Shader 545fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 546fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 547fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" %68 %100 %24 548fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 549fd4e5da5Sopenharmony_ci OpSource ESSL 310 550fd4e5da5Sopenharmony_ci OpName %4 "main" 551fd4e5da5Sopenharmony_ci OpName %22 "buf0" 552fd4e5da5Sopenharmony_ci OpMemberName %22 0 "resolution" 553fd4e5da5Sopenharmony_ci OpName %24 "" 554fd4e5da5Sopenharmony_ci OpName %46 "A" 555fd4e5da5Sopenharmony_ci OpName %68 "gl_FragCoord" 556fd4e5da5Sopenharmony_ci OpName %100 "_GLF_color" 557fd4e5da5Sopenharmony_ci OpMemberDecorate %22 0 Offset 0 558fd4e5da5Sopenharmony_ci OpDecorate %22 Block 559fd4e5da5Sopenharmony_ci OpDecorate %24 DescriptorSet 0 560fd4e5da5Sopenharmony_ci OpDecorate %24 Binding 0 561fd4e5da5Sopenharmony_ci OpDecorate %37 RelaxedPrecision 562fd4e5da5Sopenharmony_ci OpDecorate %38 RelaxedPrecision 563fd4e5da5Sopenharmony_ci OpDecorate %55 RelaxedPrecision 564fd4e5da5Sopenharmony_ci OpDecorate %68 BuiltIn FragCoord 565fd4e5da5Sopenharmony_ci OpDecorate %83 RelaxedPrecision 566fd4e5da5Sopenharmony_ci OpDecorate %91 RelaxedPrecision 567fd4e5da5Sopenharmony_ci OpDecorate %100 Location 0 568fd4e5da5Sopenharmony_ci OpDecorate %302 RelaxedPrecision 569fd4e5da5Sopenharmony_ci OpDecorate %304 RelaxedPrecision 570fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 571fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 572fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 573fd4e5da5Sopenharmony_ci %9 = OpConstant %6 0 574fd4e5da5Sopenharmony_ci %16 = OpConstant %6 200 575fd4e5da5Sopenharmony_ci %17 = OpTypeBool 576fd4e5da5Sopenharmony_ci %20 = OpTypeFloat 32 577fd4e5da5Sopenharmony_ci %21 = OpTypeVector %20 2 578fd4e5da5Sopenharmony_ci %22 = OpTypeStruct %21 579fd4e5da5Sopenharmony_ci %23 = OpTypePointer Uniform %22 580fd4e5da5Sopenharmony_ci %24 = OpVariable %23 Uniform 581fd4e5da5Sopenharmony_ci %25 = OpTypeInt 32 0 582fd4e5da5Sopenharmony_ci %26 = OpConstant %25 0 583fd4e5da5Sopenharmony_ci %27 = OpTypePointer Uniform %20 584fd4e5da5Sopenharmony_ci %35 = OpConstant %6 4 585fd4e5da5Sopenharmony_ci %43 = OpConstant %25 50 586fd4e5da5Sopenharmony_ci %44 = OpTypeArray %20 %43 587fd4e5da5Sopenharmony_ci %45 = OpTypePointer Function %44 588fd4e5da5Sopenharmony_ci %51 = OpTypePointer Function %20 589fd4e5da5Sopenharmony_ci %54 = OpConstant %6 1 590fd4e5da5Sopenharmony_ci %63 = OpConstant %6 50 591fd4e5da5Sopenharmony_ci %66 = OpTypeVector %20 4 592fd4e5da5Sopenharmony_ci %67 = OpTypePointer Input %66 593fd4e5da5Sopenharmony_ci %68 = OpVariable %67 Input 594fd4e5da5Sopenharmony_ci %69 = OpTypePointer Input %20 595fd4e5da5Sopenharmony_ci %95 = OpConstant %6 20 596fd4e5da5Sopenharmony_ci %99 = OpTypePointer Output %66 597fd4e5da5Sopenharmony_ci %100 = OpVariable %99 Output 598fd4e5da5Sopenharmony_ci %108 = OpConstant %25 1 599fd4e5da5Sopenharmony_ci %112 = OpConstant %20 1 600fd4e5da5Sopenharmony_ci %118 = OpConstant %6 40 601fd4e5da5Sopenharmony_ci %122 = OpConstant %6 5 602fd4e5da5Sopenharmony_ci %128 = OpConstant %6 9 603fd4e5da5Sopenharmony_ci %139 = OpConstant %6 60 604fd4e5da5Sopenharmony_ci %143 = OpConstant %6 10 605fd4e5da5Sopenharmony_ci %149 = OpConstant %6 14 606fd4e5da5Sopenharmony_ci %160 = OpConstant %6 80 607fd4e5da5Sopenharmony_ci %164 = OpConstant %6 15 608fd4e5da5Sopenharmony_ci %170 = OpConstant %6 19 609fd4e5da5Sopenharmony_ci %181 = OpConstant %6 100 610fd4e5da5Sopenharmony_ci %190 = OpConstant %6 24 611fd4e5da5Sopenharmony_ci %201 = OpConstant %6 120 612fd4e5da5Sopenharmony_ci %205 = OpConstant %6 25 613fd4e5da5Sopenharmony_ci %211 = OpConstant %6 29 614fd4e5da5Sopenharmony_ci %222 = OpConstant %6 140 615fd4e5da5Sopenharmony_ci %226 = OpConstant %6 30 616fd4e5da5Sopenharmony_ci %232 = OpConstant %6 34 617fd4e5da5Sopenharmony_ci %243 = OpConstant %6 160 618fd4e5da5Sopenharmony_ci %247 = OpConstant %6 35 619fd4e5da5Sopenharmony_ci %253 = OpConstant %6 39 620fd4e5da5Sopenharmony_ci %264 = OpConstant %6 180 621fd4e5da5Sopenharmony_ci %273 = OpConstant %6 44 622fd4e5da5Sopenharmony_ci %287 = OpConstant %6 45 623fd4e5da5Sopenharmony_ci %293 = OpConstant %6 49 624fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 625fd4e5da5Sopenharmony_ci %5 = OpLabel 626fd4e5da5Sopenharmony_ci %46 = OpVariable %45 Function 627fd4e5da5Sopenharmony_ci OpBranch %10 628fd4e5da5Sopenharmony_ci %10 = OpLabel 629fd4e5da5Sopenharmony_ci %302 = OpPhi %6 %9 %5 %55 %42 630fd4e5da5Sopenharmony_ci %18 = OpSLessThan %17 %302 %16 631fd4e5da5Sopenharmony_ci OpLoopMerge %12 %42 None 632fd4e5da5Sopenharmony_ci OpBranchConditional %18 %11 %12 633fd4e5da5Sopenharmony_ci %11 = OpLabel 634fd4e5da5Sopenharmony_ci %28 = OpAccessChain %27 %24 %9 %26 635fd4e5da5Sopenharmony_ci %29 = OpLoad %20 %28 636fd4e5da5Sopenharmony_ci %30 = OpConvertFToS %6 %29 637fd4e5da5Sopenharmony_ci %31 = OpSGreaterThanEqual %17 %302 %30 638fd4e5da5Sopenharmony_ci OpSelectionMerge %33 None 639fd4e5da5Sopenharmony_ci OpBranchConditional %31 %32 %33 640fd4e5da5Sopenharmony_ci %32 = OpLabel 641fd4e5da5Sopenharmony_ci OpBranch %12 642fd4e5da5Sopenharmony_ci %33 = OpLabel 643fd4e5da5Sopenharmony_ci %37 = OpSDiv %6 %302 %35 644fd4e5da5Sopenharmony_ci %38 = OpIMul %6 %35 %37 645fd4e5da5Sopenharmony_ci %40 = OpIEqual %17 %38 %302 646fd4e5da5Sopenharmony_ci OpBranchConditional %40 %41 %42 647fd4e5da5Sopenharmony_ci %41 = OpLabel 648fd4e5da5Sopenharmony_ci %50 = OpConvertSToF %20 %302 649fd4e5da5Sopenharmony_ci %52 = OpAccessChain %51 %46 %37 650fd4e5da5Sopenharmony_ci OpStore %52 %50 651fd4e5da5Sopenharmony_ci OpBranch %42 652fd4e5da5Sopenharmony_ci %42 = OpLabel 653fd4e5da5Sopenharmony_ci %55 = OpIAdd %6 %302 %54 654fd4e5da5Sopenharmony_ci OpBranch %10 655fd4e5da5Sopenharmony_ci %12 = OpLabel 656fd4e5da5Sopenharmony_ci OpBranch %57 657fd4e5da5Sopenharmony_ci %57 = OpLabel 658fd4e5da5Sopenharmony_ci %304 = OpPhi %6 %9 %12 %91 %80 659fd4e5da5Sopenharmony_ci %64 = OpSLessThan %17 %304 %63 660fd4e5da5Sopenharmony_ci OpLoopMerge %59 %80 None 661fd4e5da5Sopenharmony_ci OpBranchConditional %64 %58 %59 662fd4e5da5Sopenharmony_ci %58 = OpLabel 663fd4e5da5Sopenharmony_ci %70 = OpAccessChain %69 %68 %26 664fd4e5da5Sopenharmony_ci %71 = OpLoad %20 %70 665fd4e5da5Sopenharmony_ci %72 = OpConvertFToS %6 %71 666fd4e5da5Sopenharmony_ci %73 = OpSLessThan %17 %304 %72 667fd4e5da5Sopenharmony_ci OpSelectionMerge %75 None 668fd4e5da5Sopenharmony_ci OpBranchConditional %73 %74 %75 669fd4e5da5Sopenharmony_ci %74 = OpLabel 670fd4e5da5Sopenharmony_ci OpBranch %59 671fd4e5da5Sopenharmony_ci %75 = OpLabel 672fd4e5da5Sopenharmony_ci %78 = OpSGreaterThan %17 %304 %9 673fd4e5da5Sopenharmony_ci OpBranchConditional %78 %79 %80 674fd4e5da5Sopenharmony_ci %79 = OpLabel 675fd4e5da5Sopenharmony_ci %83 = OpISub %6 %304 %54 676fd4e5da5Sopenharmony_ci %84 = OpAccessChain %51 %46 %83 677fd4e5da5Sopenharmony_ci %85 = OpLoad %20 %84 678fd4e5da5Sopenharmony_ci %86 = OpAccessChain %51 %46 %304 679fd4e5da5Sopenharmony_ci %87 = OpLoad %20 %86 680fd4e5da5Sopenharmony_ci %88 = OpFAdd %20 %87 %85 681fd4e5da5Sopenharmony_ci OpStore %86 %88 682fd4e5da5Sopenharmony_ci OpBranch %80 683fd4e5da5Sopenharmony_ci %80 = OpLabel 684fd4e5da5Sopenharmony_ci %91 = OpIAdd %6 %304 %54 685fd4e5da5Sopenharmony_ci OpBranch %57 686fd4e5da5Sopenharmony_ci %59 = OpLabel 687fd4e5da5Sopenharmony_ci %92 = OpAccessChain %69 %68 %26 688fd4e5da5Sopenharmony_ci %93 = OpLoad %20 %92 689fd4e5da5Sopenharmony_ci %94 = OpConvertFToS %6 %93 690fd4e5da5Sopenharmony_ci %96 = OpSLessThan %17 %94 %95 691fd4e5da5Sopenharmony_ci OpSelectionMerge %98 None 692fd4e5da5Sopenharmony_ci OpBranchConditional %96 %97 %114 693fd4e5da5Sopenharmony_ci %97 = OpLabel 694fd4e5da5Sopenharmony_ci %101 = OpAccessChain %51 %46 %9 695fd4e5da5Sopenharmony_ci %102 = OpLoad %20 %101 696fd4e5da5Sopenharmony_ci %103 = OpAccessChain %27 %24 %9 %26 697fd4e5da5Sopenharmony_ci %104 = OpLoad %20 %103 698fd4e5da5Sopenharmony_ci %105 = OpFDiv %20 %102 %104 699fd4e5da5Sopenharmony_ci %106 = OpAccessChain %51 %46 %35 700fd4e5da5Sopenharmony_ci %107 = OpLoad %20 %106 701fd4e5da5Sopenharmony_ci %109 = OpAccessChain %27 %24 %9 %108 702fd4e5da5Sopenharmony_ci %110 = OpLoad %20 %109 703fd4e5da5Sopenharmony_ci %111 = OpFDiv %20 %107 %110 704fd4e5da5Sopenharmony_ci %113 = OpCompositeConstruct %66 %105 %111 %112 %112 705fd4e5da5Sopenharmony_ci OpStore %100 %113 706fd4e5da5Sopenharmony_ci OpBranch %98 707fd4e5da5Sopenharmony_ci %114 = OpLabel 708fd4e5da5Sopenharmony_ci %119 = OpSLessThan %17 %94 %118 709fd4e5da5Sopenharmony_ci OpSelectionMerge %121 None 710fd4e5da5Sopenharmony_ci OpBranchConditional %119 %120 %135 711fd4e5da5Sopenharmony_ci %120 = OpLabel 712fd4e5da5Sopenharmony_ci %123 = OpAccessChain %51 %46 %122 713fd4e5da5Sopenharmony_ci %124 = OpLoad %20 %123 714fd4e5da5Sopenharmony_ci %125 = OpAccessChain %27 %24 %9 %26 715fd4e5da5Sopenharmony_ci %126 = OpLoad %20 %125 716fd4e5da5Sopenharmony_ci %127 = OpFDiv %20 %124 %126 717fd4e5da5Sopenharmony_ci %129 = OpAccessChain %51 %46 %128 718fd4e5da5Sopenharmony_ci %130 = OpLoad %20 %129 719fd4e5da5Sopenharmony_ci %131 = OpAccessChain %27 %24 %9 %108 720fd4e5da5Sopenharmony_ci %132 = OpLoad %20 %131 721fd4e5da5Sopenharmony_ci %133 = OpFDiv %20 %130 %132 722fd4e5da5Sopenharmony_ci %134 = OpCompositeConstruct %66 %127 %133 %112 %112 723fd4e5da5Sopenharmony_ci OpStore %100 %134 724fd4e5da5Sopenharmony_ci OpBranch %121 725fd4e5da5Sopenharmony_ci %135 = OpLabel 726fd4e5da5Sopenharmony_ci %140 = OpSLessThan %17 %94 %139 727fd4e5da5Sopenharmony_ci OpSelectionMerge %142 None 728fd4e5da5Sopenharmony_ci OpBranchConditional %140 %141 %156 729fd4e5da5Sopenharmony_ci %141 = OpLabel 730fd4e5da5Sopenharmony_ci %144 = OpAccessChain %51 %46 %143 731fd4e5da5Sopenharmony_ci %145 = OpLoad %20 %144 732fd4e5da5Sopenharmony_ci %146 = OpAccessChain %27 %24 %9 %26 733fd4e5da5Sopenharmony_ci %147 = OpLoad %20 %146 734fd4e5da5Sopenharmony_ci %148 = OpFDiv %20 %145 %147 735fd4e5da5Sopenharmony_ci %150 = OpAccessChain %51 %46 %149 736fd4e5da5Sopenharmony_ci %151 = OpLoad %20 %150 737fd4e5da5Sopenharmony_ci %152 = OpAccessChain %27 %24 %9 %108 738fd4e5da5Sopenharmony_ci %153 = OpLoad %20 %152 739fd4e5da5Sopenharmony_ci %154 = OpFDiv %20 %151 %153 740fd4e5da5Sopenharmony_ci %155 = OpCompositeConstruct %66 %148 %154 %112 %112 741fd4e5da5Sopenharmony_ci OpStore %100 %155 742fd4e5da5Sopenharmony_ci OpBranch %142 743fd4e5da5Sopenharmony_ci %156 = OpLabel 744fd4e5da5Sopenharmony_ci %161 = OpSLessThan %17 %94 %160 745fd4e5da5Sopenharmony_ci OpSelectionMerge %163 None 746fd4e5da5Sopenharmony_ci OpBranchConditional %161 %162 %177 747fd4e5da5Sopenharmony_ci %162 = OpLabel 748fd4e5da5Sopenharmony_ci %165 = OpAccessChain %51 %46 %164 749fd4e5da5Sopenharmony_ci %166 = OpLoad %20 %165 750fd4e5da5Sopenharmony_ci %167 = OpAccessChain %27 %24 %9 %26 751fd4e5da5Sopenharmony_ci %168 = OpLoad %20 %167 752fd4e5da5Sopenharmony_ci %169 = OpFDiv %20 %166 %168 753fd4e5da5Sopenharmony_ci %171 = OpAccessChain %51 %46 %170 754fd4e5da5Sopenharmony_ci %172 = OpLoad %20 %171 755fd4e5da5Sopenharmony_ci %173 = OpAccessChain %27 %24 %9 %108 756fd4e5da5Sopenharmony_ci %174 = OpLoad %20 %173 757fd4e5da5Sopenharmony_ci %175 = OpFDiv %20 %172 %174 758fd4e5da5Sopenharmony_ci %176 = OpCompositeConstruct %66 %169 %175 %112 %112 759fd4e5da5Sopenharmony_ci OpStore %100 %176 760fd4e5da5Sopenharmony_ci OpBranch %163 761fd4e5da5Sopenharmony_ci %177 = OpLabel 762fd4e5da5Sopenharmony_ci %182 = OpSLessThan %17 %94 %181 763fd4e5da5Sopenharmony_ci OpSelectionMerge %184 None 764fd4e5da5Sopenharmony_ci OpBranchConditional %182 %183 %197 765fd4e5da5Sopenharmony_ci %183 = OpLabel 766fd4e5da5Sopenharmony_ci %185 = OpAccessChain %51 %46 %95 767fd4e5da5Sopenharmony_ci %186 = OpLoad %20 %185 768fd4e5da5Sopenharmony_ci %187 = OpAccessChain %27 %24 %9 %26 769fd4e5da5Sopenharmony_ci %188 = OpLoad %20 %187 770fd4e5da5Sopenharmony_ci %189 = OpFDiv %20 %186 %188 771fd4e5da5Sopenharmony_ci %191 = OpAccessChain %51 %46 %190 772fd4e5da5Sopenharmony_ci %192 = OpLoad %20 %191 773fd4e5da5Sopenharmony_ci %193 = OpAccessChain %27 %24 %9 %108 774fd4e5da5Sopenharmony_ci %194 = OpLoad %20 %193 775fd4e5da5Sopenharmony_ci %195 = OpFDiv %20 %192 %194 776fd4e5da5Sopenharmony_ci %196 = OpCompositeConstruct %66 %189 %195 %112 %112 777fd4e5da5Sopenharmony_ci OpStore %100 %196 778fd4e5da5Sopenharmony_ci OpBranch %184 779fd4e5da5Sopenharmony_ci %197 = OpLabel 780fd4e5da5Sopenharmony_ci %202 = OpSLessThan %17 %94 %201 781fd4e5da5Sopenharmony_ci OpSelectionMerge %204 None 782fd4e5da5Sopenharmony_ci OpBranchConditional %202 %203 %218 783fd4e5da5Sopenharmony_ci %203 = OpLabel 784fd4e5da5Sopenharmony_ci %206 = OpAccessChain %51 %46 %205 785fd4e5da5Sopenharmony_ci %207 = OpLoad %20 %206 786fd4e5da5Sopenharmony_ci %208 = OpAccessChain %27 %24 %9 %26 787fd4e5da5Sopenharmony_ci %209 = OpLoad %20 %208 788fd4e5da5Sopenharmony_ci %210 = OpFDiv %20 %207 %209 789fd4e5da5Sopenharmony_ci %212 = OpAccessChain %51 %46 %211 790fd4e5da5Sopenharmony_ci %213 = OpLoad %20 %212 791fd4e5da5Sopenharmony_ci %214 = OpAccessChain %27 %24 %9 %108 792fd4e5da5Sopenharmony_ci %215 = OpLoad %20 %214 793fd4e5da5Sopenharmony_ci %216 = OpFDiv %20 %213 %215 794fd4e5da5Sopenharmony_ci %217 = OpCompositeConstruct %66 %210 %216 %112 %112 795fd4e5da5Sopenharmony_ci OpStore %100 %217 796fd4e5da5Sopenharmony_ci OpBranch %204 797fd4e5da5Sopenharmony_ci %218 = OpLabel 798fd4e5da5Sopenharmony_ci %223 = OpSLessThan %17 %94 %222 799fd4e5da5Sopenharmony_ci OpSelectionMerge %225 None 800fd4e5da5Sopenharmony_ci OpBranchConditional %223 %224 %239 801fd4e5da5Sopenharmony_ci %224 = OpLabel 802fd4e5da5Sopenharmony_ci %227 = OpAccessChain %51 %46 %226 803fd4e5da5Sopenharmony_ci %228 = OpLoad %20 %227 804fd4e5da5Sopenharmony_ci %229 = OpAccessChain %27 %24 %9 %26 805fd4e5da5Sopenharmony_ci %230 = OpLoad %20 %229 806fd4e5da5Sopenharmony_ci %231 = OpFDiv %20 %228 %230 807fd4e5da5Sopenharmony_ci %233 = OpAccessChain %51 %46 %232 808fd4e5da5Sopenharmony_ci %234 = OpLoad %20 %233 809fd4e5da5Sopenharmony_ci %235 = OpAccessChain %27 %24 %9 %108 810fd4e5da5Sopenharmony_ci %236 = OpLoad %20 %235 811fd4e5da5Sopenharmony_ci %237 = OpFDiv %20 %234 %236 812fd4e5da5Sopenharmony_ci %238 = OpCompositeConstruct %66 %231 %237 %112 %112 813fd4e5da5Sopenharmony_ci OpStore %100 %238 814fd4e5da5Sopenharmony_ci OpBranch %225 815fd4e5da5Sopenharmony_ci %239 = OpLabel 816fd4e5da5Sopenharmony_ci %244 = OpSLessThan %17 %94 %243 817fd4e5da5Sopenharmony_ci OpSelectionMerge %246 None 818fd4e5da5Sopenharmony_ci OpBranchConditional %244 %245 %260 819fd4e5da5Sopenharmony_ci %245 = OpLabel 820fd4e5da5Sopenharmony_ci %248 = OpAccessChain %51 %46 %247 821fd4e5da5Sopenharmony_ci %249 = OpLoad %20 %248 822fd4e5da5Sopenharmony_ci %250 = OpAccessChain %27 %24 %9 %26 823fd4e5da5Sopenharmony_ci %251 = OpLoad %20 %250 824fd4e5da5Sopenharmony_ci %252 = OpFDiv %20 %249 %251 825fd4e5da5Sopenharmony_ci %254 = OpAccessChain %51 %46 %253 826fd4e5da5Sopenharmony_ci %255 = OpLoad %20 %254 827fd4e5da5Sopenharmony_ci %256 = OpAccessChain %27 %24 %9 %108 828fd4e5da5Sopenharmony_ci %257 = OpLoad %20 %256 829fd4e5da5Sopenharmony_ci %258 = OpFDiv %20 %255 %257 830fd4e5da5Sopenharmony_ci %259 = OpCompositeConstruct %66 %252 %258 %112 %112 831fd4e5da5Sopenharmony_ci OpStore %100 %259 832fd4e5da5Sopenharmony_ci OpBranch %246 833fd4e5da5Sopenharmony_ci %260 = OpLabel 834fd4e5da5Sopenharmony_ci %265 = OpSLessThan %17 %94 %264 835fd4e5da5Sopenharmony_ci OpSelectionMerge %267 None 836fd4e5da5Sopenharmony_ci OpBranchConditional %265 %266 %280 837fd4e5da5Sopenharmony_ci %266 = OpLabel 838fd4e5da5Sopenharmony_ci %268 = OpAccessChain %51 %46 %118 839fd4e5da5Sopenharmony_ci %269 = OpLoad %20 %268 840fd4e5da5Sopenharmony_ci %270 = OpAccessChain %27 %24 %9 %26 841fd4e5da5Sopenharmony_ci %271 = OpLoad %20 %270 842fd4e5da5Sopenharmony_ci %272 = OpFDiv %20 %269 %271 843fd4e5da5Sopenharmony_ci %274 = OpAccessChain %51 %46 %273 844fd4e5da5Sopenharmony_ci %275 = OpLoad %20 %274 845fd4e5da5Sopenharmony_ci %276 = OpAccessChain %27 %24 %9 %108 846fd4e5da5Sopenharmony_ci %277 = OpLoad %20 %276 847fd4e5da5Sopenharmony_ci %278 = OpFDiv %20 %275 %277 848fd4e5da5Sopenharmony_ci %279 = OpCompositeConstruct %66 %272 %278 %112 %112 849fd4e5da5Sopenharmony_ci OpStore %100 %279 850fd4e5da5Sopenharmony_ci OpBranch %267 851fd4e5da5Sopenharmony_ci %280 = OpLabel 852fd4e5da5Sopenharmony_ci OpSelectionMerge %285 None 853fd4e5da5Sopenharmony_ci OpBranchConditional %265 %285 %300 854fd4e5da5Sopenharmony_ci %285 = OpLabel 855fd4e5da5Sopenharmony_ci %288 = OpAccessChain %51 %46 %287 856fd4e5da5Sopenharmony_ci %289 = OpLoad %20 %288 857fd4e5da5Sopenharmony_ci %290 = OpAccessChain %27 %24 %9 %26 858fd4e5da5Sopenharmony_ci %291 = OpLoad %20 %290 859fd4e5da5Sopenharmony_ci %292 = OpFDiv %20 %289 %291 860fd4e5da5Sopenharmony_ci %294 = OpAccessChain %51 %46 %293 861fd4e5da5Sopenharmony_ci %295 = OpLoad %20 %294 862fd4e5da5Sopenharmony_ci %296 = OpAccessChain %27 %24 %9 %108 863fd4e5da5Sopenharmony_ci %297 = OpLoad %20 %296 864fd4e5da5Sopenharmony_ci %298 = OpFDiv %20 %295 %297 865fd4e5da5Sopenharmony_ci %299 = OpCompositeConstruct %66 %292 %298 %112 %112 866fd4e5da5Sopenharmony_ci OpStore %100 %299 867fd4e5da5Sopenharmony_ci OpBranch %267 868fd4e5da5Sopenharmony_ci %300 = OpLabel 869fd4e5da5Sopenharmony_ci OpKill 870fd4e5da5Sopenharmony_ci %267 = OpLabel 871fd4e5da5Sopenharmony_ci OpBranch %246 872fd4e5da5Sopenharmony_ci %246 = OpLabel 873fd4e5da5Sopenharmony_ci OpBranch %225 874fd4e5da5Sopenharmony_ci %225 = OpLabel 875fd4e5da5Sopenharmony_ci OpBranch %204 876fd4e5da5Sopenharmony_ci %204 = OpLabel 877fd4e5da5Sopenharmony_ci OpBranch %184 878fd4e5da5Sopenharmony_ci %184 = OpLabel 879fd4e5da5Sopenharmony_ci OpBranch %163 880fd4e5da5Sopenharmony_ci %163 = OpLabel 881fd4e5da5Sopenharmony_ci OpBranch %142 882fd4e5da5Sopenharmony_ci %142 = OpLabel 883fd4e5da5Sopenharmony_ci OpBranch %121 884fd4e5da5Sopenharmony_ci %121 = OpLabel 885fd4e5da5Sopenharmony_ci OpBranch %98 886fd4e5da5Sopenharmony_ci %98 = OpLabel 887fd4e5da5Sopenharmony_ci OpReturn 888fd4e5da5Sopenharmony_ci OpFunctionEnd 889fd4e5da5Sopenharmony_ci )"; 890fd4e5da5Sopenharmony_ci 891fd4e5da5Sopenharmony_ci// Abstract class exposing an interestingness function as a virtual method. 892fd4e5da5Sopenharmony_ciclass InterestingnessTest { 893fd4e5da5Sopenharmony_ci public: 894fd4e5da5Sopenharmony_ci virtual ~InterestingnessTest() = default; 895fd4e5da5Sopenharmony_ci 896fd4e5da5Sopenharmony_ci // Abstract method that subclasses should implement for specific notions of 897fd4e5da5Sopenharmony_ci // interestingness. Its signature matches Shrinker::InterestingnessFunction. 898fd4e5da5Sopenharmony_ci // Argument |binary| is the SPIR-V binary to be checked; |counter| is used for 899fd4e5da5Sopenharmony_ci // debugging purposes. 900fd4e5da5Sopenharmony_ci virtual bool Interesting(const std::vector<uint32_t>& binary, 901fd4e5da5Sopenharmony_ci uint32_t counter) = 0; 902fd4e5da5Sopenharmony_ci 903fd4e5da5Sopenharmony_ci // Yields the Interesting instance method wrapped in a function object. 904fd4e5da5Sopenharmony_ci Shrinker::InterestingnessFunction AsFunction() { 905fd4e5da5Sopenharmony_ci return std::bind(&InterestingnessTest::Interesting, this, 906fd4e5da5Sopenharmony_ci std::placeholders::_1, std::placeholders::_2); 907fd4e5da5Sopenharmony_ci } 908fd4e5da5Sopenharmony_ci}; 909fd4e5da5Sopenharmony_ci 910fd4e5da5Sopenharmony_ci// A test that says all binaries are interesting. 911fd4e5da5Sopenharmony_ciclass AlwaysInteresting : public InterestingnessTest { 912fd4e5da5Sopenharmony_ci public: 913fd4e5da5Sopenharmony_ci bool Interesting(const std::vector<uint32_t>&, uint32_t) override { 914fd4e5da5Sopenharmony_ci return true; 915fd4e5da5Sopenharmony_ci } 916fd4e5da5Sopenharmony_ci}; 917fd4e5da5Sopenharmony_ci 918fd4e5da5Sopenharmony_ci// A test that says a binary is interesting first time round, and uninteresting 919fd4e5da5Sopenharmony_ci// thereafter. 920fd4e5da5Sopenharmony_ciclass OnlyInterestingFirstTime : public InterestingnessTest { 921fd4e5da5Sopenharmony_ci public: 922fd4e5da5Sopenharmony_ci explicit OnlyInterestingFirstTime() : first_time_(true) {} 923fd4e5da5Sopenharmony_ci 924fd4e5da5Sopenharmony_ci bool Interesting(const std::vector<uint32_t>&, uint32_t) override { 925fd4e5da5Sopenharmony_ci if (first_time_) { 926fd4e5da5Sopenharmony_ci first_time_ = false; 927fd4e5da5Sopenharmony_ci return true; 928fd4e5da5Sopenharmony_ci } 929fd4e5da5Sopenharmony_ci return false; 930fd4e5da5Sopenharmony_ci } 931fd4e5da5Sopenharmony_ci 932fd4e5da5Sopenharmony_ci private: 933fd4e5da5Sopenharmony_ci bool first_time_; 934fd4e5da5Sopenharmony_ci}; 935fd4e5da5Sopenharmony_ci 936fd4e5da5Sopenharmony_ci// A test that says a binary is interesting first time round, after which 937fd4e5da5Sopenharmony_ci// interestingness ping pongs between false and true. 938fd4e5da5Sopenharmony_ciclass PingPong : public InterestingnessTest { 939fd4e5da5Sopenharmony_ci public: 940fd4e5da5Sopenharmony_ci explicit PingPong() : interesting_(false) {} 941fd4e5da5Sopenharmony_ci 942fd4e5da5Sopenharmony_ci bool Interesting(const std::vector<uint32_t>&, uint32_t) override { 943fd4e5da5Sopenharmony_ci interesting_ = !interesting_; 944fd4e5da5Sopenharmony_ci return interesting_; 945fd4e5da5Sopenharmony_ci } 946fd4e5da5Sopenharmony_ci 947fd4e5da5Sopenharmony_ci private: 948fd4e5da5Sopenharmony_ci bool interesting_; 949fd4e5da5Sopenharmony_ci}; 950fd4e5da5Sopenharmony_ci 951fd4e5da5Sopenharmony_ci// A test that says a binary is interesting first time round, thereafter 952fd4e5da5Sopenharmony_ci// decides at random whether it is interesting. This allows the logic of the 953fd4e5da5Sopenharmony_ci// shrinker to be exercised quite a bit. 954fd4e5da5Sopenharmony_ciclass InterestingThenRandom : public InterestingnessTest { 955fd4e5da5Sopenharmony_ci public: 956fd4e5da5Sopenharmony_ci InterestingThenRandom(const PseudoRandomGenerator& random_generator) 957fd4e5da5Sopenharmony_ci : first_time_(true), random_generator_(random_generator) {} 958fd4e5da5Sopenharmony_ci 959fd4e5da5Sopenharmony_ci bool Interesting(const std::vector<uint32_t>&, uint32_t) override { 960fd4e5da5Sopenharmony_ci if (first_time_) { 961fd4e5da5Sopenharmony_ci first_time_ = false; 962fd4e5da5Sopenharmony_ci return true; 963fd4e5da5Sopenharmony_ci } 964fd4e5da5Sopenharmony_ci return random_generator_.RandomBool(); 965fd4e5da5Sopenharmony_ci } 966fd4e5da5Sopenharmony_ci 967fd4e5da5Sopenharmony_ci private: 968fd4e5da5Sopenharmony_ci bool first_time_; 969fd4e5da5Sopenharmony_ci PseudoRandomGenerator random_generator_; 970fd4e5da5Sopenharmony_ci}; 971fd4e5da5Sopenharmony_ci 972fd4e5da5Sopenharmony_ci// |binary_in| and |initial_facts| are a SPIR-V binary and sequence of facts to 973fd4e5da5Sopenharmony_ci// which |transformation_sequence_in| can be applied. Shrinking of 974fd4e5da5Sopenharmony_ci// |transformation_sequence_in| gets performed with respect to 975fd4e5da5Sopenharmony_ci// |interestingness_function|. If |expected_binary_out| is non-empty, it must 976fd4e5da5Sopenharmony_ci// match the binary obtained by applying the final shrunk set of 977fd4e5da5Sopenharmony_ci// transformations, in which case the number of such transformations should 978fd4e5da5Sopenharmony_ci// equal |expected_transformations_out_size|. 979fd4e5da5Sopenharmony_ci// 980fd4e5da5Sopenharmony_ci// The |step_limit| parameter restricts the number of steps that the shrinker 981fd4e5da5Sopenharmony_ci// will try; it can be set to something small for a faster (but less thorough) 982fd4e5da5Sopenharmony_ci// test. 983fd4e5da5Sopenharmony_ci// 984fd4e5da5Sopenharmony_ci// The |validator_options| parameter provides validator options that should be 985fd4e5da5Sopenharmony_ci// used during shrinking. 986fd4e5da5Sopenharmony_civoid RunAndCheckShrinker( 987fd4e5da5Sopenharmony_ci const spv_target_env& target_env, const std::vector<uint32_t>& binary_in, 988fd4e5da5Sopenharmony_ci const protobufs::FactSequence& initial_facts, 989fd4e5da5Sopenharmony_ci const protobufs::TransformationSequence& transformation_sequence_in, 990fd4e5da5Sopenharmony_ci const Shrinker::InterestingnessFunction& interestingness_function, 991fd4e5da5Sopenharmony_ci const std::vector<uint32_t>& expected_binary_out, 992fd4e5da5Sopenharmony_ci uint32_t expected_transformations_out_size, uint32_t step_limit, 993fd4e5da5Sopenharmony_ci spv_validator_options validator_options) { 994fd4e5da5Sopenharmony_ci // Run the shrinker. 995fd4e5da5Sopenharmony_ci auto shrinker_result = 996fd4e5da5Sopenharmony_ci Shrinker(target_env, kConsoleMessageConsumer, binary_in, initial_facts, 997fd4e5da5Sopenharmony_ci transformation_sequence_in, interestingness_function, step_limit, 998fd4e5da5Sopenharmony_ci false, validator_options) 999fd4e5da5Sopenharmony_ci .Run(); 1000fd4e5da5Sopenharmony_ci 1001fd4e5da5Sopenharmony_ci ASSERT_TRUE(Shrinker::ShrinkerResultStatus::kComplete == 1002fd4e5da5Sopenharmony_ci shrinker_result.status || 1003fd4e5da5Sopenharmony_ci Shrinker::ShrinkerResultStatus::kStepLimitReached == 1004fd4e5da5Sopenharmony_ci shrinker_result.status); 1005fd4e5da5Sopenharmony_ci 1006fd4e5da5Sopenharmony_ci // If a non-empty expected binary was provided, check that it matches the 1007fd4e5da5Sopenharmony_ci // result of shrinking and that the expected number of transformations remain. 1008fd4e5da5Sopenharmony_ci if (!expected_binary_out.empty()) { 1009fd4e5da5Sopenharmony_ci ASSERT_EQ(expected_binary_out, shrinker_result.transformed_binary); 1010fd4e5da5Sopenharmony_ci ASSERT_EQ( 1011fd4e5da5Sopenharmony_ci expected_transformations_out_size, 1012fd4e5da5Sopenharmony_ci static_cast<uint32_t>( 1013fd4e5da5Sopenharmony_ci shrinker_result.applied_transformations.transformation_size())); 1014fd4e5da5Sopenharmony_ci } 1015fd4e5da5Sopenharmony_ci} 1016fd4e5da5Sopenharmony_ci 1017fd4e5da5Sopenharmony_ci// Assembles the given |shader| text, and then: 1018fd4e5da5Sopenharmony_ci// - Runs the fuzzer with |seed| to yield a set of transformations 1019fd4e5da5Sopenharmony_ci// - Shrinks the transformation with various interestingness functions, 1020fd4e5da5Sopenharmony_ci// asserting some properties about the result each time 1021fd4e5da5Sopenharmony_civoid RunFuzzerAndShrinker(const std::string& shader, 1022fd4e5da5Sopenharmony_ci const protobufs::FactSequence& initial_facts, 1023fd4e5da5Sopenharmony_ci uint32_t seed) { 1024fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_5; 1025fd4e5da5Sopenharmony_ci 1026fd4e5da5Sopenharmony_ci std::vector<uint32_t> binary_in; 1027fd4e5da5Sopenharmony_ci SpirvTools t(env); 1028fd4e5da5Sopenharmony_ci t.SetMessageConsumer(kConsoleMessageConsumer); 1029fd4e5da5Sopenharmony_ci ASSERT_TRUE(t.Assemble(shader, &binary_in, kFuzzAssembleOption)); 1030fd4e5da5Sopenharmony_ci ASSERT_TRUE(t.Validate(binary_in)); 1031fd4e5da5Sopenharmony_ci 1032fd4e5da5Sopenharmony_ci std::vector<fuzzerutil::ModuleSupplier> donor_suppliers; 1033fd4e5da5Sopenharmony_ci for (auto donor : {&kTestShader1, &kTestShader2, &kTestShader3}) { 1034fd4e5da5Sopenharmony_ci donor_suppliers.emplace_back([donor]() { 1035fd4e5da5Sopenharmony_ci return BuildModule(env, kConsoleMessageConsumer, *donor, 1036fd4e5da5Sopenharmony_ci kFuzzAssembleOption); 1037fd4e5da5Sopenharmony_ci }); 1038fd4e5da5Sopenharmony_ci } 1039fd4e5da5Sopenharmony_ci 1040fd4e5da5Sopenharmony_ci // Run the fuzzer and check that it successfully yields a valid binary. 1041fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 1042fd4e5da5Sopenharmony_ci 1043fd4e5da5Sopenharmony_ci // Depending on the seed, decide whether to enable all passes and which 1044fd4e5da5Sopenharmony_ci // repeated pass manager to use. 1045fd4e5da5Sopenharmony_ci bool enable_all_passes = (seed % 4) == 0; 1046fd4e5da5Sopenharmony_ci RepeatedPassStrategy repeated_pass_strategy; 1047fd4e5da5Sopenharmony_ci if ((seed % 3) == 0) { 1048fd4e5da5Sopenharmony_ci repeated_pass_strategy = RepeatedPassStrategy::kSimple; 1049fd4e5da5Sopenharmony_ci } else if ((seed % 3) == 1) { 1050fd4e5da5Sopenharmony_ci repeated_pass_strategy = RepeatedPassStrategy::kLoopedWithRecommendations; 1051fd4e5da5Sopenharmony_ci } else { 1052fd4e5da5Sopenharmony_ci repeated_pass_strategy = RepeatedPassStrategy::kRandomWithRecommendations; 1053fd4e5da5Sopenharmony_ci } 1054fd4e5da5Sopenharmony_ci 1055fd4e5da5Sopenharmony_ci std::unique_ptr<opt::IRContext> ir_context; 1056fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::BuildIRContext( 1057fd4e5da5Sopenharmony_ci env, kConsoleMessageConsumer, binary_in, validator_options, &ir_context)); 1058fd4e5da5Sopenharmony_ci 1059fd4e5da5Sopenharmony_ci auto fuzzer_context = MakeUnique<FuzzerContext>( 1060fd4e5da5Sopenharmony_ci MakeUnique<PseudoRandomGenerator>(seed), 1061fd4e5da5Sopenharmony_ci FuzzerContext::GetMinFreshId(ir_context.get()), false); 1062fd4e5da5Sopenharmony_ci 1063fd4e5da5Sopenharmony_ci auto transformation_context = MakeUnique<TransformationContext>( 1064fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(ir_context.get()), validator_options); 1065fd4e5da5Sopenharmony_ci transformation_context->GetFactManager()->AddInitialFacts( 1066fd4e5da5Sopenharmony_ci kConsoleMessageConsumer, initial_facts); 1067fd4e5da5Sopenharmony_ci 1068fd4e5da5Sopenharmony_ci Fuzzer fuzzer(std::move(ir_context), std::move(transformation_context), 1069fd4e5da5Sopenharmony_ci std::move(fuzzer_context), kConsoleMessageConsumer, 1070fd4e5da5Sopenharmony_ci donor_suppliers, enable_all_passes, repeated_pass_strategy, 1071fd4e5da5Sopenharmony_ci true, validator_options, false); 1072fd4e5da5Sopenharmony_ci auto fuzzer_result = fuzzer.Run(0); 1073fd4e5da5Sopenharmony_ci ASSERT_NE(Fuzzer::Status::kFuzzerPassLedToInvalidModule, 1074fd4e5da5Sopenharmony_ci fuzzer_result.status); 1075fd4e5da5Sopenharmony_ci std::vector<uint32_t> transformed_binary; 1076fd4e5da5Sopenharmony_ci fuzzer.GetIRContext()->module()->ToBinary(&transformed_binary, true); 1077fd4e5da5Sopenharmony_ci ASSERT_TRUE(t.Validate(transformed_binary)); 1078fd4e5da5Sopenharmony_ci 1079fd4e5da5Sopenharmony_ci const uint32_t kReasonableStepLimit = 50; 1080fd4e5da5Sopenharmony_ci const uint32_t kSmallStepLimit = 20; 1081fd4e5da5Sopenharmony_ci 1082fd4e5da5Sopenharmony_ci // With the AlwaysInteresting test, we should quickly shrink to the original 1083fd4e5da5Sopenharmony_ci // binary with no transformations remaining. 1084fd4e5da5Sopenharmony_ci RunAndCheckShrinker(env, binary_in, initial_facts, 1085fd4e5da5Sopenharmony_ci fuzzer.GetTransformationSequence(), 1086fd4e5da5Sopenharmony_ci AlwaysInteresting().AsFunction(), binary_in, 0, 1087fd4e5da5Sopenharmony_ci kReasonableStepLimit, validator_options); 1088fd4e5da5Sopenharmony_ci 1089fd4e5da5Sopenharmony_ci // With the OnlyInterestingFirstTime test, no shrinking should be achieved. 1090fd4e5da5Sopenharmony_ci RunAndCheckShrinker( 1091fd4e5da5Sopenharmony_ci env, binary_in, initial_facts, fuzzer.GetTransformationSequence(), 1092fd4e5da5Sopenharmony_ci OnlyInterestingFirstTime().AsFunction(), transformed_binary, 1093fd4e5da5Sopenharmony_ci static_cast<uint32_t>( 1094fd4e5da5Sopenharmony_ci fuzzer.GetTransformationSequence().transformation_size()), 1095fd4e5da5Sopenharmony_ci kReasonableStepLimit, validator_options); 1096fd4e5da5Sopenharmony_ci 1097fd4e5da5Sopenharmony_ci // The PingPong test is unpredictable; passing an empty expected binary 1098fd4e5da5Sopenharmony_ci // means that we don't check anything beyond that shrinking completes 1099fd4e5da5Sopenharmony_ci // successfully. 1100fd4e5da5Sopenharmony_ci RunAndCheckShrinker( 1101fd4e5da5Sopenharmony_ci env, binary_in, initial_facts, fuzzer.GetTransformationSequence(), 1102fd4e5da5Sopenharmony_ci PingPong().AsFunction(), {}, 0, kSmallStepLimit, validator_options); 1103fd4e5da5Sopenharmony_ci 1104fd4e5da5Sopenharmony_ci // The InterestingThenRandom test is unpredictable; passing an empty 1105fd4e5da5Sopenharmony_ci // expected binary means that we do not check anything about shrinking 1106fd4e5da5Sopenharmony_ci // results. 1107fd4e5da5Sopenharmony_ci RunAndCheckShrinker( 1108fd4e5da5Sopenharmony_ci env, binary_in, initial_facts, fuzzer.GetTransformationSequence(), 1109fd4e5da5Sopenharmony_ci InterestingThenRandom(PseudoRandomGenerator(seed)).AsFunction(), {}, 0, 1110fd4e5da5Sopenharmony_ci kSmallStepLimit, validator_options); 1111fd4e5da5Sopenharmony_ci} 1112fd4e5da5Sopenharmony_ci 1113fd4e5da5Sopenharmony_ciTEST(FuzzerShrinkerTest, Miscellaneous1) { 1114fd4e5da5Sopenharmony_ci RunFuzzerAndShrinker(kTestShader1, protobufs::FactSequence(), 2); 1115fd4e5da5Sopenharmony_ci} 1116fd4e5da5Sopenharmony_ci 1117fd4e5da5Sopenharmony_ciTEST(FuzzerShrinkerTest, Miscellaneous2) { 1118fd4e5da5Sopenharmony_ci RunFuzzerAndShrinker(kTestShader2, protobufs::FactSequence(), 19); 1119fd4e5da5Sopenharmony_ci} 1120fd4e5da5Sopenharmony_ci 1121fd4e5da5Sopenharmony_ciTEST(FuzzerShrinkerTest, Miscellaneous3) { 1122fd4e5da5Sopenharmony_ci // Add the facts "resolution.x == 250" and "resolution.y == 100". 1123fd4e5da5Sopenharmony_ci protobufs::FactSequence facts; 1124fd4e5da5Sopenharmony_ci { 1125fd4e5da5Sopenharmony_ci protobufs::FactConstantUniform resolution_x_eq_250; 1126fd4e5da5Sopenharmony_ci *resolution_x_eq_250.mutable_uniform_buffer_element_descriptor() = 1127fd4e5da5Sopenharmony_ci MakeUniformBufferElementDescriptor(0, 0, {0, 0}); 1128fd4e5da5Sopenharmony_ci *resolution_x_eq_250.mutable_constant_word()->Add() = 250; 1129fd4e5da5Sopenharmony_ci protobufs::Fact temp; 1130fd4e5da5Sopenharmony_ci *temp.mutable_constant_uniform_fact() = resolution_x_eq_250; 1131fd4e5da5Sopenharmony_ci *facts.mutable_fact()->Add() = temp; 1132fd4e5da5Sopenharmony_ci } 1133fd4e5da5Sopenharmony_ci { 1134fd4e5da5Sopenharmony_ci protobufs::FactConstantUniform resolution_y_eq_100; 1135fd4e5da5Sopenharmony_ci *resolution_y_eq_100.mutable_uniform_buffer_element_descriptor() = 1136fd4e5da5Sopenharmony_ci MakeUniformBufferElementDescriptor(0, 0, {0, 1}); 1137fd4e5da5Sopenharmony_ci *resolution_y_eq_100.mutable_constant_word()->Add() = 100; 1138fd4e5da5Sopenharmony_ci protobufs::Fact temp; 1139fd4e5da5Sopenharmony_ci *temp.mutable_constant_uniform_fact() = resolution_y_eq_100; 1140fd4e5da5Sopenharmony_ci *facts.mutable_fact()->Add() = temp; 1141fd4e5da5Sopenharmony_ci } 1142fd4e5da5Sopenharmony_ci // Also add an invalid fact, which should be ignored. 1143fd4e5da5Sopenharmony_ci { 1144fd4e5da5Sopenharmony_ci protobufs::FactConstantUniform bad_fact; 1145fd4e5da5Sopenharmony_ci // The descriptor set, binding and indices used here deliberately make no 1146fd4e5da5Sopenharmony_ci // sense. 1147fd4e5da5Sopenharmony_ci *bad_fact.mutable_uniform_buffer_element_descriptor() = 1148fd4e5da5Sopenharmony_ci MakeUniformBufferElementDescriptor(22, 33, {44, 55}); 1149fd4e5da5Sopenharmony_ci *bad_fact.mutable_constant_word()->Add() = 100; 1150fd4e5da5Sopenharmony_ci protobufs::Fact temp; 1151fd4e5da5Sopenharmony_ci *temp.mutable_constant_uniform_fact() = bad_fact; 1152fd4e5da5Sopenharmony_ci *facts.mutable_fact()->Add() = temp; 1153fd4e5da5Sopenharmony_ci } 1154fd4e5da5Sopenharmony_ci 1155fd4e5da5Sopenharmony_ci // Do 2 fuzzer runs, starting from an initial seed of 194 (seed value chosen 1156fd4e5da5Sopenharmony_ci // arbitrarily). 1157fd4e5da5Sopenharmony_ci RunFuzzerAndShrinker(kTestShader3, facts, 194); 1158fd4e5da5Sopenharmony_ci} 1159fd4e5da5Sopenharmony_ci 1160fd4e5da5Sopenharmony_ci} // namespace 1161fd4e5da5Sopenharmony_ci} // namespace fuzz 1162fd4e5da5Sopenharmony_ci} // namespace spvtools 1163