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 "source/fuzz/fuzzer_pass_donate_modules.h" 16fd4e5da5Sopenharmony_ci 17fd4e5da5Sopenharmony_ci#include <algorithm> 18fd4e5da5Sopenharmony_ci 19fd4e5da5Sopenharmony_ci#include "gtest/gtest.h" 20fd4e5da5Sopenharmony_ci#include "source/fuzz/pseudo_random_generator.h" 21fd4e5da5Sopenharmony_ci#include "test/fuzz/fuzz_test_util.h" 22fd4e5da5Sopenharmony_ci 23fd4e5da5Sopenharmony_cinamespace spvtools { 24fd4e5da5Sopenharmony_cinamespace fuzz { 25fd4e5da5Sopenharmony_cinamespace { 26fd4e5da5Sopenharmony_ci 27fd4e5da5Sopenharmony_ciTEST(FuzzerPassDonateModulesTest, BasicDonation) { 28fd4e5da5Sopenharmony_ci std::string recipient_shader = R"( 29fd4e5da5Sopenharmony_ci OpCapability Shader 30fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 31fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 32fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 33fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 34fd4e5da5Sopenharmony_ci OpSource ESSL 310 35fd4e5da5Sopenharmony_ci OpName %4 "main" 36fd4e5da5Sopenharmony_ci OpName %10 "m" 37fd4e5da5Sopenharmony_ci OpName %16 "v" 38fd4e5da5Sopenharmony_ci OpDecorate %16 RelaxedPrecision 39fd4e5da5Sopenharmony_ci OpDecorate %20 RelaxedPrecision 40fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 41fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 42fd4e5da5Sopenharmony_ci %6 = OpTypeFloat 32 43fd4e5da5Sopenharmony_ci %7 = OpTypeVector %6 3 44fd4e5da5Sopenharmony_ci %8 = OpTypeMatrix %7 2 45fd4e5da5Sopenharmony_ci %9 = OpTypePointer Private %8 46fd4e5da5Sopenharmony_ci %10 = OpVariable %9 Private 47fd4e5da5Sopenharmony_ci %11 = OpTypeInt 32 1 48fd4e5da5Sopenharmony_ci %12 = OpConstant %11 0 49fd4e5da5Sopenharmony_ci %13 = OpTypeInt 32 0 50fd4e5da5Sopenharmony_ci %14 = OpTypeVector %13 4 51fd4e5da5Sopenharmony_ci %15 = OpTypePointer Private %14 52fd4e5da5Sopenharmony_ci %16 = OpVariable %15 Private 53fd4e5da5Sopenharmony_ci %17 = OpConstant %13 2 54fd4e5da5Sopenharmony_ci %18 = OpTypePointer Private %13 55fd4e5da5Sopenharmony_ci %22 = OpConstant %13 0 56fd4e5da5Sopenharmony_ci %23 = OpTypePointer Private %6 57fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 58fd4e5da5Sopenharmony_ci %5 = OpLabel 59fd4e5da5Sopenharmony_ci %19 = OpAccessChain %18 %16 %17 60fd4e5da5Sopenharmony_ci %20 = OpLoad %13 %19 61fd4e5da5Sopenharmony_ci %21 = OpConvertUToF %6 %20 62fd4e5da5Sopenharmony_ci %24 = OpAccessChain %23 %10 %12 %22 63fd4e5da5Sopenharmony_ci OpStore %24 %21 64fd4e5da5Sopenharmony_ci OpReturn 65fd4e5da5Sopenharmony_ci OpFunctionEnd 66fd4e5da5Sopenharmony_ci )"; 67fd4e5da5Sopenharmony_ci 68fd4e5da5Sopenharmony_ci std::string donor_shader = R"( 69fd4e5da5Sopenharmony_ci OpCapability Shader 70fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 71fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 72fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 73fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 74fd4e5da5Sopenharmony_ci OpSource ESSL 310 75fd4e5da5Sopenharmony_ci OpName %4 "main" 76fd4e5da5Sopenharmony_ci OpName %12 "bar(mf24;" 77fd4e5da5Sopenharmony_ci OpName %11 "m" 78fd4e5da5Sopenharmony_ci OpName %20 "foo(vu4;" 79fd4e5da5Sopenharmony_ci OpName %19 "v" 80fd4e5da5Sopenharmony_ci OpName %23 "x" 81fd4e5da5Sopenharmony_ci OpName %26 "param" 82fd4e5da5Sopenharmony_ci OpName %29 "result" 83fd4e5da5Sopenharmony_ci OpName %31 "i" 84fd4e5da5Sopenharmony_ci OpName %81 "param" 85fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 86fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 87fd4e5da5Sopenharmony_ci %6 = OpTypeFloat 32 88fd4e5da5Sopenharmony_ci %7 = OpTypeVector %6 4 89fd4e5da5Sopenharmony_ci %8 = OpTypeMatrix %7 2 90fd4e5da5Sopenharmony_ci %9 = OpTypePointer Function %8 91fd4e5da5Sopenharmony_ci %10 = OpTypeFunction %6 %9 92fd4e5da5Sopenharmony_ci %14 = OpTypeInt 32 0 93fd4e5da5Sopenharmony_ci %15 = OpTypeVector %14 4 94fd4e5da5Sopenharmony_ci %16 = OpTypePointer Function %15 95fd4e5da5Sopenharmony_ci %17 = OpTypeInt 32 1 96fd4e5da5Sopenharmony_ci %18 = OpTypeFunction %17 %16 97fd4e5da5Sopenharmony_ci %22 = OpTypePointer Function %17 98fd4e5da5Sopenharmony_ci %24 = OpConstant %14 2 99fd4e5da5Sopenharmony_ci %25 = OpConstantComposite %15 %24 %24 %24 %24 100fd4e5da5Sopenharmony_ci %28 = OpTypePointer Function %6 101fd4e5da5Sopenharmony_ci %30 = OpConstant %6 0 102fd4e5da5Sopenharmony_ci %32 = OpConstant %17 0 103fd4e5da5Sopenharmony_ci %39 = OpConstant %17 10 104fd4e5da5Sopenharmony_ci %40 = OpTypeBool 105fd4e5da5Sopenharmony_ci %43 = OpConstant %17 3 106fd4e5da5Sopenharmony_ci %50 = OpConstant %17 1 107fd4e5da5Sopenharmony_ci %55 = OpConstant %14 0 108fd4e5da5Sopenharmony_ci %56 = OpTypePointer Function %14 109fd4e5da5Sopenharmony_ci %59 = OpConstant %14 1 110fd4e5da5Sopenharmony_ci %65 = OpConstant %17 2 111fd4e5da5Sopenharmony_ci %68 = OpConstant %6 1 112fd4e5da5Sopenharmony_ci %69 = OpConstant %6 2 113fd4e5da5Sopenharmony_ci %70 = OpConstant %6 3 114fd4e5da5Sopenharmony_ci %71 = OpConstant %6 4 115fd4e5da5Sopenharmony_ci %72 = OpConstant %14 3 116fd4e5da5Sopenharmony_ci %76 = OpConstant %6 6 117fd4e5da5Sopenharmony_ci %77 = OpConstant %6 7 118fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 119fd4e5da5Sopenharmony_ci %5 = OpLabel 120fd4e5da5Sopenharmony_ci %23 = OpVariable %22 Function 121fd4e5da5Sopenharmony_ci %26 = OpVariable %16 Function 122fd4e5da5Sopenharmony_ci OpStore %26 %25 123fd4e5da5Sopenharmony_ci %27 = OpFunctionCall %17 %20 %26 124fd4e5da5Sopenharmony_ci OpStore %23 %27 125fd4e5da5Sopenharmony_ci OpReturn 126fd4e5da5Sopenharmony_ci OpFunctionEnd 127fd4e5da5Sopenharmony_ci %12 = OpFunction %6 None %10 128fd4e5da5Sopenharmony_ci %11 = OpFunctionParameter %9 129fd4e5da5Sopenharmony_ci %13 = OpLabel 130fd4e5da5Sopenharmony_ci %29 = OpVariable %28 Function 131fd4e5da5Sopenharmony_ci %31 = OpVariable %22 Function 132fd4e5da5Sopenharmony_ci OpStore %29 %30 133fd4e5da5Sopenharmony_ci OpStore %31 %32 134fd4e5da5Sopenharmony_ci OpBranch %33 135fd4e5da5Sopenharmony_ci %33 = OpLabel 136fd4e5da5Sopenharmony_ci OpLoopMerge %35 %36 None 137fd4e5da5Sopenharmony_ci OpBranch %37 138fd4e5da5Sopenharmony_ci %37 = OpLabel 139fd4e5da5Sopenharmony_ci %38 = OpLoad %17 %31 140fd4e5da5Sopenharmony_ci %41 = OpSLessThan %40 %38 %39 141fd4e5da5Sopenharmony_ci OpBranchConditional %41 %34 %35 142fd4e5da5Sopenharmony_ci %34 = OpLabel 143fd4e5da5Sopenharmony_ci %42 = OpLoad %17 %31 144fd4e5da5Sopenharmony_ci %44 = OpExtInst %17 %1 SClamp %42 %32 %43 145fd4e5da5Sopenharmony_ci %45 = OpAccessChain %28 %11 %32 %44 146fd4e5da5Sopenharmony_ci %46 = OpLoad %6 %45 147fd4e5da5Sopenharmony_ci %47 = OpLoad %6 %29 148fd4e5da5Sopenharmony_ci %48 = OpFAdd %6 %47 %46 149fd4e5da5Sopenharmony_ci OpStore %29 %48 150fd4e5da5Sopenharmony_ci OpBranch %36 151fd4e5da5Sopenharmony_ci %36 = OpLabel 152fd4e5da5Sopenharmony_ci %49 = OpLoad %17 %31 153fd4e5da5Sopenharmony_ci %51 = OpIAdd %17 %49 %50 154fd4e5da5Sopenharmony_ci OpStore %31 %51 155fd4e5da5Sopenharmony_ci OpBranch %33 156fd4e5da5Sopenharmony_ci %35 = OpLabel 157fd4e5da5Sopenharmony_ci %52 = OpLoad %6 %29 158fd4e5da5Sopenharmony_ci OpReturnValue %52 159fd4e5da5Sopenharmony_ci OpFunctionEnd 160fd4e5da5Sopenharmony_ci %20 = OpFunction %17 None %18 161fd4e5da5Sopenharmony_ci %19 = OpFunctionParameter %16 162fd4e5da5Sopenharmony_ci %21 = OpLabel 163fd4e5da5Sopenharmony_ci %81 = OpVariable %9 Function 164fd4e5da5Sopenharmony_ci %57 = OpAccessChain %56 %19 %55 165fd4e5da5Sopenharmony_ci %58 = OpLoad %14 %57 166fd4e5da5Sopenharmony_ci %60 = OpAccessChain %56 %19 %59 167fd4e5da5Sopenharmony_ci %61 = OpLoad %14 %60 168fd4e5da5Sopenharmony_ci %62 = OpUGreaterThan %40 %58 %61 169fd4e5da5Sopenharmony_ci OpSelectionMerge %64 None 170fd4e5da5Sopenharmony_ci OpBranchConditional %62 %63 %67 171fd4e5da5Sopenharmony_ci %63 = OpLabel 172fd4e5da5Sopenharmony_ci OpReturnValue %65 173fd4e5da5Sopenharmony_ci %67 = OpLabel 174fd4e5da5Sopenharmony_ci %73 = OpAccessChain %56 %19 %72 175fd4e5da5Sopenharmony_ci %74 = OpLoad %14 %73 176fd4e5da5Sopenharmony_ci %75 = OpConvertUToF %6 %74 177fd4e5da5Sopenharmony_ci %78 = OpCompositeConstruct %7 %30 %68 %69 %70 178fd4e5da5Sopenharmony_ci %79 = OpCompositeConstruct %7 %71 %75 %76 %77 179fd4e5da5Sopenharmony_ci %80 = OpCompositeConstruct %8 %78 %79 180fd4e5da5Sopenharmony_ci OpStore %81 %80 181fd4e5da5Sopenharmony_ci %82 = OpFunctionCall %6 %12 %81 182fd4e5da5Sopenharmony_ci %83 = OpConvertFToS %17 %82 183fd4e5da5Sopenharmony_ci OpReturnValue %83 184fd4e5da5Sopenharmony_ci %64 = OpLabel 185fd4e5da5Sopenharmony_ci %85 = OpUndef %17 186fd4e5da5Sopenharmony_ci OpReturnValue %85 187fd4e5da5Sopenharmony_ci OpFunctionEnd 188fd4e5da5Sopenharmony_ci )"; 189fd4e5da5Sopenharmony_ci 190fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 191fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 192fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 193fd4e5da5Sopenharmony_ci 194fd4e5da5Sopenharmony_ci const auto recipient_context = 195fd4e5da5Sopenharmony_ci BuildModule(env, consumer, recipient_shader, kFuzzAssembleOption); 196fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed( 197fd4e5da5Sopenharmony_ci recipient_context.get(), validator_options, kConsoleMessageConsumer)); 198fd4e5da5Sopenharmony_ci 199fd4e5da5Sopenharmony_ci const auto donor_context = 200fd4e5da5Sopenharmony_ci BuildModule(env, consumer, donor_shader, kFuzzAssembleOption); 201fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed( 202fd4e5da5Sopenharmony_ci donor_context.get(), validator_options, kConsoleMessageConsumer)); 203fd4e5da5Sopenharmony_ci 204fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 205fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(recipient_context.get()), validator_options); 206fd4e5da5Sopenharmony_ci 207fd4e5da5Sopenharmony_ci FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100, 208fd4e5da5Sopenharmony_ci false); 209fd4e5da5Sopenharmony_ci protobufs::TransformationSequence transformation_sequence; 210fd4e5da5Sopenharmony_ci 211fd4e5da5Sopenharmony_ci FuzzerPassDonateModules fuzzer_pass(recipient_context.get(), 212fd4e5da5Sopenharmony_ci &transformation_context, &fuzzer_context, 213fd4e5da5Sopenharmony_ci &transformation_sequence, false, {}); 214fd4e5da5Sopenharmony_ci 215fd4e5da5Sopenharmony_ci fuzzer_pass.DonateSingleModule(donor_context.get(), false); 216fd4e5da5Sopenharmony_ci 217fd4e5da5Sopenharmony_ci // We just check that the result is valid. Checking to what it should be 218fd4e5da5Sopenharmony_ci // exactly equal to would be very fragile. 219fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed( 220fd4e5da5Sopenharmony_ci recipient_context.get(), validator_options, kConsoleMessageConsumer)); 221fd4e5da5Sopenharmony_ci} 222fd4e5da5Sopenharmony_ci 223fd4e5da5Sopenharmony_ciTEST(FuzzerPassDonateModulesTest, DonationWithUniforms) { 224fd4e5da5Sopenharmony_ci // This test checks that when donating a shader that contains uniforms, 225fd4e5da5Sopenharmony_ci // uniform variables and associated pointer types are demoted from having 226fd4e5da5Sopenharmony_ci // Uniform storage class to Private storage class. 227fd4e5da5Sopenharmony_ci std::string recipient_and_donor_shader = R"( 228fd4e5da5Sopenharmony_ci OpCapability Shader 229fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 230fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 231fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 232fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 233fd4e5da5Sopenharmony_ci OpSource ESSL 310 234fd4e5da5Sopenharmony_ci OpMemberDecorate %9 0 Offset 0 235fd4e5da5Sopenharmony_ci OpDecorate %9 Block 236fd4e5da5Sopenharmony_ci OpDecorate %11 DescriptorSet 0 237fd4e5da5Sopenharmony_ci OpDecorate %11 Binding 0 238fd4e5da5Sopenharmony_ci OpMemberDecorate %19 0 Offset 0 239fd4e5da5Sopenharmony_ci OpDecorate %19 Block 240fd4e5da5Sopenharmony_ci OpDecorate %21 DescriptorSet 0 241fd4e5da5Sopenharmony_ci OpDecorate %21 Binding 1 242fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 243fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 244fd4e5da5Sopenharmony_ci %6 = OpTypeFloat 32 245fd4e5da5Sopenharmony_ci %7 = OpTypePointer Function %6 246fd4e5da5Sopenharmony_ci %9 = OpTypeStruct %6 247fd4e5da5Sopenharmony_ci %10 = OpTypePointer Uniform %9 248fd4e5da5Sopenharmony_ci %11 = OpVariable %10 Uniform 249fd4e5da5Sopenharmony_ci %12 = OpTypeInt 32 1 250fd4e5da5Sopenharmony_ci %13 = OpConstant %12 0 251fd4e5da5Sopenharmony_ci %14 = OpTypePointer Uniform %6 252fd4e5da5Sopenharmony_ci %17 = OpTypePointer Function %12 253fd4e5da5Sopenharmony_ci %19 = OpTypeStruct %12 254fd4e5da5Sopenharmony_ci %20 = OpTypePointer Uniform %19 255fd4e5da5Sopenharmony_ci %21 = OpVariable %20 Uniform 256fd4e5da5Sopenharmony_ci %22 = OpTypePointer Uniform %12 257fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 258fd4e5da5Sopenharmony_ci %5 = OpLabel 259fd4e5da5Sopenharmony_ci %8 = OpVariable %7 Function 260fd4e5da5Sopenharmony_ci %18 = OpVariable %17 Function 261fd4e5da5Sopenharmony_ci %15 = OpAccessChain %14 %11 %13 262fd4e5da5Sopenharmony_ci %16 = OpLoad %6 %15 263fd4e5da5Sopenharmony_ci OpStore %8 %16 264fd4e5da5Sopenharmony_ci %23 = OpAccessChain %22 %21 %13 265fd4e5da5Sopenharmony_ci %24 = OpLoad %12 %23 266fd4e5da5Sopenharmony_ci OpStore %18 %24 267fd4e5da5Sopenharmony_ci OpReturn 268fd4e5da5Sopenharmony_ci OpFunctionEnd 269fd4e5da5Sopenharmony_ci )"; 270fd4e5da5Sopenharmony_ci 271fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 272fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 273fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 274fd4e5da5Sopenharmony_ci 275fd4e5da5Sopenharmony_ci const auto recipient_context = BuildModule( 276fd4e5da5Sopenharmony_ci env, consumer, recipient_and_donor_shader, kFuzzAssembleOption); 277fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed( 278fd4e5da5Sopenharmony_ci recipient_context.get(), validator_options, kConsoleMessageConsumer)); 279fd4e5da5Sopenharmony_ci 280fd4e5da5Sopenharmony_ci const auto donor_context = BuildModule( 281fd4e5da5Sopenharmony_ci env, consumer, recipient_and_donor_shader, kFuzzAssembleOption); 282fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed( 283fd4e5da5Sopenharmony_ci donor_context.get(), validator_options, kConsoleMessageConsumer)); 284fd4e5da5Sopenharmony_ci 285fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 286fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(recipient_context.get()), validator_options); 287fd4e5da5Sopenharmony_ci 288fd4e5da5Sopenharmony_ci FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100, 289fd4e5da5Sopenharmony_ci false); 290fd4e5da5Sopenharmony_ci protobufs::TransformationSequence transformation_sequence; 291fd4e5da5Sopenharmony_ci 292fd4e5da5Sopenharmony_ci FuzzerPassDonateModules fuzzer_pass(recipient_context.get(), 293fd4e5da5Sopenharmony_ci &transformation_context, &fuzzer_context, 294fd4e5da5Sopenharmony_ci &transformation_sequence, false, {}); 295fd4e5da5Sopenharmony_ci 296fd4e5da5Sopenharmony_ci fuzzer_pass.DonateSingleModule(donor_context.get(), false); 297fd4e5da5Sopenharmony_ci 298fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed( 299fd4e5da5Sopenharmony_ci recipient_context.get(), validator_options, kConsoleMessageConsumer)); 300fd4e5da5Sopenharmony_ci 301fd4e5da5Sopenharmony_ci std::string after_transformation = R"( 302fd4e5da5Sopenharmony_ci OpCapability Shader 303fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 304fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 305fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 306fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 307fd4e5da5Sopenharmony_ci OpSource ESSL 310 308fd4e5da5Sopenharmony_ci OpMemberDecorate %9 0 Offset 0 309fd4e5da5Sopenharmony_ci OpDecorate %9 Block 310fd4e5da5Sopenharmony_ci OpDecorate %11 DescriptorSet 0 311fd4e5da5Sopenharmony_ci OpDecorate %11 Binding 0 312fd4e5da5Sopenharmony_ci OpMemberDecorate %19 0 Offset 0 313fd4e5da5Sopenharmony_ci OpDecorate %19 Block 314fd4e5da5Sopenharmony_ci OpDecorate %21 DescriptorSet 0 315fd4e5da5Sopenharmony_ci OpDecorate %21 Binding 1 316fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 317fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 318fd4e5da5Sopenharmony_ci %6 = OpTypeFloat 32 319fd4e5da5Sopenharmony_ci %7 = OpTypePointer Function %6 320fd4e5da5Sopenharmony_ci %9 = OpTypeStruct %6 321fd4e5da5Sopenharmony_ci %10 = OpTypePointer Uniform %9 322fd4e5da5Sopenharmony_ci %11 = OpVariable %10 Uniform 323fd4e5da5Sopenharmony_ci %12 = OpTypeInt 32 1 324fd4e5da5Sopenharmony_ci %13 = OpConstant %12 0 325fd4e5da5Sopenharmony_ci %14 = OpTypePointer Uniform %6 326fd4e5da5Sopenharmony_ci %17 = OpTypePointer Function %12 327fd4e5da5Sopenharmony_ci %19 = OpTypeStruct %12 328fd4e5da5Sopenharmony_ci %20 = OpTypePointer Uniform %19 329fd4e5da5Sopenharmony_ci %21 = OpVariable %20 Uniform 330fd4e5da5Sopenharmony_ci %22 = OpTypePointer Uniform %12 331fd4e5da5Sopenharmony_ci %100 = OpTypePointer Function %6 332fd4e5da5Sopenharmony_ci %101 = OpTypeStruct %6 333fd4e5da5Sopenharmony_ci %102 = OpTypePointer Private %101 334fd4e5da5Sopenharmony_ci %104 = OpConstant %6 0 335fd4e5da5Sopenharmony_ci %105 = OpConstantComposite %101 %104 336fd4e5da5Sopenharmony_ci %103 = OpVariable %102 Private %105 337fd4e5da5Sopenharmony_ci %106 = OpConstant %12 0 338fd4e5da5Sopenharmony_ci %107 = OpTypePointer Private %6 339fd4e5da5Sopenharmony_ci %108 = OpTypePointer Function %12 340fd4e5da5Sopenharmony_ci %109 = OpTypeStruct %12 341fd4e5da5Sopenharmony_ci %110 = OpTypePointer Private %109 342fd4e5da5Sopenharmony_ci %112 = OpConstantComposite %109 %13 343fd4e5da5Sopenharmony_ci %111 = OpVariable %110 Private %112 344fd4e5da5Sopenharmony_ci %113 = OpTypePointer Private %12 345fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 346fd4e5da5Sopenharmony_ci %5 = OpLabel 347fd4e5da5Sopenharmony_ci %8 = OpVariable %7 Function 348fd4e5da5Sopenharmony_ci %18 = OpVariable %17 Function 349fd4e5da5Sopenharmony_ci %15 = OpAccessChain %14 %11 %13 350fd4e5da5Sopenharmony_ci %16 = OpLoad %6 %15 351fd4e5da5Sopenharmony_ci OpStore %8 %16 352fd4e5da5Sopenharmony_ci %23 = OpAccessChain %22 %21 %13 353fd4e5da5Sopenharmony_ci %24 = OpLoad %12 %23 354fd4e5da5Sopenharmony_ci OpStore %18 %24 355fd4e5da5Sopenharmony_ci OpReturn 356fd4e5da5Sopenharmony_ci OpFunctionEnd 357fd4e5da5Sopenharmony_ci %114 = OpFunction %2 None %3 358fd4e5da5Sopenharmony_ci %115 = OpLabel 359fd4e5da5Sopenharmony_ci %116 = OpVariable %100 Function %104 360fd4e5da5Sopenharmony_ci %117 = OpVariable %108 Function %13 361fd4e5da5Sopenharmony_ci %118 = OpAccessChain %107 %103 %106 362fd4e5da5Sopenharmony_ci %119 = OpLoad %6 %118 363fd4e5da5Sopenharmony_ci OpStore %116 %119 364fd4e5da5Sopenharmony_ci %120 = OpAccessChain %113 %111 %106 365fd4e5da5Sopenharmony_ci %121 = OpLoad %12 %120 366fd4e5da5Sopenharmony_ci OpStore %117 %121 367fd4e5da5Sopenharmony_ci OpReturn 368fd4e5da5Sopenharmony_ci OpFunctionEnd 369fd4e5da5Sopenharmony_ci )"; 370fd4e5da5Sopenharmony_ci ASSERT_TRUE(IsEqual(env, after_transformation, recipient_context.get())); 371fd4e5da5Sopenharmony_ci} 372fd4e5da5Sopenharmony_ci 373fd4e5da5Sopenharmony_ciTEST(FuzzerPassDonateModulesTest, DonationWithInputAndOutputVariables) { 374fd4e5da5Sopenharmony_ci // This test checks that when donating a shader that contains input and output 375fd4e5da5Sopenharmony_ci // variables, such variables and associated pointer types are demoted to have 376fd4e5da5Sopenharmony_ci // the Private storage class. 377fd4e5da5Sopenharmony_ci std::string recipient_and_donor_shader = R"( 378fd4e5da5Sopenharmony_ci OpCapability Shader 379fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 380fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 381fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" %9 %11 382fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 383fd4e5da5Sopenharmony_ci OpSource ESSL 310 384fd4e5da5Sopenharmony_ci OpDecorate %9 Location 0 385fd4e5da5Sopenharmony_ci OpDecorate %11 Location 1 386fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 387fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 388fd4e5da5Sopenharmony_ci %6 = OpTypeFloat 32 389fd4e5da5Sopenharmony_ci %7 = OpTypeVector %6 4 390fd4e5da5Sopenharmony_ci %8 = OpTypePointer Output %7 391fd4e5da5Sopenharmony_ci %9 = OpVariable %8 Output 392fd4e5da5Sopenharmony_ci %10 = OpTypePointer Input %7 393fd4e5da5Sopenharmony_ci %11 = OpVariable %10 Input 394fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 395fd4e5da5Sopenharmony_ci %5 = OpLabel 396fd4e5da5Sopenharmony_ci %12 = OpLoad %7 %11 397fd4e5da5Sopenharmony_ci OpStore %9 %12 398fd4e5da5Sopenharmony_ci OpReturn 399fd4e5da5Sopenharmony_ci OpFunctionEnd 400fd4e5da5Sopenharmony_ci )"; 401fd4e5da5Sopenharmony_ci 402fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 403fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 404fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 405fd4e5da5Sopenharmony_ci 406fd4e5da5Sopenharmony_ci const auto recipient_context = BuildModule( 407fd4e5da5Sopenharmony_ci env, consumer, recipient_and_donor_shader, kFuzzAssembleOption); 408fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed( 409fd4e5da5Sopenharmony_ci recipient_context.get(), validator_options, kConsoleMessageConsumer)); 410fd4e5da5Sopenharmony_ci 411fd4e5da5Sopenharmony_ci const auto donor_context = BuildModule( 412fd4e5da5Sopenharmony_ci env, consumer, recipient_and_donor_shader, kFuzzAssembleOption); 413fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed( 414fd4e5da5Sopenharmony_ci donor_context.get(), validator_options, kConsoleMessageConsumer)); 415fd4e5da5Sopenharmony_ci 416fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 417fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(recipient_context.get()), validator_options); 418fd4e5da5Sopenharmony_ci 419fd4e5da5Sopenharmony_ci FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100, 420fd4e5da5Sopenharmony_ci false); 421fd4e5da5Sopenharmony_ci protobufs::TransformationSequence transformation_sequence; 422fd4e5da5Sopenharmony_ci 423fd4e5da5Sopenharmony_ci FuzzerPassDonateModules fuzzer_pass(recipient_context.get(), 424fd4e5da5Sopenharmony_ci &transformation_context, &fuzzer_context, 425fd4e5da5Sopenharmony_ci &transformation_sequence, false, {}); 426fd4e5da5Sopenharmony_ci 427fd4e5da5Sopenharmony_ci fuzzer_pass.DonateSingleModule(donor_context.get(), false); 428fd4e5da5Sopenharmony_ci 429fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed( 430fd4e5da5Sopenharmony_ci recipient_context.get(), validator_options, kConsoleMessageConsumer)); 431fd4e5da5Sopenharmony_ci 432fd4e5da5Sopenharmony_ci std::string after_transformation = R"( 433fd4e5da5Sopenharmony_ci OpCapability Shader 434fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 435fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 436fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" %9 %11 437fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 438fd4e5da5Sopenharmony_ci OpSource ESSL 310 439fd4e5da5Sopenharmony_ci OpDecorate %9 Location 0 440fd4e5da5Sopenharmony_ci OpDecorate %11 Location 1 441fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 442fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 443fd4e5da5Sopenharmony_ci %6 = OpTypeFloat 32 444fd4e5da5Sopenharmony_ci %7 = OpTypeVector %6 4 445fd4e5da5Sopenharmony_ci %8 = OpTypePointer Output %7 446fd4e5da5Sopenharmony_ci %9 = OpVariable %8 Output 447fd4e5da5Sopenharmony_ci %10 = OpTypePointer Input %7 448fd4e5da5Sopenharmony_ci %11 = OpVariable %10 Input 449fd4e5da5Sopenharmony_ci %100 = OpTypePointer Private %7 450fd4e5da5Sopenharmony_ci %102 = OpConstant %6 0 451fd4e5da5Sopenharmony_ci %103 = OpConstantComposite %7 %102 %102 %102 %102 452fd4e5da5Sopenharmony_ci %101 = OpVariable %100 Private %103 453fd4e5da5Sopenharmony_ci %104 = OpTypePointer Private %7 454fd4e5da5Sopenharmony_ci %105 = OpVariable %104 Private %103 455fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 456fd4e5da5Sopenharmony_ci %5 = OpLabel 457fd4e5da5Sopenharmony_ci %12 = OpLoad %7 %11 458fd4e5da5Sopenharmony_ci OpStore %9 %12 459fd4e5da5Sopenharmony_ci OpReturn 460fd4e5da5Sopenharmony_ci OpFunctionEnd 461fd4e5da5Sopenharmony_ci %106 = OpFunction %2 None %3 462fd4e5da5Sopenharmony_ci %107 = OpLabel 463fd4e5da5Sopenharmony_ci %108 = OpLoad %7 %105 464fd4e5da5Sopenharmony_ci OpStore %101 %108 465fd4e5da5Sopenharmony_ci OpReturn 466fd4e5da5Sopenharmony_ci OpFunctionEnd 467fd4e5da5Sopenharmony_ci )"; 468fd4e5da5Sopenharmony_ci ASSERT_TRUE(IsEqual(env, after_transformation, recipient_context.get())); 469fd4e5da5Sopenharmony_ci} 470fd4e5da5Sopenharmony_ci 471fd4e5da5Sopenharmony_ciTEST(FuzzerPassDonateModulesTest, DonateFunctionTypeWithDifferentPointers) { 472fd4e5da5Sopenharmony_ci std::string recipient_and_donor_shader = R"( 473fd4e5da5Sopenharmony_ci OpCapability Shader 474fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 475fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 476fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 477fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 478fd4e5da5Sopenharmony_ci OpSource ESSL 310 479fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 480fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 481fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 0 482fd4e5da5Sopenharmony_ci %7 = OpTypePointer Function %6 483fd4e5da5Sopenharmony_ci %8 = OpTypeFunction %2 %7 484fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 485fd4e5da5Sopenharmony_ci %5 = OpLabel 486fd4e5da5Sopenharmony_ci %9 = OpVariable %7 Function 487fd4e5da5Sopenharmony_ci %10 = OpFunctionCall %2 %11 %9 488fd4e5da5Sopenharmony_ci OpReturn 489fd4e5da5Sopenharmony_ci OpFunctionEnd 490fd4e5da5Sopenharmony_ci %11 = OpFunction %2 None %8 491fd4e5da5Sopenharmony_ci %12 = OpFunctionParameter %7 492fd4e5da5Sopenharmony_ci %13 = OpLabel 493fd4e5da5Sopenharmony_ci OpReturn 494fd4e5da5Sopenharmony_ci OpFunctionEnd 495fd4e5da5Sopenharmony_ci )"; 496fd4e5da5Sopenharmony_ci 497fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_5; 498fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 499fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 500fd4e5da5Sopenharmony_ci 501fd4e5da5Sopenharmony_ci const auto recipient_context = BuildModule( 502fd4e5da5Sopenharmony_ci env, consumer, recipient_and_donor_shader, kFuzzAssembleOption); 503fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed( 504fd4e5da5Sopenharmony_ci recipient_context.get(), validator_options, kConsoleMessageConsumer)); 505fd4e5da5Sopenharmony_ci 506fd4e5da5Sopenharmony_ci const auto donor_context = BuildModule( 507fd4e5da5Sopenharmony_ci env, consumer, recipient_and_donor_shader, kFuzzAssembleOption); 508fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed( 509fd4e5da5Sopenharmony_ci donor_context.get(), validator_options, kConsoleMessageConsumer)); 510fd4e5da5Sopenharmony_ci 511fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 512fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(recipient_context.get()), validator_options); 513fd4e5da5Sopenharmony_ci 514fd4e5da5Sopenharmony_ci FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100, 515fd4e5da5Sopenharmony_ci false); 516fd4e5da5Sopenharmony_ci protobufs::TransformationSequence transformation_sequence; 517fd4e5da5Sopenharmony_ci 518fd4e5da5Sopenharmony_ci FuzzerPassDonateModules fuzzer_pass(recipient_context.get(), 519fd4e5da5Sopenharmony_ci &transformation_context, &fuzzer_context, 520fd4e5da5Sopenharmony_ci &transformation_sequence, false, {}); 521fd4e5da5Sopenharmony_ci 522fd4e5da5Sopenharmony_ci fuzzer_pass.DonateSingleModule(donor_context.get(), false); 523fd4e5da5Sopenharmony_ci 524fd4e5da5Sopenharmony_ci // We just check that the result is valid. Checking to what it should be 525fd4e5da5Sopenharmony_ci // exactly equal to would be very fragile. 526fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed( 527fd4e5da5Sopenharmony_ci recipient_context.get(), validator_options, kConsoleMessageConsumer)); 528fd4e5da5Sopenharmony_ci} 529fd4e5da5Sopenharmony_ci 530fd4e5da5Sopenharmony_ciTEST(FuzzerPassDonateModulesTest, DonateOpConstantNull) { 531fd4e5da5Sopenharmony_ci std::string recipient_shader = R"( 532fd4e5da5Sopenharmony_ci OpCapability Shader 533fd4e5da5Sopenharmony_ci OpCapability ImageQuery 534fd4e5da5Sopenharmony_ci OpCapability VariablePointers 535fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 536fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 537fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 538fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 539fd4e5da5Sopenharmony_ci OpSource ESSL 320 540fd4e5da5Sopenharmony_ci OpSourceExtension "GL_EXT_samplerless_texture_functions" 541fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 542fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 543fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 544fd4e5da5Sopenharmony_ci %5 = OpLabel 545fd4e5da5Sopenharmony_ci OpReturn 546fd4e5da5Sopenharmony_ci OpFunctionEnd 547fd4e5da5Sopenharmony_ci )"; 548fd4e5da5Sopenharmony_ci 549fd4e5da5Sopenharmony_ci std::string donor_shader = R"( 550fd4e5da5Sopenharmony_ci OpCapability Shader 551fd4e5da5Sopenharmony_ci OpCapability ImageQuery 552fd4e5da5Sopenharmony_ci OpCapability VariablePointers 553fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 554fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 555fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 556fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 557fd4e5da5Sopenharmony_ci OpSource ESSL 320 558fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 559fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 560fd4e5da5Sopenharmony_ci %6 = OpTypeFloat 32 561fd4e5da5Sopenharmony_ci %7 = OpTypePointer Private %6 562fd4e5da5Sopenharmony_ci %8 = OpConstantNull %7 563fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 564fd4e5da5Sopenharmony_ci %5 = OpLabel 565fd4e5da5Sopenharmony_ci OpReturn 566fd4e5da5Sopenharmony_ci OpFunctionEnd 567fd4e5da5Sopenharmony_ci )"; 568fd4e5da5Sopenharmony_ci 569fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 570fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 571fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 572fd4e5da5Sopenharmony_ci 573fd4e5da5Sopenharmony_ci const auto recipient_context = 574fd4e5da5Sopenharmony_ci BuildModule(env, consumer, recipient_shader, kFuzzAssembleOption); 575fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed( 576fd4e5da5Sopenharmony_ci recipient_context.get(), validator_options, kConsoleMessageConsumer)); 577fd4e5da5Sopenharmony_ci 578fd4e5da5Sopenharmony_ci const auto donor_context = 579fd4e5da5Sopenharmony_ci BuildModule(env, consumer, donor_shader, kFuzzAssembleOption); 580fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed( 581fd4e5da5Sopenharmony_ci donor_context.get(), validator_options, kConsoleMessageConsumer)); 582fd4e5da5Sopenharmony_ci 583fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 584fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(recipient_context.get()), validator_options); 585fd4e5da5Sopenharmony_ci 586fd4e5da5Sopenharmony_ci FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100, 587fd4e5da5Sopenharmony_ci false); 588fd4e5da5Sopenharmony_ci protobufs::TransformationSequence transformation_sequence; 589fd4e5da5Sopenharmony_ci 590fd4e5da5Sopenharmony_ci FuzzerPassDonateModules fuzzer_pass(recipient_context.get(), 591fd4e5da5Sopenharmony_ci &transformation_context, &fuzzer_context, 592fd4e5da5Sopenharmony_ci &transformation_sequence, false, {}); 593fd4e5da5Sopenharmony_ci 594fd4e5da5Sopenharmony_ci fuzzer_pass.DonateSingleModule(donor_context.get(), false); 595fd4e5da5Sopenharmony_ci 596fd4e5da5Sopenharmony_ci // We just check that the result is valid. Checking to what it should be 597fd4e5da5Sopenharmony_ci // exactly equal to would be very fragile. 598fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed( 599fd4e5da5Sopenharmony_ci recipient_context.get(), validator_options, kConsoleMessageConsumer)); 600fd4e5da5Sopenharmony_ci} 601fd4e5da5Sopenharmony_ci 602fd4e5da5Sopenharmony_ciTEST(FuzzerPassDonateModulesTest, DonateCodeThatUsesImages) { 603fd4e5da5Sopenharmony_ci std::string recipient_shader = R"( 604fd4e5da5Sopenharmony_ci OpCapability Shader 605fd4e5da5Sopenharmony_ci OpCapability ImageQuery 606fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 607fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 608fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 609fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 610fd4e5da5Sopenharmony_ci OpSource ESSL 320 611fd4e5da5Sopenharmony_ci OpSourceExtension "GL_EXT_samplerless_texture_functions" 612fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 613fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 614fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 615fd4e5da5Sopenharmony_ci %5 = OpLabel 616fd4e5da5Sopenharmony_ci OpReturn 617fd4e5da5Sopenharmony_ci OpFunctionEnd 618fd4e5da5Sopenharmony_ci )"; 619fd4e5da5Sopenharmony_ci 620fd4e5da5Sopenharmony_ci std::string donor_shader = R"( 621fd4e5da5Sopenharmony_ci OpCapability Shader 622fd4e5da5Sopenharmony_ci OpCapability ImageQuery 623fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 624fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 625fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 626fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 627fd4e5da5Sopenharmony_ci OpSource ESSL 320 628fd4e5da5Sopenharmony_ci OpSourceExtension "GL_EXT_samplerless_texture_functions" 629fd4e5da5Sopenharmony_ci OpName %4 "main" 630fd4e5da5Sopenharmony_ci OpName %10 "mySampler" 631fd4e5da5Sopenharmony_ci OpName %21 "myTexture" 632fd4e5da5Sopenharmony_ci OpName %33 "v" 633fd4e5da5Sopenharmony_ci OpDecorate %10 RelaxedPrecision 634fd4e5da5Sopenharmony_ci OpDecorate %10 DescriptorSet 0 635fd4e5da5Sopenharmony_ci OpDecorate %10 Binding 0 636fd4e5da5Sopenharmony_ci OpDecorate %11 RelaxedPrecision 637fd4e5da5Sopenharmony_ci OpDecorate %21 RelaxedPrecision 638fd4e5da5Sopenharmony_ci OpDecorate %21 DescriptorSet 0 639fd4e5da5Sopenharmony_ci OpDecorate %21 Binding 1 640fd4e5da5Sopenharmony_ci OpDecorate %22 RelaxedPrecision 641fd4e5da5Sopenharmony_ci OpDecorate %34 RelaxedPrecision 642fd4e5da5Sopenharmony_ci OpDecorate %40 RelaxedPrecision 643fd4e5da5Sopenharmony_ci OpDecorate %42 RelaxedPrecision 644fd4e5da5Sopenharmony_ci OpDecorate %43 RelaxedPrecision 645fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 646fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 647fd4e5da5Sopenharmony_ci %6 = OpTypeFloat 32 648fd4e5da5Sopenharmony_ci %7 = OpTypeImage %6 2D 0 0 0 1 Unknown 649fd4e5da5Sopenharmony_ci %8 = OpTypeSampledImage %7 650fd4e5da5Sopenharmony_ci %9 = OpTypePointer UniformConstant %8 651fd4e5da5Sopenharmony_ci %10 = OpVariable %9 UniformConstant 652fd4e5da5Sopenharmony_ci %12 = OpTypeInt 32 1 653fd4e5da5Sopenharmony_ci %13 = OpConstant %12 2 654fd4e5da5Sopenharmony_ci %15 = OpTypeVector %12 2 655fd4e5da5Sopenharmony_ci %17 = OpTypeInt 32 0 656fd4e5da5Sopenharmony_ci %18 = OpConstant %17 0 657fd4e5da5Sopenharmony_ci %20 = OpTypePointer UniformConstant %7 658fd4e5da5Sopenharmony_ci %21 = OpVariable %20 UniformConstant 659fd4e5da5Sopenharmony_ci %23 = OpConstant %12 1 660fd4e5da5Sopenharmony_ci %25 = OpConstant %17 1 661fd4e5da5Sopenharmony_ci %27 = OpTypeBool 662fd4e5da5Sopenharmony_ci %31 = OpTypeVector %6 4 663fd4e5da5Sopenharmony_ci %32 = OpTypePointer Function %31 664fd4e5da5Sopenharmony_ci %35 = OpConstantComposite %15 %23 %23 665fd4e5da5Sopenharmony_ci %36 = OpConstant %12 3 666fd4e5da5Sopenharmony_ci %37 = OpConstant %12 4 667fd4e5da5Sopenharmony_ci %38 = OpConstantComposite %15 %36 %37 668fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 669fd4e5da5Sopenharmony_ci %5 = OpLabel 670fd4e5da5Sopenharmony_ci %33 = OpVariable %32 Function 671fd4e5da5Sopenharmony_ci %11 = OpLoad %8 %10 672fd4e5da5Sopenharmony_ci %14 = OpImage %7 %11 673fd4e5da5Sopenharmony_ci %16 = OpImageQuerySizeLod %15 %14 %13 674fd4e5da5Sopenharmony_ci %19 = OpCompositeExtract %12 %16 0 675fd4e5da5Sopenharmony_ci %22 = OpLoad %7 %21 676fd4e5da5Sopenharmony_ci %24 = OpImageQuerySizeLod %15 %22 %23 677fd4e5da5Sopenharmony_ci %26 = OpCompositeExtract %12 %24 1 678fd4e5da5Sopenharmony_ci %28 = OpSGreaterThan %27 %19 %26 679fd4e5da5Sopenharmony_ci OpSelectionMerge %30 None 680fd4e5da5Sopenharmony_ci OpBranchConditional %28 %29 %41 681fd4e5da5Sopenharmony_ci %29 = OpLabel 682fd4e5da5Sopenharmony_ci %34 = OpLoad %8 %10 683fd4e5da5Sopenharmony_ci %39 = OpImage %7 %34 684fd4e5da5Sopenharmony_ci %40 = OpImageFetch %31 %39 %35 Lod|ConstOffset %13 %38 685fd4e5da5Sopenharmony_ci OpStore %33 %40 686fd4e5da5Sopenharmony_ci OpBranch %30 687fd4e5da5Sopenharmony_ci %41 = OpLabel 688fd4e5da5Sopenharmony_ci %42 = OpLoad %7 %21 689fd4e5da5Sopenharmony_ci %43 = OpImageFetch %31 %42 %35 Lod|ConstOffset %13 %38 690fd4e5da5Sopenharmony_ci OpStore %33 %43 691fd4e5da5Sopenharmony_ci OpBranch %30 692fd4e5da5Sopenharmony_ci %30 = OpLabel 693fd4e5da5Sopenharmony_ci OpReturn 694fd4e5da5Sopenharmony_ci OpFunctionEnd 695fd4e5da5Sopenharmony_ci )"; 696fd4e5da5Sopenharmony_ci 697fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 698fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 699fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 700fd4e5da5Sopenharmony_ci 701fd4e5da5Sopenharmony_ci const auto recipient_context = 702fd4e5da5Sopenharmony_ci BuildModule(env, consumer, recipient_shader, kFuzzAssembleOption); 703fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed( 704fd4e5da5Sopenharmony_ci recipient_context.get(), validator_options, kConsoleMessageConsumer)); 705fd4e5da5Sopenharmony_ci 706fd4e5da5Sopenharmony_ci const auto donor_context = 707fd4e5da5Sopenharmony_ci BuildModule(env, consumer, donor_shader, kFuzzAssembleOption); 708fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed( 709fd4e5da5Sopenharmony_ci donor_context.get(), validator_options, kConsoleMessageConsumer)); 710fd4e5da5Sopenharmony_ci 711fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 712fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(recipient_context.get()), validator_options); 713fd4e5da5Sopenharmony_ci 714fd4e5da5Sopenharmony_ci FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100, 715fd4e5da5Sopenharmony_ci false); 716fd4e5da5Sopenharmony_ci protobufs::TransformationSequence transformation_sequence; 717fd4e5da5Sopenharmony_ci 718fd4e5da5Sopenharmony_ci FuzzerPassDonateModules fuzzer_pass(recipient_context.get(), 719fd4e5da5Sopenharmony_ci &transformation_context, &fuzzer_context, 720fd4e5da5Sopenharmony_ci &transformation_sequence, false, {}); 721fd4e5da5Sopenharmony_ci 722fd4e5da5Sopenharmony_ci fuzzer_pass.DonateSingleModule(donor_context.get(), false); 723fd4e5da5Sopenharmony_ci 724fd4e5da5Sopenharmony_ci // We just check that the result is valid. Checking to what it should be 725fd4e5da5Sopenharmony_ci // exactly equal to would be very fragile. 726fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed( 727fd4e5da5Sopenharmony_ci recipient_context.get(), validator_options, kConsoleMessageConsumer)); 728fd4e5da5Sopenharmony_ci} 729fd4e5da5Sopenharmony_ci 730fd4e5da5Sopenharmony_ciTEST(FuzzerPassDonateModulesTest, DonateCodeThatUsesSampler) { 731fd4e5da5Sopenharmony_ci std::string recipient_shader = R"( 732fd4e5da5Sopenharmony_ci OpCapability Shader 733fd4e5da5Sopenharmony_ci OpCapability ImageQuery 734fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 735fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 736fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 737fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 738fd4e5da5Sopenharmony_ci OpSource ESSL 320 739fd4e5da5Sopenharmony_ci OpSourceExtension "GL_EXT_samplerless_texture_functions" 740fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 741fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 742fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 743fd4e5da5Sopenharmony_ci %5 = OpLabel 744fd4e5da5Sopenharmony_ci OpReturn 745fd4e5da5Sopenharmony_ci OpFunctionEnd 746fd4e5da5Sopenharmony_ci )"; 747fd4e5da5Sopenharmony_ci 748fd4e5da5Sopenharmony_ci std::string donor_shader = R"( 749fd4e5da5Sopenharmony_ci OpCapability Shader 750fd4e5da5Sopenharmony_ci OpCapability ImageQuery 751fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 752fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 753fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 754fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 755fd4e5da5Sopenharmony_ci OpSource ESSL 320 756fd4e5da5Sopenharmony_ci OpDecorate %16 DescriptorSet 0 757fd4e5da5Sopenharmony_ci OpDecorate %16 Binding 0 758fd4e5da5Sopenharmony_ci OpDecorate %12 DescriptorSet 0 759fd4e5da5Sopenharmony_ci OpDecorate %12 Binding 64 760fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 761fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 762fd4e5da5Sopenharmony_ci %23 = OpTypeFloat 32 763fd4e5da5Sopenharmony_ci %6 = OpTypeImage %23 2D 2 0 0 1 Unknown 764fd4e5da5Sopenharmony_ci %47 = OpTypePointer UniformConstant %6 765fd4e5da5Sopenharmony_ci %12 = OpVariable %47 UniformConstant 766fd4e5da5Sopenharmony_ci %15 = OpTypeSampler 767fd4e5da5Sopenharmony_ci %55 = OpTypePointer UniformConstant %15 768fd4e5da5Sopenharmony_ci %17 = OpTypeSampledImage %6 769fd4e5da5Sopenharmony_ci %16 = OpVariable %55 UniformConstant 770fd4e5da5Sopenharmony_ci %37 = OpTypeVector %23 4 771fd4e5da5Sopenharmony_ci %109 = OpConstant %23 0 772fd4e5da5Sopenharmony_ci %66 = OpConstantComposite %37 %109 %109 %109 %109 773fd4e5da5Sopenharmony_ci %56 = OpTypeBool 774fd4e5da5Sopenharmony_ci %54 = OpConstantTrue %56 775fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 776fd4e5da5Sopenharmony_ci %5 = OpLabel 777fd4e5da5Sopenharmony_ci OpBranch %50 778fd4e5da5Sopenharmony_ci %50 = OpLabel 779fd4e5da5Sopenharmony_ci %51 = OpPhi %37 %66 %5 %111 %53 780fd4e5da5Sopenharmony_ci OpLoopMerge %52 %53 None 781fd4e5da5Sopenharmony_ci OpBranchConditional %54 %53 %52 782fd4e5da5Sopenharmony_ci %53 = OpLabel 783fd4e5da5Sopenharmony_ci %106 = OpLoad %6 %12 784fd4e5da5Sopenharmony_ci %107 = OpLoad %15 %16 785fd4e5da5Sopenharmony_ci %110 = OpSampledImage %17 %106 %107 786fd4e5da5Sopenharmony_ci %111 = OpImageSampleImplicitLod %37 %110 %66 Bias %109 787fd4e5da5Sopenharmony_ci OpBranch %50 788fd4e5da5Sopenharmony_ci %52 = OpLabel 789fd4e5da5Sopenharmony_ci OpReturn 790fd4e5da5Sopenharmony_ci OpFunctionEnd 791fd4e5da5Sopenharmony_ci )"; 792fd4e5da5Sopenharmony_ci 793fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 794fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 795fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 796fd4e5da5Sopenharmony_ci 797fd4e5da5Sopenharmony_ci const auto recipient_context = 798fd4e5da5Sopenharmony_ci BuildModule(env, consumer, recipient_shader, kFuzzAssembleOption); 799fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed( 800fd4e5da5Sopenharmony_ci recipient_context.get(), validator_options, kConsoleMessageConsumer)); 801fd4e5da5Sopenharmony_ci 802fd4e5da5Sopenharmony_ci const auto donor_context = 803fd4e5da5Sopenharmony_ci BuildModule(env, consumer, donor_shader, kFuzzAssembleOption); 804fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed( 805fd4e5da5Sopenharmony_ci donor_context.get(), validator_options, kConsoleMessageConsumer)); 806fd4e5da5Sopenharmony_ci 807fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 808fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(recipient_context.get()), validator_options); 809fd4e5da5Sopenharmony_ci 810fd4e5da5Sopenharmony_ci FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100, 811fd4e5da5Sopenharmony_ci false); 812fd4e5da5Sopenharmony_ci protobufs::TransformationSequence transformation_sequence; 813fd4e5da5Sopenharmony_ci 814fd4e5da5Sopenharmony_ci FuzzerPassDonateModules fuzzer_pass(recipient_context.get(), 815fd4e5da5Sopenharmony_ci &transformation_context, &fuzzer_context, 816fd4e5da5Sopenharmony_ci &transformation_sequence, false, {}); 817fd4e5da5Sopenharmony_ci 818fd4e5da5Sopenharmony_ci fuzzer_pass.DonateSingleModule(donor_context.get(), false); 819fd4e5da5Sopenharmony_ci 820fd4e5da5Sopenharmony_ci // We just check that the result is valid. Checking to what it should be 821fd4e5da5Sopenharmony_ci // exactly equal to would be very fragile. 822fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed( 823fd4e5da5Sopenharmony_ci recipient_context.get(), validator_options, kConsoleMessageConsumer)); 824fd4e5da5Sopenharmony_ci} 825fd4e5da5Sopenharmony_ci 826fd4e5da5Sopenharmony_ciTEST(FuzzerPassDonateModulesTest, DonateCodeThatUsesImageStructField) { 827fd4e5da5Sopenharmony_ci std::string recipient_shader = R"( 828fd4e5da5Sopenharmony_ci OpCapability Shader 829fd4e5da5Sopenharmony_ci OpCapability ImageQuery 830fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 831fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 832fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 833fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 834fd4e5da5Sopenharmony_ci OpSource ESSL 320 835fd4e5da5Sopenharmony_ci OpSourceExtension "GL_EXT_samplerless_texture_functions" 836fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 837fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 838fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 839fd4e5da5Sopenharmony_ci %5 = OpLabel 840fd4e5da5Sopenharmony_ci OpReturn 841fd4e5da5Sopenharmony_ci OpFunctionEnd 842fd4e5da5Sopenharmony_ci )"; 843fd4e5da5Sopenharmony_ci 844fd4e5da5Sopenharmony_ci std::string donor_shader = R"( 845fd4e5da5Sopenharmony_ci OpCapability Shader 846fd4e5da5Sopenharmony_ci OpCapability ImageQuery 847fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 848fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 849fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 850fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 851fd4e5da5Sopenharmony_ci OpSource ESSL 320 852fd4e5da5Sopenharmony_ci OpSourceExtension "GL_EXT_samplerless_texture_functions" 853fd4e5da5Sopenharmony_ci OpName %4 "main" 854fd4e5da5Sopenharmony_ci OpName %10 "mySampler" 855fd4e5da5Sopenharmony_ci OpName %21 "myTexture" 856fd4e5da5Sopenharmony_ci OpName %33 "v" 857fd4e5da5Sopenharmony_ci OpDecorate %10 RelaxedPrecision 858fd4e5da5Sopenharmony_ci OpDecorate %10 DescriptorSet 0 859fd4e5da5Sopenharmony_ci OpDecorate %10 Binding 0 860fd4e5da5Sopenharmony_ci OpDecorate %11 RelaxedPrecision 861fd4e5da5Sopenharmony_ci OpDecorate %21 RelaxedPrecision 862fd4e5da5Sopenharmony_ci OpDecorate %21 DescriptorSet 0 863fd4e5da5Sopenharmony_ci OpDecorate %21 Binding 1 864fd4e5da5Sopenharmony_ci OpDecorate %22 RelaxedPrecision 865fd4e5da5Sopenharmony_ci OpDecorate %34 RelaxedPrecision 866fd4e5da5Sopenharmony_ci OpDecorate %40 RelaxedPrecision 867fd4e5da5Sopenharmony_ci OpDecorate %42 RelaxedPrecision 868fd4e5da5Sopenharmony_ci OpDecorate %43 RelaxedPrecision 869fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 870fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 871fd4e5da5Sopenharmony_ci %6 = OpTypeFloat 32 872fd4e5da5Sopenharmony_ci %7 = OpTypeImage %6 2D 0 0 0 1 Unknown 873fd4e5da5Sopenharmony_ci %8 = OpTypeSampledImage %7 874fd4e5da5Sopenharmony_ci %9 = OpTypePointer UniformConstant %8 875fd4e5da5Sopenharmony_ci %10 = OpVariable %9 UniformConstant 876fd4e5da5Sopenharmony_ci %12 = OpTypeInt 32 1 877fd4e5da5Sopenharmony_ci %13 = OpConstant %12 2 878fd4e5da5Sopenharmony_ci %15 = OpTypeVector %12 2 879fd4e5da5Sopenharmony_ci %17 = OpTypeInt 32 0 880fd4e5da5Sopenharmony_ci %18 = OpConstant %17 0 881fd4e5da5Sopenharmony_ci %20 = OpTypePointer UniformConstant %7 882fd4e5da5Sopenharmony_ci %21 = OpVariable %20 UniformConstant 883fd4e5da5Sopenharmony_ci %23 = OpConstant %12 1 884fd4e5da5Sopenharmony_ci %25 = OpConstant %17 1 885fd4e5da5Sopenharmony_ci %27 = OpTypeBool 886fd4e5da5Sopenharmony_ci %31 = OpTypeVector %6 4 887fd4e5da5Sopenharmony_ci %32 = OpTypePointer Function %31 888fd4e5da5Sopenharmony_ci %35 = OpConstantComposite %15 %23 %23 889fd4e5da5Sopenharmony_ci %36 = OpConstant %12 3 890fd4e5da5Sopenharmony_ci %37 = OpConstant %12 4 891fd4e5da5Sopenharmony_ci %38 = OpConstantComposite %15 %36 %37 892fd4e5da5Sopenharmony_ci %201 = OpTypeStruct %7 %7 893fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 894fd4e5da5Sopenharmony_ci %5 = OpLabel 895fd4e5da5Sopenharmony_ci %33 = OpVariable %32 Function 896fd4e5da5Sopenharmony_ci %11 = OpLoad %8 %10 897fd4e5da5Sopenharmony_ci %14 = OpImage %7 %11 898fd4e5da5Sopenharmony_ci %22 = OpLoad %7 %21 899fd4e5da5Sopenharmony_ci %200 = OpCompositeConstruct %201 %14 %22 900fd4e5da5Sopenharmony_ci %202 = OpCompositeExtract %7 %200 0 901fd4e5da5Sopenharmony_ci %203 = OpCompositeExtract %7 %200 1 902fd4e5da5Sopenharmony_ci %24 = OpImageQuerySizeLod %15 %203 %23 903fd4e5da5Sopenharmony_ci %16 = OpImageQuerySizeLod %15 %202 %13 904fd4e5da5Sopenharmony_ci %26 = OpCompositeExtract %12 %24 1 905fd4e5da5Sopenharmony_ci %19 = OpCompositeExtract %12 %16 0 906fd4e5da5Sopenharmony_ci %28 = OpSGreaterThan %27 %19 %26 907fd4e5da5Sopenharmony_ci OpSelectionMerge %30 None 908fd4e5da5Sopenharmony_ci OpBranchConditional %28 %29 %41 909fd4e5da5Sopenharmony_ci %29 = OpLabel 910fd4e5da5Sopenharmony_ci %34 = OpLoad %8 %10 911fd4e5da5Sopenharmony_ci %39 = OpImage %7 %34 912fd4e5da5Sopenharmony_ci %40 = OpImageFetch %31 %39 %35 Lod|ConstOffset %13 %38 913fd4e5da5Sopenharmony_ci OpStore %33 %40 914fd4e5da5Sopenharmony_ci OpBranch %30 915fd4e5da5Sopenharmony_ci %41 = OpLabel 916fd4e5da5Sopenharmony_ci %42 = OpLoad %7 %21 917fd4e5da5Sopenharmony_ci %43 = OpImageFetch %31 %42 %35 Lod|ConstOffset %13 %38 918fd4e5da5Sopenharmony_ci OpStore %33 %43 919fd4e5da5Sopenharmony_ci OpBranch %30 920fd4e5da5Sopenharmony_ci %30 = OpLabel 921fd4e5da5Sopenharmony_ci OpReturn 922fd4e5da5Sopenharmony_ci OpFunctionEnd 923fd4e5da5Sopenharmony_ci )"; 924fd4e5da5Sopenharmony_ci 925fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 926fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 927fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 928fd4e5da5Sopenharmony_ci 929fd4e5da5Sopenharmony_ci const auto recipient_context = 930fd4e5da5Sopenharmony_ci BuildModule(env, consumer, recipient_shader, kFuzzAssembleOption); 931fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed( 932fd4e5da5Sopenharmony_ci recipient_context.get(), validator_options, kConsoleMessageConsumer)); 933fd4e5da5Sopenharmony_ci 934fd4e5da5Sopenharmony_ci const auto donor_context = 935fd4e5da5Sopenharmony_ci BuildModule(env, consumer, donor_shader, kFuzzAssembleOption); 936fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed( 937fd4e5da5Sopenharmony_ci donor_context.get(), validator_options, kConsoleMessageConsumer)); 938fd4e5da5Sopenharmony_ci 939fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 940fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(recipient_context.get()), validator_options); 941fd4e5da5Sopenharmony_ci 942fd4e5da5Sopenharmony_ci FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100, 943fd4e5da5Sopenharmony_ci false); 944fd4e5da5Sopenharmony_ci protobufs::TransformationSequence transformation_sequence; 945fd4e5da5Sopenharmony_ci 946fd4e5da5Sopenharmony_ci FuzzerPassDonateModules fuzzer_pass(recipient_context.get(), 947fd4e5da5Sopenharmony_ci &transformation_context, &fuzzer_context, 948fd4e5da5Sopenharmony_ci &transformation_sequence, false, {}); 949fd4e5da5Sopenharmony_ci 950fd4e5da5Sopenharmony_ci fuzzer_pass.DonateSingleModule(donor_context.get(), false); 951fd4e5da5Sopenharmony_ci 952fd4e5da5Sopenharmony_ci // We just check that the result is valid. Checking to what it should be 953fd4e5da5Sopenharmony_ci // exactly equal to would be very fragile. 954fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed( 955fd4e5da5Sopenharmony_ci recipient_context.get(), validator_options, kConsoleMessageConsumer)); 956fd4e5da5Sopenharmony_ci} 957fd4e5da5Sopenharmony_ci 958fd4e5da5Sopenharmony_ciTEST(FuzzerPassDonateModulesTest, DonateCodeThatUsesImageFunctionParameter) { 959fd4e5da5Sopenharmony_ci std::string recipient_shader = R"( 960fd4e5da5Sopenharmony_ci OpCapability Shader 961fd4e5da5Sopenharmony_ci OpCapability ImageQuery 962fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 963fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 964fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 965fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 966fd4e5da5Sopenharmony_ci OpSource ESSL 320 967fd4e5da5Sopenharmony_ci OpSourceExtension "GL_EXT_samplerless_texture_functions" 968fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 969fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 970fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 971fd4e5da5Sopenharmony_ci %5 = OpLabel 972fd4e5da5Sopenharmony_ci OpReturn 973fd4e5da5Sopenharmony_ci OpFunctionEnd 974fd4e5da5Sopenharmony_ci )"; 975fd4e5da5Sopenharmony_ci 976fd4e5da5Sopenharmony_ci std::string donor_shader = R"( 977fd4e5da5Sopenharmony_ci OpCapability Shader 978fd4e5da5Sopenharmony_ci OpCapability ImageQuery 979fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 980fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 981fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 982fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 983fd4e5da5Sopenharmony_ci OpSource ESSL 320 984fd4e5da5Sopenharmony_ci OpSourceExtension "GL_EXT_samplerless_texture_functions" 985fd4e5da5Sopenharmony_ci OpName %4 "main" 986fd4e5da5Sopenharmony_ci OpName %10 "mySampler" 987fd4e5da5Sopenharmony_ci OpName %21 "myTexture" 988fd4e5da5Sopenharmony_ci OpName %33 "v" 989fd4e5da5Sopenharmony_ci OpDecorate %10 RelaxedPrecision 990fd4e5da5Sopenharmony_ci OpDecorate %10 DescriptorSet 0 991fd4e5da5Sopenharmony_ci OpDecorate %10 Binding 0 992fd4e5da5Sopenharmony_ci OpDecorate %11 RelaxedPrecision 993fd4e5da5Sopenharmony_ci OpDecorate %21 RelaxedPrecision 994fd4e5da5Sopenharmony_ci OpDecorate %21 DescriptorSet 0 995fd4e5da5Sopenharmony_ci OpDecorate %21 Binding 1 996fd4e5da5Sopenharmony_ci OpDecorate %22 RelaxedPrecision 997fd4e5da5Sopenharmony_ci OpDecorate %34 RelaxedPrecision 998fd4e5da5Sopenharmony_ci OpDecorate %40 RelaxedPrecision 999fd4e5da5Sopenharmony_ci OpDecorate %42 RelaxedPrecision 1000fd4e5da5Sopenharmony_ci OpDecorate %43 RelaxedPrecision 1001fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 1002fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 1003fd4e5da5Sopenharmony_ci %6 = OpTypeFloat 32 1004fd4e5da5Sopenharmony_ci %7 = OpTypeImage %6 2D 0 0 0 1 Unknown 1005fd4e5da5Sopenharmony_ci %8 = OpTypeSampledImage %7 1006fd4e5da5Sopenharmony_ci %9 = OpTypePointer UniformConstant %8 1007fd4e5da5Sopenharmony_ci %10 = OpVariable %9 UniformConstant 1008fd4e5da5Sopenharmony_ci %12 = OpTypeInt 32 1 1009fd4e5da5Sopenharmony_ci %13 = OpConstant %12 2 1010fd4e5da5Sopenharmony_ci %15 = OpTypeVector %12 2 1011fd4e5da5Sopenharmony_ci %17 = OpTypeInt 32 0 1012fd4e5da5Sopenharmony_ci %18 = OpConstant %17 0 1013fd4e5da5Sopenharmony_ci %20 = OpTypePointer UniformConstant %7 1014fd4e5da5Sopenharmony_ci %21 = OpVariable %20 UniformConstant 1015fd4e5da5Sopenharmony_ci %23 = OpConstant %12 1 1016fd4e5da5Sopenharmony_ci %25 = OpConstant %17 1 1017fd4e5da5Sopenharmony_ci %27 = OpTypeBool 1018fd4e5da5Sopenharmony_ci %31 = OpTypeVector %6 4 1019fd4e5da5Sopenharmony_ci %32 = OpTypePointer Function %31 1020fd4e5da5Sopenharmony_ci %35 = OpConstantComposite %15 %23 %23 1021fd4e5da5Sopenharmony_ci %36 = OpConstant %12 3 1022fd4e5da5Sopenharmony_ci %37 = OpConstant %12 4 1023fd4e5da5Sopenharmony_ci %38 = OpConstantComposite %15 %36 %37 1024fd4e5da5Sopenharmony_ci %201 = OpTypeFunction %15 %7 %12 1025fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 1026fd4e5da5Sopenharmony_ci %5 = OpLabel 1027fd4e5da5Sopenharmony_ci %33 = OpVariable %32 Function 1028fd4e5da5Sopenharmony_ci %11 = OpLoad %8 %10 1029fd4e5da5Sopenharmony_ci %14 = OpImage %7 %11 1030fd4e5da5Sopenharmony_ci %16 = OpFunctionCall %15 %200 %14 %13 1031fd4e5da5Sopenharmony_ci %19 = OpCompositeExtract %12 %16 0 1032fd4e5da5Sopenharmony_ci %22 = OpLoad %7 %21 1033fd4e5da5Sopenharmony_ci %24 = OpImageQuerySizeLod %15 %22 %23 1034fd4e5da5Sopenharmony_ci %26 = OpCompositeExtract %12 %24 1 1035fd4e5da5Sopenharmony_ci %28 = OpSGreaterThan %27 %19 %26 1036fd4e5da5Sopenharmony_ci OpSelectionMerge %30 None 1037fd4e5da5Sopenharmony_ci OpBranchConditional %28 %29 %41 1038fd4e5da5Sopenharmony_ci %29 = OpLabel 1039fd4e5da5Sopenharmony_ci %34 = OpLoad %8 %10 1040fd4e5da5Sopenharmony_ci %39 = OpImage %7 %34 1041fd4e5da5Sopenharmony_ci %40 = OpImageFetch %31 %39 %35 Lod|ConstOffset %13 %38 1042fd4e5da5Sopenharmony_ci OpStore %33 %40 1043fd4e5da5Sopenharmony_ci OpBranch %30 1044fd4e5da5Sopenharmony_ci %41 = OpLabel 1045fd4e5da5Sopenharmony_ci %42 = OpLoad %7 %21 1046fd4e5da5Sopenharmony_ci %43 = OpImageFetch %31 %42 %35 Lod|ConstOffset %13 %38 1047fd4e5da5Sopenharmony_ci OpStore %33 %43 1048fd4e5da5Sopenharmony_ci OpBranch %30 1049fd4e5da5Sopenharmony_ci %30 = OpLabel 1050fd4e5da5Sopenharmony_ci OpReturn 1051fd4e5da5Sopenharmony_ci OpFunctionEnd 1052fd4e5da5Sopenharmony_ci %200 = OpFunction %15 None %201 1053fd4e5da5Sopenharmony_ci %202 = OpFunctionParameter %7 1054fd4e5da5Sopenharmony_ci %203 = OpFunctionParameter %12 1055fd4e5da5Sopenharmony_ci %204 = OpLabel 1056fd4e5da5Sopenharmony_ci %205 = OpImageQuerySizeLod %15 %202 %203 1057fd4e5da5Sopenharmony_ci OpReturnValue %205 1058fd4e5da5Sopenharmony_ci OpFunctionEnd 1059fd4e5da5Sopenharmony_ci )"; 1060fd4e5da5Sopenharmony_ci 1061fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 1062fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 1063fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 1064fd4e5da5Sopenharmony_ci 1065fd4e5da5Sopenharmony_ci const auto recipient_context = 1066fd4e5da5Sopenharmony_ci BuildModule(env, consumer, recipient_shader, kFuzzAssembleOption); 1067fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed( 1068fd4e5da5Sopenharmony_ci recipient_context.get(), validator_options, kConsoleMessageConsumer)); 1069fd4e5da5Sopenharmony_ci 1070fd4e5da5Sopenharmony_ci const auto donor_context = 1071fd4e5da5Sopenharmony_ci BuildModule(env, consumer, donor_shader, kFuzzAssembleOption); 1072fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed( 1073fd4e5da5Sopenharmony_ci donor_context.get(), validator_options, kConsoleMessageConsumer)); 1074fd4e5da5Sopenharmony_ci 1075fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 1076fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(recipient_context.get()), validator_options); 1077fd4e5da5Sopenharmony_ci 1078fd4e5da5Sopenharmony_ci FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100, 1079fd4e5da5Sopenharmony_ci false); 1080fd4e5da5Sopenharmony_ci protobufs::TransformationSequence transformation_sequence; 1081fd4e5da5Sopenharmony_ci 1082fd4e5da5Sopenharmony_ci FuzzerPassDonateModules fuzzer_pass(recipient_context.get(), 1083fd4e5da5Sopenharmony_ci &transformation_context, &fuzzer_context, 1084fd4e5da5Sopenharmony_ci &transformation_sequence, false, {}); 1085fd4e5da5Sopenharmony_ci 1086fd4e5da5Sopenharmony_ci fuzzer_pass.DonateSingleModule(donor_context.get(), false); 1087fd4e5da5Sopenharmony_ci 1088fd4e5da5Sopenharmony_ci // We just check that the result is valid. Checking to what it should be 1089fd4e5da5Sopenharmony_ci // exactly equal to would be very fragile. 1090fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed( 1091fd4e5da5Sopenharmony_ci recipient_context.get(), validator_options, kConsoleMessageConsumer)); 1092fd4e5da5Sopenharmony_ci} 1093fd4e5da5Sopenharmony_ci 1094fd4e5da5Sopenharmony_ciTEST(FuzzerPassDonateModulesTest, DonateShaderWithImageStorageClass) { 1095fd4e5da5Sopenharmony_ci std::string recipient_shader = R"( 1096fd4e5da5Sopenharmony_ci OpCapability Shader 1097fd4e5da5Sopenharmony_ci OpCapability ImageQuery 1098fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 1099fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1100fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 1101fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 1102fd4e5da5Sopenharmony_ci OpSource ESSL 320 1103fd4e5da5Sopenharmony_ci OpSourceExtension "GL_EXT_samplerless_texture_functions" 1104fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 1105fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 1106fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 1107fd4e5da5Sopenharmony_ci %5 = OpLabel 1108fd4e5da5Sopenharmony_ci OpReturn 1109fd4e5da5Sopenharmony_ci OpFunctionEnd 1110fd4e5da5Sopenharmony_ci )"; 1111fd4e5da5Sopenharmony_ci 1112fd4e5da5Sopenharmony_ci std::string donor_shader = R"( 1113fd4e5da5Sopenharmony_ci OpCapability Shader 1114fd4e5da5Sopenharmony_ci OpCapability SampledBuffer 1115fd4e5da5Sopenharmony_ci OpCapability ImageBuffer 1116fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 1117fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1118fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %2 "MainPSPacked" 1119fd4e5da5Sopenharmony_ci OpExecutionMode %2 OriginUpperLeft 1120fd4e5da5Sopenharmony_ci OpDecorate %18 DescriptorSet 0 1121fd4e5da5Sopenharmony_ci OpDecorate %18 Binding 128 1122fd4e5da5Sopenharmony_ci %49 = OpTypeInt 32 0 1123fd4e5da5Sopenharmony_ci %50 = OpTypeFloat 32 1124fd4e5da5Sopenharmony_ci %58 = OpConstant %50 1 1125fd4e5da5Sopenharmony_ci %66 = OpConstant %49 0 1126fd4e5da5Sopenharmony_ci %87 = OpTypeVector %50 2 1127fd4e5da5Sopenharmony_ci %88 = OpConstantComposite %87 %58 %58 1128fd4e5da5Sopenharmony_ci %17 = OpTypeImage %49 2D 2 0 0 2 R32ui 1129fd4e5da5Sopenharmony_ci %118 = OpTypePointer UniformConstant %17 1130fd4e5da5Sopenharmony_ci %123 = OpTypeVector %49 2 1131fd4e5da5Sopenharmony_ci %132 = OpTypeVoid 1132fd4e5da5Sopenharmony_ci %133 = OpTypeFunction %132 1133fd4e5da5Sopenharmony_ci %142 = OpTypePointer Image %49 1134fd4e5da5Sopenharmony_ci %18 = OpVariable %118 UniformConstant 1135fd4e5da5Sopenharmony_ci %2 = OpFunction %132 None %133 1136fd4e5da5Sopenharmony_ci %153 = OpLabel 1137fd4e5da5Sopenharmony_ci %495 = OpConvertFToU %123 %88 1138fd4e5da5Sopenharmony_ci %501 = OpImageTexelPointer %142 %18 %495 %66 1139fd4e5da5Sopenharmony_ci OpReturn 1140fd4e5da5Sopenharmony_ci OpFunctionEnd 1141fd4e5da5Sopenharmony_ci )"; 1142fd4e5da5Sopenharmony_ci 1143fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 1144fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 1145fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 1146fd4e5da5Sopenharmony_ci 1147fd4e5da5Sopenharmony_ci const auto recipient_context = 1148fd4e5da5Sopenharmony_ci BuildModule(env, consumer, recipient_shader, kFuzzAssembleOption); 1149fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed( 1150fd4e5da5Sopenharmony_ci recipient_context.get(), validator_options, kConsoleMessageConsumer)); 1151fd4e5da5Sopenharmony_ci 1152fd4e5da5Sopenharmony_ci const auto donor_context = 1153fd4e5da5Sopenharmony_ci BuildModule(env, consumer, donor_shader, kFuzzAssembleOption); 1154fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed( 1155fd4e5da5Sopenharmony_ci donor_context.get(), validator_options, kConsoleMessageConsumer)); 1156fd4e5da5Sopenharmony_ci 1157fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 1158fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(recipient_context.get()), validator_options); 1159fd4e5da5Sopenharmony_ci 1160fd4e5da5Sopenharmony_ci FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100, 1161fd4e5da5Sopenharmony_ci false); 1162fd4e5da5Sopenharmony_ci protobufs::TransformationSequence transformation_sequence; 1163fd4e5da5Sopenharmony_ci 1164fd4e5da5Sopenharmony_ci FuzzerPassDonateModules fuzzer_pass(recipient_context.get(), 1165fd4e5da5Sopenharmony_ci &transformation_context, &fuzzer_context, 1166fd4e5da5Sopenharmony_ci &transformation_sequence, false, {}); 1167fd4e5da5Sopenharmony_ci 1168fd4e5da5Sopenharmony_ci fuzzer_pass.DonateSingleModule(donor_context.get(), true); 1169fd4e5da5Sopenharmony_ci 1170fd4e5da5Sopenharmony_ci // We just check that the result is valid. Checking to what it should be 1171fd4e5da5Sopenharmony_ci // exactly equal to would be very fragile. 1172fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed( 1173fd4e5da5Sopenharmony_ci recipient_context.get(), validator_options, kConsoleMessageConsumer)); 1174fd4e5da5Sopenharmony_ci} 1175fd4e5da5Sopenharmony_ci 1176fd4e5da5Sopenharmony_ciTEST(FuzzerPassDonateModulesTest, DonateComputeShaderWithRuntimeArray) { 1177fd4e5da5Sopenharmony_ci std::string recipient_shader = R"( 1178fd4e5da5Sopenharmony_ci OpCapability Shader 1179fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 1180fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1181fd4e5da5Sopenharmony_ci OpEntryPoint GLCompute %4 "main" 1182fd4e5da5Sopenharmony_ci OpExecutionMode %4 LocalSize 1 1 1 1183fd4e5da5Sopenharmony_ci OpSource ESSL 310 1184fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 1185fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 1186fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 1187fd4e5da5Sopenharmony_ci %5 = OpLabel 1188fd4e5da5Sopenharmony_ci OpReturn 1189fd4e5da5Sopenharmony_ci OpFunctionEnd 1190fd4e5da5Sopenharmony_ci )"; 1191fd4e5da5Sopenharmony_ci 1192fd4e5da5Sopenharmony_ci std::string donor_shader = R"( 1193fd4e5da5Sopenharmony_ci OpCapability Shader 1194fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 1195fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1196fd4e5da5Sopenharmony_ci OpEntryPoint GLCompute %4 "main" 1197fd4e5da5Sopenharmony_ci OpExecutionMode %4 LocalSize 1 1 1 1198fd4e5da5Sopenharmony_ci OpSource ESSL 310 1199fd4e5da5Sopenharmony_ci OpDecorate %9 ArrayStride 4 1200fd4e5da5Sopenharmony_ci OpMemberDecorate %10 0 Offset 0 1201fd4e5da5Sopenharmony_ci OpDecorate %10 BufferBlock 1202fd4e5da5Sopenharmony_ci OpDecorate %12 DescriptorSet 0 1203fd4e5da5Sopenharmony_ci OpDecorate %12 Binding 0 1204fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 1205fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 1206fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 1207fd4e5da5Sopenharmony_ci %7 = OpTypePointer Function %6 1208fd4e5da5Sopenharmony_ci %9 = OpTypeRuntimeArray %6 1209fd4e5da5Sopenharmony_ci %10 = OpTypeStruct %9 1210fd4e5da5Sopenharmony_ci %11 = OpTypePointer Uniform %10 1211fd4e5da5Sopenharmony_ci %12 = OpVariable %11 Uniform 1212fd4e5da5Sopenharmony_ci %13 = OpTypeInt 32 0 1213fd4e5da5Sopenharmony_ci %16 = OpConstant %6 0 1214fd4e5da5Sopenharmony_ci %18 = OpConstant %6 1 1215fd4e5da5Sopenharmony_ci %20 = OpTypePointer Uniform %6 1216fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 1217fd4e5da5Sopenharmony_ci %5 = OpLabel 1218fd4e5da5Sopenharmony_ci %8 = OpVariable %7 Function 1219fd4e5da5Sopenharmony_ci %14 = OpArrayLength %13 %12 0 1220fd4e5da5Sopenharmony_ci %15 = OpBitcast %6 %14 1221fd4e5da5Sopenharmony_ci OpStore %8 %15 1222fd4e5da5Sopenharmony_ci %17 = OpLoad %6 %8 1223fd4e5da5Sopenharmony_ci %19 = OpISub %6 %17 %18 1224fd4e5da5Sopenharmony_ci %21 = OpAccessChain %20 %12 %16 %19 1225fd4e5da5Sopenharmony_ci OpStore %21 %16 1226fd4e5da5Sopenharmony_ci OpReturn 1227fd4e5da5Sopenharmony_ci OpFunctionEnd 1228fd4e5da5Sopenharmony_ci )"; 1229fd4e5da5Sopenharmony_ci 1230fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 1231fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 1232fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 1233fd4e5da5Sopenharmony_ci 1234fd4e5da5Sopenharmony_ci const auto recipient_context = 1235fd4e5da5Sopenharmony_ci BuildModule(env, consumer, recipient_shader, kFuzzAssembleOption); 1236fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed( 1237fd4e5da5Sopenharmony_ci recipient_context.get(), validator_options, kConsoleMessageConsumer)); 1238fd4e5da5Sopenharmony_ci 1239fd4e5da5Sopenharmony_ci const auto donor_context = 1240fd4e5da5Sopenharmony_ci BuildModule(env, consumer, donor_shader, kFuzzAssembleOption); 1241fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed( 1242fd4e5da5Sopenharmony_ci donor_context.get(), validator_options, kConsoleMessageConsumer)); 1243fd4e5da5Sopenharmony_ci 1244fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 1245fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(recipient_context.get()), validator_options); 1246fd4e5da5Sopenharmony_ci 1247fd4e5da5Sopenharmony_ci FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100, 1248fd4e5da5Sopenharmony_ci false); 1249fd4e5da5Sopenharmony_ci protobufs::TransformationSequence transformation_sequence; 1250fd4e5da5Sopenharmony_ci 1251fd4e5da5Sopenharmony_ci FuzzerPassDonateModules fuzzer_pass(recipient_context.get(), 1252fd4e5da5Sopenharmony_ci &transformation_context, &fuzzer_context, 1253fd4e5da5Sopenharmony_ci &transformation_sequence, false, {}); 1254fd4e5da5Sopenharmony_ci 1255fd4e5da5Sopenharmony_ci fuzzer_pass.DonateSingleModule(donor_context.get(), false); 1256fd4e5da5Sopenharmony_ci 1257fd4e5da5Sopenharmony_ci // We just check that the result is valid. Checking to what it should be 1258fd4e5da5Sopenharmony_ci // exactly equal to would be very fragile. 1259fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed( 1260fd4e5da5Sopenharmony_ci recipient_context.get(), validator_options, kConsoleMessageConsumer)); 1261fd4e5da5Sopenharmony_ci} 1262fd4e5da5Sopenharmony_ci 1263fd4e5da5Sopenharmony_ciTEST(FuzzerPassDonateModulesTest, DonateComputeShaderWithRuntimeArrayLivesafe) { 1264fd4e5da5Sopenharmony_ci std::string recipient_shader = R"( 1265fd4e5da5Sopenharmony_ci OpCapability Shader 1266fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 1267fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1268fd4e5da5Sopenharmony_ci OpEntryPoint GLCompute %4 "main" 1269fd4e5da5Sopenharmony_ci OpExecutionMode %4 LocalSize 1 1 1 1270fd4e5da5Sopenharmony_ci OpSource ESSL 310 1271fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 1272fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 1273fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 1274fd4e5da5Sopenharmony_ci %5 = OpLabel 1275fd4e5da5Sopenharmony_ci OpReturn 1276fd4e5da5Sopenharmony_ci OpFunctionEnd 1277fd4e5da5Sopenharmony_ci )"; 1278fd4e5da5Sopenharmony_ci 1279fd4e5da5Sopenharmony_ci std::string donor_shader = R"( 1280fd4e5da5Sopenharmony_ci OpCapability Shader 1281fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 1282fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1283fd4e5da5Sopenharmony_ci OpEntryPoint GLCompute %4 "main" 1284fd4e5da5Sopenharmony_ci OpExecutionMode %4 LocalSize 1 1 1 1285fd4e5da5Sopenharmony_ci OpSource ESSL 310 1286fd4e5da5Sopenharmony_ci OpDecorate %16 ArrayStride 4 1287fd4e5da5Sopenharmony_ci OpMemberDecorate %17 0 Offset 0 1288fd4e5da5Sopenharmony_ci OpDecorate %17 BufferBlock 1289fd4e5da5Sopenharmony_ci OpDecorate %19 DescriptorSet 0 1290fd4e5da5Sopenharmony_ci OpDecorate %19 Binding 0 1291fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 1292fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 1293fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 1294fd4e5da5Sopenharmony_ci %7 = OpTypePointer Function %6 1295fd4e5da5Sopenharmony_ci %9 = OpConstant %6 0 1296fd4e5da5Sopenharmony_ci %16 = OpTypeRuntimeArray %6 1297fd4e5da5Sopenharmony_ci %17 = OpTypeStruct %16 1298fd4e5da5Sopenharmony_ci %18 = OpTypePointer Uniform %17 1299fd4e5da5Sopenharmony_ci %19 = OpVariable %18 Uniform 1300fd4e5da5Sopenharmony_ci %20 = OpTypeInt 32 0 1301fd4e5da5Sopenharmony_ci %23 = OpTypeBool 1302fd4e5da5Sopenharmony_ci %26 = OpConstant %6 32 1303fd4e5da5Sopenharmony_ci %27 = OpTypePointer Uniform %6 1304fd4e5da5Sopenharmony_ci %30 = OpConstant %6 1 1305fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 1306fd4e5da5Sopenharmony_ci %5 = OpLabel 1307fd4e5da5Sopenharmony_ci %8 = OpVariable %7 Function 1308fd4e5da5Sopenharmony_ci OpStore %8 %9 1309fd4e5da5Sopenharmony_ci OpBranch %10 1310fd4e5da5Sopenharmony_ci %10 = OpLabel 1311fd4e5da5Sopenharmony_ci OpLoopMerge %12 %13 None 1312fd4e5da5Sopenharmony_ci OpBranch %14 1313fd4e5da5Sopenharmony_ci %14 = OpLabel 1314fd4e5da5Sopenharmony_ci %15 = OpLoad %6 %8 1315fd4e5da5Sopenharmony_ci %21 = OpArrayLength %20 %19 0 1316fd4e5da5Sopenharmony_ci %22 = OpBitcast %6 %21 1317fd4e5da5Sopenharmony_ci %24 = OpSLessThan %23 %15 %22 1318fd4e5da5Sopenharmony_ci OpBranchConditional %24 %11 %12 1319fd4e5da5Sopenharmony_ci %11 = OpLabel 1320fd4e5da5Sopenharmony_ci %25 = OpLoad %6 %8 1321fd4e5da5Sopenharmony_ci %28 = OpAccessChain %27 %19 %9 %25 1322fd4e5da5Sopenharmony_ci OpStore %28 %26 1323fd4e5da5Sopenharmony_ci OpBranch %13 1324fd4e5da5Sopenharmony_ci %13 = OpLabel 1325fd4e5da5Sopenharmony_ci %29 = OpLoad %6 %8 1326fd4e5da5Sopenharmony_ci %31 = OpIAdd %6 %29 %30 1327fd4e5da5Sopenharmony_ci OpStore %8 %31 1328fd4e5da5Sopenharmony_ci OpBranch %10 1329fd4e5da5Sopenharmony_ci %12 = OpLabel 1330fd4e5da5Sopenharmony_ci OpReturn 1331fd4e5da5Sopenharmony_ci OpFunctionEnd 1332fd4e5da5Sopenharmony_ci )"; 1333fd4e5da5Sopenharmony_ci 1334fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 1335fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 1336fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 1337fd4e5da5Sopenharmony_ci 1338fd4e5da5Sopenharmony_ci const auto recipient_context = 1339fd4e5da5Sopenharmony_ci BuildModule(env, consumer, recipient_shader, kFuzzAssembleOption); 1340fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed( 1341fd4e5da5Sopenharmony_ci recipient_context.get(), validator_options, kConsoleMessageConsumer)); 1342fd4e5da5Sopenharmony_ci 1343fd4e5da5Sopenharmony_ci const auto donor_context = 1344fd4e5da5Sopenharmony_ci BuildModule(env, consumer, donor_shader, kFuzzAssembleOption); 1345fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed( 1346fd4e5da5Sopenharmony_ci donor_context.get(), validator_options, kConsoleMessageConsumer)); 1347fd4e5da5Sopenharmony_ci 1348fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 1349fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(recipient_context.get()), validator_options); 1350fd4e5da5Sopenharmony_ci 1351fd4e5da5Sopenharmony_ci FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100, 1352fd4e5da5Sopenharmony_ci false); 1353fd4e5da5Sopenharmony_ci protobufs::TransformationSequence transformation_sequence; 1354fd4e5da5Sopenharmony_ci 1355fd4e5da5Sopenharmony_ci FuzzerPassDonateModules fuzzer_pass(recipient_context.get(), 1356fd4e5da5Sopenharmony_ci &transformation_context, &fuzzer_context, 1357fd4e5da5Sopenharmony_ci &transformation_sequence, false, {}); 1358fd4e5da5Sopenharmony_ci 1359fd4e5da5Sopenharmony_ci fuzzer_pass.DonateSingleModule(donor_context.get(), true); 1360fd4e5da5Sopenharmony_ci 1361fd4e5da5Sopenharmony_ci // We just check that the result is valid. Checking to what it should be 1362fd4e5da5Sopenharmony_ci // exactly equal to would be very fragile. 1363fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed( 1364fd4e5da5Sopenharmony_ci recipient_context.get(), validator_options, kConsoleMessageConsumer)); 1365fd4e5da5Sopenharmony_ci} 1366fd4e5da5Sopenharmony_ci 1367fd4e5da5Sopenharmony_ciTEST(FuzzerPassDonateModulesTest, DonateComputeShaderWithWorkgroupVariables) { 1368fd4e5da5Sopenharmony_ci std::string recipient_shader = R"( 1369fd4e5da5Sopenharmony_ci OpCapability Shader 1370fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 1371fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1372fd4e5da5Sopenharmony_ci OpEntryPoint GLCompute %4 "main" 1373fd4e5da5Sopenharmony_ci OpExecutionMode %4 LocalSize 1 1 1 1374fd4e5da5Sopenharmony_ci OpSource ESSL 310 1375fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 1376fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 1377fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 1378fd4e5da5Sopenharmony_ci %5 = OpLabel 1379fd4e5da5Sopenharmony_ci OpReturn 1380fd4e5da5Sopenharmony_ci OpFunctionEnd 1381fd4e5da5Sopenharmony_ci )"; 1382fd4e5da5Sopenharmony_ci 1383fd4e5da5Sopenharmony_ci std::string donor_shader = R"( 1384fd4e5da5Sopenharmony_ci OpCapability Shader 1385fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 1386fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1387fd4e5da5Sopenharmony_ci OpEntryPoint GLCompute %4 "main" 1388fd4e5da5Sopenharmony_ci OpExecutionMode %4 LocalSize 1 1 1 1389fd4e5da5Sopenharmony_ci OpSource ESSL 310 1390fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 1391fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 1392fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 1393fd4e5da5Sopenharmony_ci %7 = OpTypePointer Workgroup %6 1394fd4e5da5Sopenharmony_ci %8 = OpVariable %7 Workgroup 1395fd4e5da5Sopenharmony_ci %9 = OpConstant %6 2 1396fd4e5da5Sopenharmony_ci %10 = OpVariable %7 Workgroup 1397fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 1398fd4e5da5Sopenharmony_ci %5 = OpLabel 1399fd4e5da5Sopenharmony_ci OpStore %8 %9 1400fd4e5da5Sopenharmony_ci %11 = OpLoad %6 %8 1401fd4e5da5Sopenharmony_ci OpStore %10 %11 1402fd4e5da5Sopenharmony_ci OpReturn 1403fd4e5da5Sopenharmony_ci OpFunctionEnd 1404fd4e5da5Sopenharmony_ci )"; 1405fd4e5da5Sopenharmony_ci 1406fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 1407fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 1408fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 1409fd4e5da5Sopenharmony_ci 1410fd4e5da5Sopenharmony_ci const auto recipient_context = 1411fd4e5da5Sopenharmony_ci BuildModule(env, consumer, recipient_shader, kFuzzAssembleOption); 1412fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed( 1413fd4e5da5Sopenharmony_ci recipient_context.get(), validator_options, kConsoleMessageConsumer)); 1414fd4e5da5Sopenharmony_ci 1415fd4e5da5Sopenharmony_ci const auto donor_context = 1416fd4e5da5Sopenharmony_ci BuildModule(env, consumer, donor_shader, kFuzzAssembleOption); 1417fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed( 1418fd4e5da5Sopenharmony_ci donor_context.get(), validator_options, kConsoleMessageConsumer)); 1419fd4e5da5Sopenharmony_ci 1420fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 1421fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(recipient_context.get()), validator_options); 1422fd4e5da5Sopenharmony_ci 1423fd4e5da5Sopenharmony_ci FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100, 1424fd4e5da5Sopenharmony_ci false); 1425fd4e5da5Sopenharmony_ci protobufs::TransformationSequence transformation_sequence; 1426fd4e5da5Sopenharmony_ci 1427fd4e5da5Sopenharmony_ci FuzzerPassDonateModules fuzzer_pass(recipient_context.get(), 1428fd4e5da5Sopenharmony_ci &transformation_context, &fuzzer_context, 1429fd4e5da5Sopenharmony_ci &transformation_sequence, false, {}); 1430fd4e5da5Sopenharmony_ci 1431fd4e5da5Sopenharmony_ci fuzzer_pass.DonateSingleModule(donor_context.get(), true); 1432fd4e5da5Sopenharmony_ci 1433fd4e5da5Sopenharmony_ci // We just check that the result is valid. Checking to what it should be 1434fd4e5da5Sopenharmony_ci // exactly equal to would be very fragile. 1435fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed( 1436fd4e5da5Sopenharmony_ci recipient_context.get(), validator_options, kConsoleMessageConsumer)); 1437fd4e5da5Sopenharmony_ci} 1438fd4e5da5Sopenharmony_ci 1439fd4e5da5Sopenharmony_ciTEST(FuzzerPassDonateModulesTest, DonateComputeShaderWithAtomics) { 1440fd4e5da5Sopenharmony_ci std::string recipient_shader = R"( 1441fd4e5da5Sopenharmony_ci OpCapability Shader 1442fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 1443fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1444fd4e5da5Sopenharmony_ci OpEntryPoint GLCompute %4 "main" 1445fd4e5da5Sopenharmony_ci OpExecutionMode %4 LocalSize 1 1 1 1446fd4e5da5Sopenharmony_ci OpSource ESSL 310 1447fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 1448fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 1449fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 1450fd4e5da5Sopenharmony_ci %5 = OpLabel 1451fd4e5da5Sopenharmony_ci OpReturn 1452fd4e5da5Sopenharmony_ci OpFunctionEnd 1453fd4e5da5Sopenharmony_ci )"; 1454fd4e5da5Sopenharmony_ci 1455fd4e5da5Sopenharmony_ci std::string donor_shader = R"( 1456fd4e5da5Sopenharmony_ci OpCapability Shader 1457fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 1458fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1459fd4e5da5Sopenharmony_ci OpEntryPoint GLCompute %4 "main" 1460fd4e5da5Sopenharmony_ci OpExecutionMode %4 LocalSize 1 1 1 1461fd4e5da5Sopenharmony_ci OpSource ESSL 310 1462fd4e5da5Sopenharmony_ci OpMemberDecorate %9 0 Offset 0 1463fd4e5da5Sopenharmony_ci OpDecorate %9 BufferBlock 1464fd4e5da5Sopenharmony_ci OpDecorate %11 DescriptorSet 0 1465fd4e5da5Sopenharmony_ci OpDecorate %11 Binding 0 1466fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 1467fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 1468fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 0 1469fd4e5da5Sopenharmony_ci %7 = OpTypePointer Function %6 1470fd4e5da5Sopenharmony_ci %9 = OpTypeStruct %6 1471fd4e5da5Sopenharmony_ci %10 = OpTypePointer Uniform %9 1472fd4e5da5Sopenharmony_ci %11 = OpVariable %10 Uniform 1473fd4e5da5Sopenharmony_ci %12 = OpTypeInt 32 1 1474fd4e5da5Sopenharmony_ci %13 = OpConstant %12 0 1475fd4e5da5Sopenharmony_ci %14 = OpTypePointer Uniform %6 1476fd4e5da5Sopenharmony_ci %16 = OpConstant %6 1 1477fd4e5da5Sopenharmony_ci %17 = OpConstant %6 0 1478fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 1479fd4e5da5Sopenharmony_ci %5 = OpLabel 1480fd4e5da5Sopenharmony_ci %8 = OpVariable %7 Function 1481fd4e5da5Sopenharmony_ci %15 = OpAccessChain %14 %11 %13 1482fd4e5da5Sopenharmony_ci %18 = OpAtomicIAdd %6 %15 %16 %17 %16 1483fd4e5da5Sopenharmony_ci OpStore %8 %18 1484fd4e5da5Sopenharmony_ci %19 = OpAccessChain %14 %11 %13 1485fd4e5da5Sopenharmony_ci %20 = OpLoad %6 %8 1486fd4e5da5Sopenharmony_ci %21 = OpAtomicUMin %6 %19 %16 %17 %20 1487fd4e5da5Sopenharmony_ci OpStore %8 %21 1488fd4e5da5Sopenharmony_ci %22 = OpAccessChain %14 %11 %13 1489fd4e5da5Sopenharmony_ci %23 = OpLoad %6 %8 1490fd4e5da5Sopenharmony_ci %24 = OpAtomicUMax %6 %22 %16 %17 %23 1491fd4e5da5Sopenharmony_ci OpStore %8 %24 1492fd4e5da5Sopenharmony_ci %25 = OpAccessChain %14 %11 %13 1493fd4e5da5Sopenharmony_ci %26 = OpLoad %6 %8 1494fd4e5da5Sopenharmony_ci %27 = OpAtomicAnd %6 %25 %16 %17 %26 1495fd4e5da5Sopenharmony_ci OpStore %8 %27 1496fd4e5da5Sopenharmony_ci %28 = OpAccessChain %14 %11 %13 1497fd4e5da5Sopenharmony_ci %29 = OpLoad %6 %8 1498fd4e5da5Sopenharmony_ci %30 = OpAtomicOr %6 %28 %16 %17 %29 1499fd4e5da5Sopenharmony_ci OpStore %8 %30 1500fd4e5da5Sopenharmony_ci %31 = OpAccessChain %14 %11 %13 1501fd4e5da5Sopenharmony_ci %32 = OpLoad %6 %8 1502fd4e5da5Sopenharmony_ci %33 = OpAtomicXor %6 %31 %16 %17 %32 1503fd4e5da5Sopenharmony_ci OpStore %8 %33 1504fd4e5da5Sopenharmony_ci %34 = OpAccessChain %14 %11 %13 1505fd4e5da5Sopenharmony_ci %35 = OpLoad %6 %8 1506fd4e5da5Sopenharmony_ci %36 = OpAtomicExchange %6 %34 %16 %17 %35 1507fd4e5da5Sopenharmony_ci OpStore %8 %36 1508fd4e5da5Sopenharmony_ci %37 = OpAccessChain %14 %11 %13 1509fd4e5da5Sopenharmony_ci %38 = OpLoad %6 %8 1510fd4e5da5Sopenharmony_ci %39 = OpAtomicCompareExchange %6 %37 %16 %17 %17 %16 %38 1511fd4e5da5Sopenharmony_ci OpStore %8 %39 1512fd4e5da5Sopenharmony_ci OpReturn 1513fd4e5da5Sopenharmony_ci OpFunctionEnd 1514fd4e5da5Sopenharmony_ci )"; 1515fd4e5da5Sopenharmony_ci 1516fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 1517fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 1518fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 1519fd4e5da5Sopenharmony_ci 1520fd4e5da5Sopenharmony_ci const auto recipient_context = 1521fd4e5da5Sopenharmony_ci BuildModule(env, consumer, recipient_shader, kFuzzAssembleOption); 1522fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed( 1523fd4e5da5Sopenharmony_ci recipient_context.get(), validator_options, kConsoleMessageConsumer)); 1524fd4e5da5Sopenharmony_ci 1525fd4e5da5Sopenharmony_ci const auto donor_context = 1526fd4e5da5Sopenharmony_ci BuildModule(env, consumer, donor_shader, kFuzzAssembleOption); 1527fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed( 1528fd4e5da5Sopenharmony_ci donor_context.get(), validator_options, kConsoleMessageConsumer)); 1529fd4e5da5Sopenharmony_ci 1530fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 1531fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(recipient_context.get()), validator_options); 1532fd4e5da5Sopenharmony_ci 1533fd4e5da5Sopenharmony_ci FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100, 1534fd4e5da5Sopenharmony_ci false); 1535fd4e5da5Sopenharmony_ci protobufs::TransformationSequence transformation_sequence; 1536fd4e5da5Sopenharmony_ci 1537fd4e5da5Sopenharmony_ci FuzzerPassDonateModules fuzzer_pass(recipient_context.get(), 1538fd4e5da5Sopenharmony_ci &transformation_context, &fuzzer_context, 1539fd4e5da5Sopenharmony_ci &transformation_sequence, false, {}); 1540fd4e5da5Sopenharmony_ci 1541fd4e5da5Sopenharmony_ci fuzzer_pass.DonateSingleModule(donor_context.get(), true); 1542fd4e5da5Sopenharmony_ci 1543fd4e5da5Sopenharmony_ci // We just check that the result is valid. Checking to what it should be 1544fd4e5da5Sopenharmony_ci // exactly equal to would be very fragile. 1545fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed( 1546fd4e5da5Sopenharmony_ci recipient_context.get(), validator_options, kConsoleMessageConsumer)); 1547fd4e5da5Sopenharmony_ci} 1548fd4e5da5Sopenharmony_ci 1549fd4e5da5Sopenharmony_ciTEST(FuzzerPassDonateModulesTest, Miscellaneous1) { 1550fd4e5da5Sopenharmony_ci std::string recipient_shader = R"( 1551fd4e5da5Sopenharmony_ci OpCapability Shader 1552fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 1553fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1554fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 1555fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 1556fd4e5da5Sopenharmony_ci OpSource ESSL 310 1557fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 1558fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 1559fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 1560fd4e5da5Sopenharmony_ci %5 = OpLabel 1561fd4e5da5Sopenharmony_ci OpReturn 1562fd4e5da5Sopenharmony_ci OpFunctionEnd 1563fd4e5da5Sopenharmony_ci )"; 1564fd4e5da5Sopenharmony_ci 1565fd4e5da5Sopenharmony_ci std::string donor_shader = R"( 1566fd4e5da5Sopenharmony_ci OpCapability Shader 1567fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 1568fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1569fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 1570fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 1571fd4e5da5Sopenharmony_ci OpSource ESSL 310 1572fd4e5da5Sopenharmony_ci OpName %4 "main" 1573fd4e5da5Sopenharmony_ci OpName %6 "foo(" 1574fd4e5da5Sopenharmony_ci OpName %10 "x" 1575fd4e5da5Sopenharmony_ci OpName %12 "i" 1576fd4e5da5Sopenharmony_ci OpName %33 "i" 1577fd4e5da5Sopenharmony_ci OpName %42 "j" 1578fd4e5da5Sopenharmony_ci OpDecorate %10 RelaxedPrecision 1579fd4e5da5Sopenharmony_ci OpDecorate %12 RelaxedPrecision 1580fd4e5da5Sopenharmony_ci OpDecorate %19 RelaxedPrecision 1581fd4e5da5Sopenharmony_ci OpDecorate %23 RelaxedPrecision 1582fd4e5da5Sopenharmony_ci OpDecorate %24 RelaxedPrecision 1583fd4e5da5Sopenharmony_ci OpDecorate %25 RelaxedPrecision 1584fd4e5da5Sopenharmony_ci OpDecorate %26 RelaxedPrecision 1585fd4e5da5Sopenharmony_ci OpDecorate %27 RelaxedPrecision 1586fd4e5da5Sopenharmony_ci OpDecorate %28 RelaxedPrecision 1587fd4e5da5Sopenharmony_ci OpDecorate %30 RelaxedPrecision 1588fd4e5da5Sopenharmony_ci OpDecorate %33 RelaxedPrecision 1589fd4e5da5Sopenharmony_ci OpDecorate %39 RelaxedPrecision 1590fd4e5da5Sopenharmony_ci OpDecorate %42 RelaxedPrecision 1591fd4e5da5Sopenharmony_ci OpDecorate %49 RelaxedPrecision 1592fd4e5da5Sopenharmony_ci OpDecorate %52 RelaxedPrecision 1593fd4e5da5Sopenharmony_ci OpDecorate %53 RelaxedPrecision 1594fd4e5da5Sopenharmony_ci OpDecorate %58 RelaxedPrecision 1595fd4e5da5Sopenharmony_ci OpDecorate %59 RelaxedPrecision 1596fd4e5da5Sopenharmony_ci OpDecorate %60 RelaxedPrecision 1597fd4e5da5Sopenharmony_ci OpDecorate %63 RelaxedPrecision 1598fd4e5da5Sopenharmony_ci OpDecorate %64 RelaxedPrecision 1599fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 1600fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 1601fd4e5da5Sopenharmony_ci %8 = OpTypeInt 32 1 1602fd4e5da5Sopenharmony_ci %9 = OpTypePointer Function %8 1603fd4e5da5Sopenharmony_ci %11 = OpConstant %8 2 1604fd4e5da5Sopenharmony_ci %13 = OpConstant %8 0 1605fd4e5da5Sopenharmony_ci %20 = OpConstant %8 100 1606fd4e5da5Sopenharmony_ci %21 = OpTypeBool 1607fd4e5da5Sopenharmony_ci %29 = OpConstant %8 1 1608fd4e5da5Sopenharmony_ci %40 = OpConstant %8 10 1609fd4e5da5Sopenharmony_ci %43 = OpConstant %8 20 1610fd4e5da5Sopenharmony_ci %61 = OpConstant %8 4 1611fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 1612fd4e5da5Sopenharmony_ci %5 = OpLabel 1613fd4e5da5Sopenharmony_ci %33 = OpVariable %9 Function 1614fd4e5da5Sopenharmony_ci %42 = OpVariable %9 Function 1615fd4e5da5Sopenharmony_ci %32 = OpFunctionCall %2 %6 1616fd4e5da5Sopenharmony_ci OpStore %33 %13 1617fd4e5da5Sopenharmony_ci OpBranch %34 1618fd4e5da5Sopenharmony_ci %34 = OpLabel 1619fd4e5da5Sopenharmony_ci OpLoopMerge %36 %37 None 1620fd4e5da5Sopenharmony_ci OpBranch %38 1621fd4e5da5Sopenharmony_ci %38 = OpLabel 1622fd4e5da5Sopenharmony_ci %39 = OpLoad %8 %33 1623fd4e5da5Sopenharmony_ci %41 = OpSLessThan %21 %39 %40 1624fd4e5da5Sopenharmony_ci OpBranchConditional %41 %35 %36 1625fd4e5da5Sopenharmony_ci %35 = OpLabel 1626fd4e5da5Sopenharmony_ci OpStore %42 %43 1627fd4e5da5Sopenharmony_ci OpBranch %44 1628fd4e5da5Sopenharmony_ci %44 = OpLabel 1629fd4e5da5Sopenharmony_ci OpLoopMerge %46 %47 None 1630fd4e5da5Sopenharmony_ci OpBranch %48 1631fd4e5da5Sopenharmony_ci %48 = OpLabel 1632fd4e5da5Sopenharmony_ci %49 = OpLoad %8 %42 1633fd4e5da5Sopenharmony_ci %50 = OpSGreaterThan %21 %49 %13 1634fd4e5da5Sopenharmony_ci OpBranchConditional %50 %45 %46 1635fd4e5da5Sopenharmony_ci %45 = OpLabel 1636fd4e5da5Sopenharmony_ci %51 = OpFunctionCall %2 %6 1637fd4e5da5Sopenharmony_ci %52 = OpLoad %8 %42 1638fd4e5da5Sopenharmony_ci %53 = OpISub %8 %52 %29 1639fd4e5da5Sopenharmony_ci OpStore %42 %53 1640fd4e5da5Sopenharmony_ci OpBranch %47 1641fd4e5da5Sopenharmony_ci %47 = OpLabel 1642fd4e5da5Sopenharmony_ci OpBranch %44 1643fd4e5da5Sopenharmony_ci %46 = OpLabel 1644fd4e5da5Sopenharmony_ci OpBranch %54 1645fd4e5da5Sopenharmony_ci %54 = OpLabel 1646fd4e5da5Sopenharmony_ci OpLoopMerge %56 %57 None 1647fd4e5da5Sopenharmony_ci OpBranch %55 1648fd4e5da5Sopenharmony_ci %55 = OpLabel 1649fd4e5da5Sopenharmony_ci %58 = OpLoad %8 %33 1650fd4e5da5Sopenharmony_ci %59 = OpIAdd %8 %58 %29 1651fd4e5da5Sopenharmony_ci OpStore %33 %59 1652fd4e5da5Sopenharmony_ci OpBranch %57 1653fd4e5da5Sopenharmony_ci %57 = OpLabel 1654fd4e5da5Sopenharmony_ci %60 = OpLoad %8 %33 1655fd4e5da5Sopenharmony_ci %62 = OpSLessThan %21 %60 %61 1656fd4e5da5Sopenharmony_ci OpBranchConditional %62 %54 %56 1657fd4e5da5Sopenharmony_ci %56 = OpLabel 1658fd4e5da5Sopenharmony_ci OpBranch %37 1659fd4e5da5Sopenharmony_ci %37 = OpLabel 1660fd4e5da5Sopenharmony_ci %63 = OpLoad %8 %33 1661fd4e5da5Sopenharmony_ci %64 = OpIAdd %8 %63 %29 1662fd4e5da5Sopenharmony_ci OpStore %33 %64 1663fd4e5da5Sopenharmony_ci OpBranch %34 1664fd4e5da5Sopenharmony_ci %36 = OpLabel 1665fd4e5da5Sopenharmony_ci OpReturn 1666fd4e5da5Sopenharmony_ci OpFunctionEnd 1667fd4e5da5Sopenharmony_ci %6 = OpFunction %2 None %3 1668fd4e5da5Sopenharmony_ci %7 = OpLabel 1669fd4e5da5Sopenharmony_ci %10 = OpVariable %9 Function 1670fd4e5da5Sopenharmony_ci %12 = OpVariable %9 Function 1671fd4e5da5Sopenharmony_ci OpStore %10 %11 1672fd4e5da5Sopenharmony_ci OpStore %12 %13 1673fd4e5da5Sopenharmony_ci OpBranch %14 1674fd4e5da5Sopenharmony_ci %14 = OpLabel 1675fd4e5da5Sopenharmony_ci OpLoopMerge %16 %17 None 1676fd4e5da5Sopenharmony_ci OpBranch %18 1677fd4e5da5Sopenharmony_ci %18 = OpLabel 1678fd4e5da5Sopenharmony_ci %19 = OpLoad %8 %12 1679fd4e5da5Sopenharmony_ci %22 = OpSLessThan %21 %19 %20 1680fd4e5da5Sopenharmony_ci OpBranchConditional %22 %15 %16 1681fd4e5da5Sopenharmony_ci %15 = OpLabel 1682fd4e5da5Sopenharmony_ci %23 = OpLoad %8 %12 1683fd4e5da5Sopenharmony_ci %24 = OpLoad %8 %10 1684fd4e5da5Sopenharmony_ci %25 = OpIAdd %8 %24 %23 1685fd4e5da5Sopenharmony_ci OpStore %10 %25 1686fd4e5da5Sopenharmony_ci %26 = OpLoad %8 %10 1687fd4e5da5Sopenharmony_ci %27 = OpIMul %8 %26 %11 1688fd4e5da5Sopenharmony_ci OpStore %10 %27 1689fd4e5da5Sopenharmony_ci OpBranch %17 1690fd4e5da5Sopenharmony_ci %17 = OpLabel 1691fd4e5da5Sopenharmony_ci %28 = OpLoad %8 %12 1692fd4e5da5Sopenharmony_ci %30 = OpIAdd %8 %28 %29 1693fd4e5da5Sopenharmony_ci OpStore %12 %30 1694fd4e5da5Sopenharmony_ci OpBranch %14 1695fd4e5da5Sopenharmony_ci %16 = OpLabel 1696fd4e5da5Sopenharmony_ci OpReturn 1697fd4e5da5Sopenharmony_ci OpFunctionEnd 1698fd4e5da5Sopenharmony_ci )"; 1699fd4e5da5Sopenharmony_ci 1700fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_5; 1701fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 1702fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 1703fd4e5da5Sopenharmony_ci 1704fd4e5da5Sopenharmony_ci const auto recipient_context = 1705fd4e5da5Sopenharmony_ci BuildModule(env, consumer, recipient_shader, kFuzzAssembleOption); 1706fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed( 1707fd4e5da5Sopenharmony_ci recipient_context.get(), validator_options, kConsoleMessageConsumer)); 1708fd4e5da5Sopenharmony_ci 1709fd4e5da5Sopenharmony_ci const auto donor_context = 1710fd4e5da5Sopenharmony_ci BuildModule(env, consumer, donor_shader, kFuzzAssembleOption); 1711fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed( 1712fd4e5da5Sopenharmony_ci donor_context.get(), validator_options, kConsoleMessageConsumer)); 1713fd4e5da5Sopenharmony_ci 1714fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 1715fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(recipient_context.get()), validator_options); 1716fd4e5da5Sopenharmony_ci 1717fd4e5da5Sopenharmony_ci FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100, 1718fd4e5da5Sopenharmony_ci false); 1719fd4e5da5Sopenharmony_ci protobufs::TransformationSequence transformation_sequence; 1720fd4e5da5Sopenharmony_ci 1721fd4e5da5Sopenharmony_ci FuzzerPassDonateModules fuzzer_pass(recipient_context.get(), 1722fd4e5da5Sopenharmony_ci &transformation_context, &fuzzer_context, 1723fd4e5da5Sopenharmony_ci &transformation_sequence, false, {}); 1724fd4e5da5Sopenharmony_ci 1725fd4e5da5Sopenharmony_ci fuzzer_pass.DonateSingleModule(donor_context.get(), false); 1726fd4e5da5Sopenharmony_ci 1727fd4e5da5Sopenharmony_ci // We just check that the result is valid. Checking to what it should be 1728fd4e5da5Sopenharmony_ci // exactly equal to would be very fragile. 1729fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed( 1730fd4e5da5Sopenharmony_ci recipient_context.get(), validator_options, kConsoleMessageConsumer)); 1731fd4e5da5Sopenharmony_ci} 1732fd4e5da5Sopenharmony_ci 1733fd4e5da5Sopenharmony_ciTEST(FuzzerPassDonateModulesTest, OpSpecConstantInstructions) { 1734fd4e5da5Sopenharmony_ci std::string donor_shader = R"( 1735fd4e5da5Sopenharmony_ci OpCapability Shader 1736fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 1737fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1738fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 1739fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 1740fd4e5da5Sopenharmony_ci OpSource ESSL 310 1741fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 1742fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 1743fd4e5da5Sopenharmony_ci %6 = OpTypeBool 1744fd4e5da5Sopenharmony_ci %7 = OpTypeInt 32 1 1745fd4e5da5Sopenharmony_ci %8 = OpTypeStruct %6 %6 %7 1746fd4e5da5Sopenharmony_ci %9 = OpSpecConstantTrue %6 1747fd4e5da5Sopenharmony_ci %10 = OpSpecConstantFalse %6 1748fd4e5da5Sopenharmony_ci %11 = OpSpecConstant %7 2 1749fd4e5da5Sopenharmony_ci %12 = OpSpecConstantComposite %8 %9 %10 %11 1750fd4e5da5Sopenharmony_ci %13 = OpSpecConstantOp %6 LogicalEqual %9 %10 1751fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 1752fd4e5da5Sopenharmony_ci %5 = OpLabel 1753fd4e5da5Sopenharmony_ci OpReturn 1754fd4e5da5Sopenharmony_ci OpFunctionEnd 1755fd4e5da5Sopenharmony_ci )"; 1756fd4e5da5Sopenharmony_ci 1757fd4e5da5Sopenharmony_ci std::string recipient_shader = R"( 1758fd4e5da5Sopenharmony_ci OpCapability Shader 1759fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 1760fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1761fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 1762fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 1763fd4e5da5Sopenharmony_ci OpSource ESSL 310 1764fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 1765fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 1766fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 1767fd4e5da5Sopenharmony_ci %5 = OpLabel 1768fd4e5da5Sopenharmony_ci OpReturn 1769fd4e5da5Sopenharmony_ci OpFunctionEnd 1770fd4e5da5Sopenharmony_ci )"; 1771fd4e5da5Sopenharmony_ci 1772fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 1773fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 1774fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 1775fd4e5da5Sopenharmony_ci 1776fd4e5da5Sopenharmony_ci const auto recipient_context = 1777fd4e5da5Sopenharmony_ci BuildModule(env, consumer, recipient_shader, kFuzzAssembleOption); 1778fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed( 1779fd4e5da5Sopenharmony_ci recipient_context.get(), validator_options, kConsoleMessageConsumer)); 1780fd4e5da5Sopenharmony_ci 1781fd4e5da5Sopenharmony_ci const auto donor_context = 1782fd4e5da5Sopenharmony_ci BuildModule(env, consumer, donor_shader, kFuzzAssembleOption); 1783fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed( 1784fd4e5da5Sopenharmony_ci donor_context.get(), validator_options, kConsoleMessageConsumer)); 1785fd4e5da5Sopenharmony_ci 1786fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 1787fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(recipient_context.get()), validator_options); 1788fd4e5da5Sopenharmony_ci 1789fd4e5da5Sopenharmony_ci FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100, 1790fd4e5da5Sopenharmony_ci false); 1791fd4e5da5Sopenharmony_ci protobufs::TransformationSequence transformation_sequence; 1792fd4e5da5Sopenharmony_ci 1793fd4e5da5Sopenharmony_ci FuzzerPassDonateModules fuzzer_pass(recipient_context.get(), 1794fd4e5da5Sopenharmony_ci &transformation_context, &fuzzer_context, 1795fd4e5da5Sopenharmony_ci &transformation_sequence, false, {}); 1796fd4e5da5Sopenharmony_ci 1797fd4e5da5Sopenharmony_ci fuzzer_pass.DonateSingleModule(donor_context.get(), false); 1798fd4e5da5Sopenharmony_ci 1799fd4e5da5Sopenharmony_ci // Check that the module is valid first. 1800fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed( 1801fd4e5da5Sopenharmony_ci recipient_context.get(), validator_options, kConsoleMessageConsumer)); 1802fd4e5da5Sopenharmony_ci 1803fd4e5da5Sopenharmony_ci std::string expected_shader = R"( 1804fd4e5da5Sopenharmony_ci OpCapability Shader 1805fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 1806fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1807fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 1808fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 1809fd4e5da5Sopenharmony_ci OpSource ESSL 310 1810fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 1811fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 1812fd4e5da5Sopenharmony_ci %100 = OpTypeBool 1813fd4e5da5Sopenharmony_ci %101 = OpTypeInt 32 1 1814fd4e5da5Sopenharmony_ci %102 = OpTypeStruct %100 %100 %101 1815fd4e5da5Sopenharmony_ci %103 = OpConstantTrue %100 1816fd4e5da5Sopenharmony_ci %104 = OpConstantFalse %100 1817fd4e5da5Sopenharmony_ci %105 = OpConstant %101 2 1818fd4e5da5Sopenharmony_ci %106 = OpConstantComposite %102 %103 %104 %105 1819fd4e5da5Sopenharmony_ci %107 = OpSpecConstantOp %100 LogicalEqual %103 %104 1820fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 1821fd4e5da5Sopenharmony_ci %5 = OpLabel 1822fd4e5da5Sopenharmony_ci OpReturn 1823fd4e5da5Sopenharmony_ci OpFunctionEnd 1824fd4e5da5Sopenharmony_ci %108 = OpFunction %2 None %3 1825fd4e5da5Sopenharmony_ci %109 = OpLabel 1826fd4e5da5Sopenharmony_ci OpReturn 1827fd4e5da5Sopenharmony_ci OpFunctionEnd 1828fd4e5da5Sopenharmony_ci )"; 1829fd4e5da5Sopenharmony_ci 1830fd4e5da5Sopenharmony_ci // Now check that the transformation has produced the expected result. 1831fd4e5da5Sopenharmony_ci ASSERT_TRUE(IsEqual(env, expected_shader, recipient_context.get())); 1832fd4e5da5Sopenharmony_ci} 1833fd4e5da5Sopenharmony_ci 1834fd4e5da5Sopenharmony_ciTEST(FuzzerPassDonateModulesTest, DonationSupportsOpTypeRuntimeArray) { 1835fd4e5da5Sopenharmony_ci std::string donor_shader = R"( 1836fd4e5da5Sopenharmony_ci OpCapability Shader 1837fd4e5da5Sopenharmony_ci OpExtension "SPV_KHR_storage_buffer_storage_class" 1838fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1839fd4e5da5Sopenharmony_ci OpEntryPoint GLCompute %29 "kernel_1" 1840fd4e5da5Sopenharmony_ci OpEntryPoint GLCompute %37 "kernel_2" 1841fd4e5da5Sopenharmony_ci OpSource OpenCL_C 120 1842fd4e5da5Sopenharmony_ci OpDecorate %2 ArrayStride 4 1843fd4e5da5Sopenharmony_ci OpMemberDecorate %3 0 Offset 0 1844fd4e5da5Sopenharmony_ci OpDecorate %3 Block 1845fd4e5da5Sopenharmony_ci OpMemberDecorate %5 0 Offset 0 1846fd4e5da5Sopenharmony_ci OpMemberDecorate %6 0 Offset 0 1847fd4e5da5Sopenharmony_ci OpDecorate %6 Block 1848fd4e5da5Sopenharmony_ci OpDecorate %21 BuiltIn WorkgroupSize 1849fd4e5da5Sopenharmony_ci OpDecorate %23 DescriptorSet 0 1850fd4e5da5Sopenharmony_ci OpDecorate %23 Binding 0 1851fd4e5da5Sopenharmony_ci OpDecorate %25 SpecId 3 1852fd4e5da5Sopenharmony_ci OpDecorate %18 SpecId 0 1853fd4e5da5Sopenharmony_ci OpDecorate %19 SpecId 1 1854fd4e5da5Sopenharmony_ci OpDecorate %20 SpecId 2 1855fd4e5da5Sopenharmony_ci %1 = OpTypeInt 32 0 1856fd4e5da5Sopenharmony_ci %2 = OpTypeRuntimeArray %1 1857fd4e5da5Sopenharmony_ci %3 = OpTypeStruct %2 1858fd4e5da5Sopenharmony_ci %4 = OpTypePointer StorageBuffer %3 1859fd4e5da5Sopenharmony_ci %5 = OpTypeStruct %1 1860fd4e5da5Sopenharmony_ci %6 = OpTypeStruct %5 1861fd4e5da5Sopenharmony_ci %7 = OpTypePointer PushConstant %6 1862fd4e5da5Sopenharmony_ci %8 = OpTypeFloat 32 1863fd4e5da5Sopenharmony_ci %9 = OpTypeVoid 1864fd4e5da5Sopenharmony_ci %10 = OpTypeFunction %9 1865fd4e5da5Sopenharmony_ci %11 = OpTypePointer Workgroup %1 1866fd4e5da5Sopenharmony_ci %12 = OpTypePointer PushConstant %5 1867fd4e5da5Sopenharmony_ci %13 = OpTypePointer StorageBuffer %1 1868fd4e5da5Sopenharmony_ci %14 = OpTypeFunction %1 %1 1869fd4e5da5Sopenharmony_ci %15 = OpTypeVector %1 3 1870fd4e5da5Sopenharmony_ci %16 = OpTypePointer Private %15 1871fd4e5da5Sopenharmony_ci %17 = OpConstant %1 0 1872fd4e5da5Sopenharmony_ci %18 = OpSpecConstant %1 1 1873fd4e5da5Sopenharmony_ci %19 = OpSpecConstant %1 1 1874fd4e5da5Sopenharmony_ci %20 = OpSpecConstant %1 1 1875fd4e5da5Sopenharmony_ci %21 = OpSpecConstantComposite %15 %18 %19 %20 1876fd4e5da5Sopenharmony_ci %25 = OpSpecConstant %1 1 1877fd4e5da5Sopenharmony_ci %26 = OpTypeArray %1 %25 1878fd4e5da5Sopenharmony_ci %27 = OpTypePointer Workgroup %26 1879fd4e5da5Sopenharmony_ci %22 = OpVariable %16 Private %21 1880fd4e5da5Sopenharmony_ci %23 = OpVariable %4 StorageBuffer 1881fd4e5da5Sopenharmony_ci %24 = OpVariable %7 PushConstant 1882fd4e5da5Sopenharmony_ci %28 = OpVariable %27 Workgroup 1883fd4e5da5Sopenharmony_ci %29 = OpFunction %9 None %10 1884fd4e5da5Sopenharmony_ci %30 = OpLabel 1885fd4e5da5Sopenharmony_ci %31 = OpAccessChain %11 %28 %17 1886fd4e5da5Sopenharmony_ci %32 = OpAccessChain %12 %24 %17 1887fd4e5da5Sopenharmony_ci %33 = OpLoad %5 %32 1888fd4e5da5Sopenharmony_ci %34 = OpCompositeExtract %1 %33 0 1889fd4e5da5Sopenharmony_ci %35 = OpFunctionCall %1 %45 %34 1890fd4e5da5Sopenharmony_ci %36 = OpAccessChain %13 %23 %17 %34 1891fd4e5da5Sopenharmony_ci OpStore %36 %35 1892fd4e5da5Sopenharmony_ci OpReturn 1893fd4e5da5Sopenharmony_ci OpFunctionEnd 1894fd4e5da5Sopenharmony_ci %37 = OpFunction %9 None %10 1895fd4e5da5Sopenharmony_ci %38 = OpLabel 1896fd4e5da5Sopenharmony_ci %39 = OpAccessChain %11 %28 %17 1897fd4e5da5Sopenharmony_ci %40 = OpAccessChain %12 %24 %17 1898fd4e5da5Sopenharmony_ci %41 = OpLoad %5 %40 1899fd4e5da5Sopenharmony_ci %42 = OpCompositeExtract %1 %41 0 1900fd4e5da5Sopenharmony_ci %43 = OpFunctionCall %1 %45 %42 1901fd4e5da5Sopenharmony_ci %44 = OpAccessChain %13 %23 %17 %42 1902fd4e5da5Sopenharmony_ci OpStore %44 %43 1903fd4e5da5Sopenharmony_ci OpReturn 1904fd4e5da5Sopenharmony_ci OpFunctionEnd 1905fd4e5da5Sopenharmony_ci %45 = OpFunction %1 Pure %14 1906fd4e5da5Sopenharmony_ci %46 = OpFunctionParameter %1 1907fd4e5da5Sopenharmony_ci %47 = OpLabel 1908fd4e5da5Sopenharmony_ci %48 = OpAccessChain %11 %28 %46 1909fd4e5da5Sopenharmony_ci %49 = OpLoad %1 %48 1910fd4e5da5Sopenharmony_ci OpReturnValue %49 1911fd4e5da5Sopenharmony_ci OpFunctionEnd 1912fd4e5da5Sopenharmony_ci )"; 1913fd4e5da5Sopenharmony_ci 1914fd4e5da5Sopenharmony_ci std::string recipient_shader = R"( 1915fd4e5da5Sopenharmony_ci OpCapability Shader 1916fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 1917fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1918fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 1919fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 1920fd4e5da5Sopenharmony_ci OpSource ESSL 310 1921fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 1922fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 1923fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 1924fd4e5da5Sopenharmony_ci %5 = OpLabel 1925fd4e5da5Sopenharmony_ci OpReturn 1926fd4e5da5Sopenharmony_ci OpFunctionEnd 1927fd4e5da5Sopenharmony_ci )"; 1928fd4e5da5Sopenharmony_ci 1929fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_0; 1930fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 1931fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 1932fd4e5da5Sopenharmony_ci 1933fd4e5da5Sopenharmony_ci const auto recipient_context = 1934fd4e5da5Sopenharmony_ci BuildModule(env, consumer, recipient_shader, kFuzzAssembleOption); 1935fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed( 1936fd4e5da5Sopenharmony_ci recipient_context.get(), validator_options, kConsoleMessageConsumer)); 1937fd4e5da5Sopenharmony_ci 1938fd4e5da5Sopenharmony_ci const auto donor_context = 1939fd4e5da5Sopenharmony_ci BuildModule(env, consumer, donor_shader, kFuzzAssembleOption); 1940fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed( 1941fd4e5da5Sopenharmony_ci donor_context.get(), validator_options, kConsoleMessageConsumer)); 1942fd4e5da5Sopenharmony_ci 1943fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 1944fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(recipient_context.get()), validator_options); 1945fd4e5da5Sopenharmony_ci 1946fd4e5da5Sopenharmony_ci FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100, 1947fd4e5da5Sopenharmony_ci false); 1948fd4e5da5Sopenharmony_ci protobufs::TransformationSequence transformation_sequence; 1949fd4e5da5Sopenharmony_ci 1950fd4e5da5Sopenharmony_ci FuzzerPassDonateModules fuzzer_pass(recipient_context.get(), 1951fd4e5da5Sopenharmony_ci &transformation_context, &fuzzer_context, 1952fd4e5da5Sopenharmony_ci &transformation_sequence, false, {}); 1953fd4e5da5Sopenharmony_ci 1954fd4e5da5Sopenharmony_ci fuzzer_pass.DonateSingleModule(donor_context.get(), false); 1955fd4e5da5Sopenharmony_ci 1956fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed( 1957fd4e5da5Sopenharmony_ci recipient_context.get(), validator_options, kConsoleMessageConsumer)); 1958fd4e5da5Sopenharmony_ci} 1959fd4e5da5Sopenharmony_ci 1960fd4e5da5Sopenharmony_ciTEST(FuzzerPassDonateModulesTest, HandlesCapabilities) { 1961fd4e5da5Sopenharmony_ci std::string donor_shader = R"( 1962fd4e5da5Sopenharmony_ci OpCapability VariablePointersStorageBuffer 1963fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 1964fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1965fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 1966fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 1967fd4e5da5Sopenharmony_ci OpSource ESSL 310 1968fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 1969fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 1970fd4e5da5Sopenharmony_ci %6 = OpTypeFloat 32 1971fd4e5da5Sopenharmony_ci %11 = OpConstant %6 23 1972fd4e5da5Sopenharmony_ci %7 = OpTypePointer Function %6 1973fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 1974fd4e5da5Sopenharmony_ci 1975fd4e5da5Sopenharmony_ci %5 = OpLabel 1976fd4e5da5Sopenharmony_ci %8 = OpVariable %7 Function 1977fd4e5da5Sopenharmony_ci OpBranch %9 1978fd4e5da5Sopenharmony_ci 1979fd4e5da5Sopenharmony_ci %9 = OpLabel 1980fd4e5da5Sopenharmony_ci %10 = OpPhi %7 %8 %5 1981fd4e5da5Sopenharmony_ci OpStore %10 %11 1982fd4e5da5Sopenharmony_ci OpReturn 1983fd4e5da5Sopenharmony_ci 1984fd4e5da5Sopenharmony_ci OpFunctionEnd 1985fd4e5da5Sopenharmony_ci )"; 1986fd4e5da5Sopenharmony_ci 1987fd4e5da5Sopenharmony_ci std::string recipient_shader = R"( 1988fd4e5da5Sopenharmony_ci OpCapability Shader 1989fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 1990fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1991fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 1992fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 1993fd4e5da5Sopenharmony_ci OpSource ESSL 310 1994fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 1995fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 1996fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 1997fd4e5da5Sopenharmony_ci %5 = OpLabel 1998fd4e5da5Sopenharmony_ci OpReturn 1999fd4e5da5Sopenharmony_ci OpFunctionEnd 2000fd4e5da5Sopenharmony_ci )"; 2001fd4e5da5Sopenharmony_ci 2002fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 2003fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 2004fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 2005fd4e5da5Sopenharmony_ci 2006fd4e5da5Sopenharmony_ci const auto recipient_context = 2007fd4e5da5Sopenharmony_ci BuildModule(env, consumer, recipient_shader, kFuzzAssembleOption); 2008fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed( 2009fd4e5da5Sopenharmony_ci recipient_context.get(), validator_options, kConsoleMessageConsumer)); 2010fd4e5da5Sopenharmony_ci 2011fd4e5da5Sopenharmony_ci const auto donor_context = 2012fd4e5da5Sopenharmony_ci BuildModule(env, consumer, donor_shader, kFuzzAssembleOption); 2013fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed( 2014fd4e5da5Sopenharmony_ci donor_context.get(), validator_options, kConsoleMessageConsumer)); 2015fd4e5da5Sopenharmony_ci 2016fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 2017fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(recipient_context.get()), validator_options); 2018fd4e5da5Sopenharmony_ci 2019fd4e5da5Sopenharmony_ci FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100, 2020fd4e5da5Sopenharmony_ci false); 2021fd4e5da5Sopenharmony_ci protobufs::TransformationSequence transformation_sequence; 2022fd4e5da5Sopenharmony_ci 2023fd4e5da5Sopenharmony_ci FuzzerPassDonateModules fuzzer_pass(recipient_context.get(), 2024fd4e5da5Sopenharmony_ci &transformation_context, &fuzzer_context, 2025fd4e5da5Sopenharmony_ci &transformation_sequence, false, {}); 2026fd4e5da5Sopenharmony_ci 2027fd4e5da5Sopenharmony_ci ASSERT_TRUE(donor_context->get_feature_mgr()->HasCapability( 2028fd4e5da5Sopenharmony_ci spv::Capability::VariablePointersStorageBuffer)); 2029fd4e5da5Sopenharmony_ci ASSERT_FALSE(recipient_context->get_feature_mgr()->HasCapability( 2030fd4e5da5Sopenharmony_ci spv::Capability::VariablePointersStorageBuffer)); 2031fd4e5da5Sopenharmony_ci 2032fd4e5da5Sopenharmony_ci fuzzer_pass.DonateSingleModule(donor_context.get(), false); 2033fd4e5da5Sopenharmony_ci 2034fd4e5da5Sopenharmony_ci // Check that recipient module hasn't changed. 2035fd4e5da5Sopenharmony_ci ASSERT_TRUE(IsEqual(env, recipient_shader, recipient_context.get())); 2036fd4e5da5Sopenharmony_ci 2037fd4e5da5Sopenharmony_ci // Add the missing capability. 2038fd4e5da5Sopenharmony_ci // 2039fd4e5da5Sopenharmony_ci // We are adding VariablePointers to test the case when donor and recipient 2040fd4e5da5Sopenharmony_ci // have different OpCapability instructions but the same capabilities. In our 2041fd4e5da5Sopenharmony_ci // example, VariablePointers implicitly declares 2042fd4e5da5Sopenharmony_ci // VariablePointersStorageBuffer. Thus, two modules must be compatible. 2043fd4e5da5Sopenharmony_ci recipient_context->AddCapability(spv::Capability::VariablePointers); 2044fd4e5da5Sopenharmony_ci 2045fd4e5da5Sopenharmony_ci ASSERT_TRUE(donor_context->get_feature_mgr()->HasCapability( 2046fd4e5da5Sopenharmony_ci spv::Capability::VariablePointersStorageBuffer)); 2047fd4e5da5Sopenharmony_ci ASSERT_TRUE(recipient_context->get_feature_mgr()->HasCapability( 2048fd4e5da5Sopenharmony_ci spv::Capability::VariablePointersStorageBuffer)); 2049fd4e5da5Sopenharmony_ci 2050fd4e5da5Sopenharmony_ci fuzzer_pass.DonateSingleModule(donor_context.get(), false); 2051fd4e5da5Sopenharmony_ci 2052fd4e5da5Sopenharmony_ci // Check that donation was successful. 2053fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed( 2054fd4e5da5Sopenharmony_ci recipient_context.get(), validator_options, kConsoleMessageConsumer)); 2055fd4e5da5Sopenharmony_ci 2056fd4e5da5Sopenharmony_ci std::string after_transformation = R"( 2057fd4e5da5Sopenharmony_ci OpCapability Shader 2058fd4e5da5Sopenharmony_ci OpCapability VariablePointers 2059fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 2060fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 2061fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 2062fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 2063fd4e5da5Sopenharmony_ci OpSource ESSL 310 2064fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 2065fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 2066fd4e5da5Sopenharmony_ci %100 = OpTypeFloat 32 2067fd4e5da5Sopenharmony_ci %101 = OpConstant %100 23 2068fd4e5da5Sopenharmony_ci %102 = OpTypePointer Function %100 2069fd4e5da5Sopenharmony_ci %105 = OpConstant %100 0 2070fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 2071fd4e5da5Sopenharmony_ci %5 = OpLabel 2072fd4e5da5Sopenharmony_ci OpReturn 2073fd4e5da5Sopenharmony_ci OpFunctionEnd 2074fd4e5da5Sopenharmony_ci %103 = OpFunction %2 None %3 2075fd4e5da5Sopenharmony_ci %104 = OpLabel 2076fd4e5da5Sopenharmony_ci %106 = OpVariable %102 Function %105 2077fd4e5da5Sopenharmony_ci OpBranch %107 2078fd4e5da5Sopenharmony_ci %107 = OpLabel 2079fd4e5da5Sopenharmony_ci %108 = OpPhi %102 %106 %104 2080fd4e5da5Sopenharmony_ci OpStore %108 %101 2081fd4e5da5Sopenharmony_ci OpReturn 2082fd4e5da5Sopenharmony_ci OpFunctionEnd 2083fd4e5da5Sopenharmony_ci )"; 2084fd4e5da5Sopenharmony_ci 2085fd4e5da5Sopenharmony_ci ASSERT_TRUE(IsEqual(env, after_transformation, recipient_context.get())); 2086fd4e5da5Sopenharmony_ci} 2087fd4e5da5Sopenharmony_ci 2088fd4e5da5Sopenharmony_ciTEST(FuzzerPassDonateModulesTest, HandlesOpPhisInMergeBlock) { 2089fd4e5da5Sopenharmony_ci std::string donor_shader = R"( 2090fd4e5da5Sopenharmony_ci ; OpPhis don't support pointers without this capability 2091fd4e5da5Sopenharmony_ci ; and we need pointers to test some of the functionality 2092fd4e5da5Sopenharmony_ci OpCapability VariablePointers 2093fd4e5da5Sopenharmony_ci OpCapability Shader 2094fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 2095fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 2096fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 2097fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 2098fd4e5da5Sopenharmony_ci OpSource ESSL 310 2099fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 2100fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 2101fd4e5da5Sopenharmony_ci %14 = OpTypeBool 2102fd4e5da5Sopenharmony_ci %15 = OpConstantTrue %14 2103fd4e5da5Sopenharmony_ci %42 = OpTypePointer Function %14 2104fd4e5da5Sopenharmony_ci 2105fd4e5da5Sopenharmony_ci ; back-edge block is unreachable in the CFG 2106fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 2107fd4e5da5Sopenharmony_ci %5 = OpLabel 2108fd4e5da5Sopenharmony_ci OpBranch %6 2109fd4e5da5Sopenharmony_ci %6 = OpLabel 2110fd4e5da5Sopenharmony_ci OpLoopMerge %8 %7 None 2111fd4e5da5Sopenharmony_ci OpBranch %8 2112fd4e5da5Sopenharmony_ci %7 = OpLabel 2113fd4e5da5Sopenharmony_ci OpBranch %6 2114fd4e5da5Sopenharmony_ci %8 = OpLabel 2115fd4e5da5Sopenharmony_ci OpReturn 2116fd4e5da5Sopenharmony_ci OpFunctionEnd 2117fd4e5da5Sopenharmony_ci 2118fd4e5da5Sopenharmony_ci ; back-edge block already has an edge to the merge block 2119fd4e5da5Sopenharmony_ci %9 = OpFunction %2 None %3 2120fd4e5da5Sopenharmony_ci %10 = OpLabel 2121fd4e5da5Sopenharmony_ci OpBranch %11 2122fd4e5da5Sopenharmony_ci %11 = OpLabel 2123fd4e5da5Sopenharmony_ci OpLoopMerge %13 %12 None 2124fd4e5da5Sopenharmony_ci OpBranch %12 2125fd4e5da5Sopenharmony_ci %12 = OpLabel 2126fd4e5da5Sopenharmony_ci OpBranchConditional %15 %11 %13 2127fd4e5da5Sopenharmony_ci %13 = OpLabel 2128fd4e5da5Sopenharmony_ci OpReturn 2129fd4e5da5Sopenharmony_ci OpFunctionEnd 2130fd4e5da5Sopenharmony_ci 2131fd4e5da5Sopenharmony_ci ; merge block has no OpPhis 2132fd4e5da5Sopenharmony_ci %16 = OpFunction %2 None %3 2133fd4e5da5Sopenharmony_ci %17 = OpLabel 2134fd4e5da5Sopenharmony_ci OpBranch %18 2135fd4e5da5Sopenharmony_ci %18 = OpLabel 2136fd4e5da5Sopenharmony_ci OpLoopMerge %20 %19 None 2137fd4e5da5Sopenharmony_ci OpBranchConditional %15 %19 %20 2138fd4e5da5Sopenharmony_ci %19 = OpLabel 2139fd4e5da5Sopenharmony_ci OpBranch %18 2140fd4e5da5Sopenharmony_ci %20 = OpLabel 2141fd4e5da5Sopenharmony_ci OpReturn 2142fd4e5da5Sopenharmony_ci OpFunctionEnd 2143fd4e5da5Sopenharmony_ci 2144fd4e5da5Sopenharmony_ci ; merge block has OpPhis and some of their operands are available at 2145fd4e5da5Sopenharmony_ci ; the back-edge block 2146fd4e5da5Sopenharmony_ci %21 = OpFunction %2 None %3 2147fd4e5da5Sopenharmony_ci %22 = OpLabel 2148fd4e5da5Sopenharmony_ci OpBranch %23 2149fd4e5da5Sopenharmony_ci %23 = OpLabel 2150fd4e5da5Sopenharmony_ci %24 = OpCopyObject %14 %15 2151fd4e5da5Sopenharmony_ci OpLoopMerge %28 %27 None 2152fd4e5da5Sopenharmony_ci OpBranchConditional %15 %25 %28 2153fd4e5da5Sopenharmony_ci %25 = OpLabel 2154fd4e5da5Sopenharmony_ci %26 = OpCopyObject %14 %15 2155fd4e5da5Sopenharmony_ci OpBranchConditional %15 %28 %27 2156fd4e5da5Sopenharmony_ci %27 = OpLabel 2157fd4e5da5Sopenharmony_ci OpBranch %23 2158fd4e5da5Sopenharmony_ci %28 = OpLabel 2159fd4e5da5Sopenharmony_ci %29 = OpPhi %14 %24 %23 %26 %25 2160fd4e5da5Sopenharmony_ci OpReturn 2161fd4e5da5Sopenharmony_ci OpFunctionEnd 2162fd4e5da5Sopenharmony_ci 2163fd4e5da5Sopenharmony_ci ; none of the OpPhis' operands dominate the back-edge block but some of 2164fd4e5da5Sopenharmony_ci ; them have basic type 2165fd4e5da5Sopenharmony_ci %30 = OpFunction %2 None %3 2166fd4e5da5Sopenharmony_ci %31 = OpLabel 2167fd4e5da5Sopenharmony_ci OpBranch %32 2168fd4e5da5Sopenharmony_ci %32 = OpLabel 2169fd4e5da5Sopenharmony_ci OpLoopMerge %40 %39 None 2170fd4e5da5Sopenharmony_ci OpBranch %33 2171fd4e5da5Sopenharmony_ci %33 = OpLabel 2172fd4e5da5Sopenharmony_ci OpSelectionMerge %38 None 2173fd4e5da5Sopenharmony_ci OpBranchConditional %15 %34 %36 2174fd4e5da5Sopenharmony_ci %34 = OpLabel 2175fd4e5da5Sopenharmony_ci %35 = OpCopyObject %14 %15 2176fd4e5da5Sopenharmony_ci OpBranchConditional %35 %38 %40 2177fd4e5da5Sopenharmony_ci %36 = OpLabel 2178fd4e5da5Sopenharmony_ci %37 = OpCopyObject %14 %15 2179fd4e5da5Sopenharmony_ci OpBranchConditional %37 %38 %40 2180fd4e5da5Sopenharmony_ci %38 = OpLabel 2181fd4e5da5Sopenharmony_ci OpBranch %39 2182fd4e5da5Sopenharmony_ci %39 = OpLabel 2183fd4e5da5Sopenharmony_ci OpBranch %32 2184fd4e5da5Sopenharmony_ci %40 = OpLabel 2185fd4e5da5Sopenharmony_ci %41 = OpPhi %14 %35 %34 %37 %36 2186fd4e5da5Sopenharmony_ci OpReturn 2187fd4e5da5Sopenharmony_ci OpFunctionEnd 2188fd4e5da5Sopenharmony_ci 2189fd4e5da5Sopenharmony_ci ; none of the OpPhis' operands dominate the back-edge block and none of 2190fd4e5da5Sopenharmony_ci ; them have basic type 2191fd4e5da5Sopenharmony_ci %43 = OpFunction %2 None %3 2192fd4e5da5Sopenharmony_ci %44 = OpLabel 2193fd4e5da5Sopenharmony_ci %45 = OpVariable %42 Function 2194fd4e5da5Sopenharmony_ci OpBranch %46 2195fd4e5da5Sopenharmony_ci %46 = OpLabel 2196fd4e5da5Sopenharmony_ci OpLoopMerge %54 %53 None 2197fd4e5da5Sopenharmony_ci OpBranch %47 2198fd4e5da5Sopenharmony_ci %47 = OpLabel 2199fd4e5da5Sopenharmony_ci OpSelectionMerge %52 None 2200fd4e5da5Sopenharmony_ci OpBranchConditional %15 %48 %50 2201fd4e5da5Sopenharmony_ci %48 = OpLabel 2202fd4e5da5Sopenharmony_ci %49 = OpCopyObject %42 %45 2203fd4e5da5Sopenharmony_ci OpBranchConditional %15 %52 %54 2204fd4e5da5Sopenharmony_ci %50 = OpLabel 2205fd4e5da5Sopenharmony_ci %51 = OpCopyObject %42 %45 2206fd4e5da5Sopenharmony_ci OpBranchConditional %15 %52 %54 2207fd4e5da5Sopenharmony_ci %52 = OpLabel 2208fd4e5da5Sopenharmony_ci OpBranch %53 2209fd4e5da5Sopenharmony_ci %53 = OpLabel 2210fd4e5da5Sopenharmony_ci OpBranch %46 2211fd4e5da5Sopenharmony_ci %54 = OpLabel 2212fd4e5da5Sopenharmony_ci %55 = OpPhi %42 %49 %48 %51 %50 2213fd4e5da5Sopenharmony_ci OpReturn 2214fd4e5da5Sopenharmony_ci OpFunctionEnd 2215fd4e5da5Sopenharmony_ci )"; 2216fd4e5da5Sopenharmony_ci 2217fd4e5da5Sopenharmony_ci std::string recipient_shader = R"( 2218fd4e5da5Sopenharmony_ci ; OpPhis don't support pointers without this capability 2219fd4e5da5Sopenharmony_ci ; and we need pointers to test some of the functionality 2220fd4e5da5Sopenharmony_ci OpCapability VariablePointers 2221fd4e5da5Sopenharmony_ci OpCapability Shader 2222fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 2223fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 2224fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 2225fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 2226fd4e5da5Sopenharmony_ci OpSource ESSL 310 2227fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 2228fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 2229fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 2230fd4e5da5Sopenharmony_ci %5 = OpLabel 2231fd4e5da5Sopenharmony_ci OpReturn 2232fd4e5da5Sopenharmony_ci OpFunctionEnd 2233fd4e5da5Sopenharmony_ci )"; 2234fd4e5da5Sopenharmony_ci 2235fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 2236fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 2237fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 2238fd4e5da5Sopenharmony_ci 2239fd4e5da5Sopenharmony_ci const auto recipient_context = 2240fd4e5da5Sopenharmony_ci BuildModule(env, consumer, recipient_shader, kFuzzAssembleOption); 2241fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed( 2242fd4e5da5Sopenharmony_ci recipient_context.get(), validator_options, kConsoleMessageConsumer)); 2243fd4e5da5Sopenharmony_ci 2244fd4e5da5Sopenharmony_ci const auto donor_context = 2245fd4e5da5Sopenharmony_ci BuildModule(env, consumer, donor_shader, kFuzzAssembleOption); 2246fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed( 2247fd4e5da5Sopenharmony_ci donor_context.get(), validator_options, kConsoleMessageConsumer)); 2248fd4e5da5Sopenharmony_ci 2249fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 2250fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(recipient_context.get()), validator_options); 2251fd4e5da5Sopenharmony_ci 2252fd4e5da5Sopenharmony_ci FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100, 2253fd4e5da5Sopenharmony_ci false); 2254fd4e5da5Sopenharmony_ci protobufs::TransformationSequence transformation_sequence; 2255fd4e5da5Sopenharmony_ci 2256fd4e5da5Sopenharmony_ci FuzzerPassDonateModules fuzzer_pass(recipient_context.get(), 2257fd4e5da5Sopenharmony_ci &transformation_context, &fuzzer_context, 2258fd4e5da5Sopenharmony_ci &transformation_sequence, false, {}); 2259fd4e5da5Sopenharmony_ci 2260fd4e5da5Sopenharmony_ci fuzzer_pass.DonateSingleModule(donor_context.get(), true); 2261fd4e5da5Sopenharmony_ci 2262fd4e5da5Sopenharmony_ci // We just check that the result is valid. Checking to what it should be 2263fd4e5da5Sopenharmony_ci // exactly equal to would be very fragile. 2264fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed( 2265fd4e5da5Sopenharmony_ci recipient_context.get(), validator_options, kConsoleMessageConsumer)); 2266fd4e5da5Sopenharmony_ci} 2267fd4e5da5Sopenharmony_ci 2268fd4e5da5Sopenharmony_ci} // namespace 2269fd4e5da5Sopenharmony_ci} // namespace fuzz 2270fd4e5da5Sopenharmony_ci} // namespace spvtools 2271