1fd4e5da5Sopenharmony_ci// Copyright (c) 2020 André Perez Maselco 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/transformation_inline_function.h" 16fd4e5da5Sopenharmony_ci 17fd4e5da5Sopenharmony_ci#include "gtest/gtest.h" 18fd4e5da5Sopenharmony_ci#include "source/fuzz/counter_overflow_id_source.h" 19fd4e5da5Sopenharmony_ci#include "source/fuzz/fuzzer_util.h" 20fd4e5da5Sopenharmony_ci#include "source/fuzz/instruction_descriptor.h" 21fd4e5da5Sopenharmony_ci#include "test/fuzz/fuzz_test_util.h" 22fd4e5da5Sopenharmony_ci 23fd4e5da5Sopenharmony_cinamespace spvtools { 24fd4e5da5Sopenharmony_cinamespace fuzz { 25fd4e5da5Sopenharmony_cinamespace { 26fd4e5da5Sopenharmony_ci 27fd4e5da5Sopenharmony_ciTEST(TransformationInlineFunctionTest, IsApplicable) { 28fd4e5da5Sopenharmony_ci std::string shader = R"( 29fd4e5da5Sopenharmony_ci OpCapability Shader 30fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 31fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 32fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %52 "main" 33fd4e5da5Sopenharmony_ci OpExecutionMode %52 OriginUpperLeft 34fd4e5da5Sopenharmony_ci OpName %56 "function_with_void_return" 35fd4e5da5Sopenharmony_ci 36fd4e5da5Sopenharmony_ci; Types 37fd4e5da5Sopenharmony_ci %2 = OpTypeBool 38fd4e5da5Sopenharmony_ci %3 = OpTypeFloat 32 39fd4e5da5Sopenharmony_ci %4 = OpTypeVector %3 4 40fd4e5da5Sopenharmony_ci %5 = OpTypePointer Function %4 41fd4e5da5Sopenharmony_ci %6 = OpTypeVoid 42fd4e5da5Sopenharmony_ci %7 = OpTypeFunction %6 43fd4e5da5Sopenharmony_ci %8 = OpTypeFunction %3 %5 %5 44fd4e5da5Sopenharmony_ci 45fd4e5da5Sopenharmony_ci; Constant scalars 46fd4e5da5Sopenharmony_ci %9 = OpConstant %3 1 47fd4e5da5Sopenharmony_ci %10 = OpConstant %3 2 48fd4e5da5Sopenharmony_ci %11 = OpConstant %3 3 49fd4e5da5Sopenharmony_ci %12 = OpConstant %3 4 50fd4e5da5Sopenharmony_ci %13 = OpConstant %3 5 51fd4e5da5Sopenharmony_ci %14 = OpConstant %3 6 52fd4e5da5Sopenharmony_ci %15 = OpConstant %3 7 53fd4e5da5Sopenharmony_ci %16 = OpConstant %3 8 54fd4e5da5Sopenharmony_ci %17 = OpConstantTrue %2 55fd4e5da5Sopenharmony_ci 56fd4e5da5Sopenharmony_ci; Constant vectors 57fd4e5da5Sopenharmony_ci %18 = OpConstantComposite %4 %9 %10 %11 %12 58fd4e5da5Sopenharmony_ci %19 = OpConstantComposite %4 %13 %14 %15 %16 59fd4e5da5Sopenharmony_ci 60fd4e5da5Sopenharmony_ci; function with void return 61fd4e5da5Sopenharmony_ci %20 = OpFunction %6 None %7 62fd4e5da5Sopenharmony_ci %21 = OpLabel 63fd4e5da5Sopenharmony_ci OpReturn 64fd4e5da5Sopenharmony_ci OpFunctionEnd 65fd4e5da5Sopenharmony_ci 66fd4e5da5Sopenharmony_ci; function with early return 67fd4e5da5Sopenharmony_ci %22 = OpFunction %6 None %7 68fd4e5da5Sopenharmony_ci %23 = OpLabel 69fd4e5da5Sopenharmony_ci OpSelectionMerge %26 None 70fd4e5da5Sopenharmony_ci OpBranchConditional %17 %24 %25 71fd4e5da5Sopenharmony_ci %24 = OpLabel 72fd4e5da5Sopenharmony_ci OpReturn 73fd4e5da5Sopenharmony_ci %25 = OpLabel 74fd4e5da5Sopenharmony_ci OpBranch %26 75fd4e5da5Sopenharmony_ci %26 = OpLabel 76fd4e5da5Sopenharmony_ci OpReturn 77fd4e5da5Sopenharmony_ci OpFunctionEnd 78fd4e5da5Sopenharmony_ci 79fd4e5da5Sopenharmony_ci; function containing an OpKill instruction 80fd4e5da5Sopenharmony_ci %27 = OpFunction %6 None %7 81fd4e5da5Sopenharmony_ci %28 = OpLabel 82fd4e5da5Sopenharmony_ci OpKill 83fd4e5da5Sopenharmony_ci OpFunctionEnd 84fd4e5da5Sopenharmony_ci 85fd4e5da5Sopenharmony_ci; function containing an OpUnreachable instruction 86fd4e5da5Sopenharmony_ci %29 = OpFunction %6 None %7 87fd4e5da5Sopenharmony_ci %30 = OpLabel 88fd4e5da5Sopenharmony_ci OpUnreachable 89fd4e5da5Sopenharmony_ci OpFunctionEnd 90fd4e5da5Sopenharmony_ci 91fd4e5da5Sopenharmony_ci; dot product function 92fd4e5da5Sopenharmony_ci %31 = OpFunction %3 None %8 93fd4e5da5Sopenharmony_ci %32 = OpFunctionParameter %5 94fd4e5da5Sopenharmony_ci %33 = OpFunctionParameter %5 95fd4e5da5Sopenharmony_ci %34 = OpLabel 96fd4e5da5Sopenharmony_ci %35 = OpLoad %4 %32 97fd4e5da5Sopenharmony_ci %36 = OpLoad %4 %33 98fd4e5da5Sopenharmony_ci %37 = OpCompositeExtract %3 %35 0 99fd4e5da5Sopenharmony_ci %38 = OpCompositeExtract %3 %36 0 100fd4e5da5Sopenharmony_ci %39 = OpFMul %3 %37 %38 101fd4e5da5Sopenharmony_ci %40 = OpCompositeExtract %3 %35 1 102fd4e5da5Sopenharmony_ci %41 = OpCompositeExtract %3 %36 1 103fd4e5da5Sopenharmony_ci %42 = OpFMul %3 %40 %41 104fd4e5da5Sopenharmony_ci %43 = OpCompositeExtract %3 %35 2 105fd4e5da5Sopenharmony_ci %44 = OpCompositeExtract %3 %36 2 106fd4e5da5Sopenharmony_ci %45 = OpFMul %3 %43 %44 107fd4e5da5Sopenharmony_ci %46 = OpCompositeExtract %3 %35 3 108fd4e5da5Sopenharmony_ci %47 = OpCompositeExtract %3 %36 3 109fd4e5da5Sopenharmony_ci %48 = OpFMul %3 %46 %47 110fd4e5da5Sopenharmony_ci %49 = OpFAdd %3 %39 %42 111fd4e5da5Sopenharmony_ci %50 = OpFAdd %3 %45 %49 112fd4e5da5Sopenharmony_ci %51 = OpFAdd %3 %48 %50 113fd4e5da5Sopenharmony_ci OpReturnValue %51 114fd4e5da5Sopenharmony_ci OpFunctionEnd 115fd4e5da5Sopenharmony_ci 116fd4e5da5Sopenharmony_ci; main function 117fd4e5da5Sopenharmony_ci %52 = OpFunction %6 None %7 118fd4e5da5Sopenharmony_ci %53 = OpLabel 119fd4e5da5Sopenharmony_ci %54 = OpVariable %5 Function 120fd4e5da5Sopenharmony_ci %55 = OpVariable %5 Function 121fd4e5da5Sopenharmony_ci %56 = OpFunctionCall %6 %20 ; function with void return 122fd4e5da5Sopenharmony_ci OpBranch %57 123fd4e5da5Sopenharmony_ci %57 = OpLabel 124fd4e5da5Sopenharmony_ci %59 = OpFunctionCall %6 %22 ; function with early return 125fd4e5da5Sopenharmony_ci OpBranch %60 126fd4e5da5Sopenharmony_ci %60 = OpLabel 127fd4e5da5Sopenharmony_ci %61 = OpFunctionCall %6 %27 ; function containing OpKill 128fd4e5da5Sopenharmony_ci OpBranch %62 129fd4e5da5Sopenharmony_ci %62 = OpLabel 130fd4e5da5Sopenharmony_ci %63 = OpFunctionCall %6 %29 ; function containing OpUnreachable 131fd4e5da5Sopenharmony_ci OpBranch %64 132fd4e5da5Sopenharmony_ci %64 = OpLabel 133fd4e5da5Sopenharmony_ci OpStore %54 %18 134fd4e5da5Sopenharmony_ci OpStore %55 %19 135fd4e5da5Sopenharmony_ci %65 = OpFunctionCall %3 %31 %54 %55 ; dot product function 136fd4e5da5Sopenharmony_ci OpBranch %66 137fd4e5da5Sopenharmony_ci %66 = OpLabel 138fd4e5da5Sopenharmony_ci OpReturn 139fd4e5da5Sopenharmony_ci OpFunctionEnd 140fd4e5da5Sopenharmony_ci )"; 141fd4e5da5Sopenharmony_ci 142fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_5; 143fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 144fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); 145fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 146fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 147fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 148fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 149fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(context.get()), validator_options); 150fd4e5da5Sopenharmony_ci // Tests undefined OpFunctionCall instruction. 151fd4e5da5Sopenharmony_ci auto transformation = TransformationInlineFunction(67, {}); 152fd4e5da5Sopenharmony_ci ASSERT_FALSE( 153fd4e5da5Sopenharmony_ci transformation.IsApplicable(context.get(), transformation_context)); 154fd4e5da5Sopenharmony_ci 155fd4e5da5Sopenharmony_ci // Tests false OpFunctionCall instruction. 156fd4e5da5Sopenharmony_ci transformation = TransformationInlineFunction(42, {}); 157fd4e5da5Sopenharmony_ci ASSERT_FALSE( 158fd4e5da5Sopenharmony_ci transformation.IsApplicable(context.get(), transformation_context)); 159fd4e5da5Sopenharmony_ci 160fd4e5da5Sopenharmony_ci // Tests use of called function with void return. 161fd4e5da5Sopenharmony_ci transformation = TransformationInlineFunction(56, {}); 162fd4e5da5Sopenharmony_ci ASSERT_FALSE( 163fd4e5da5Sopenharmony_ci transformation.IsApplicable(context.get(), transformation_context)); 164fd4e5da5Sopenharmony_ci 165fd4e5da5Sopenharmony_ci // Tests called function having an early return. 166fd4e5da5Sopenharmony_ci transformation = 167fd4e5da5Sopenharmony_ci TransformationInlineFunction(59, {{24, 67}, {25, 68}, {26, 69}}); 168fd4e5da5Sopenharmony_ci ASSERT_FALSE( 169fd4e5da5Sopenharmony_ci transformation.IsApplicable(context.get(), transformation_context)); 170fd4e5da5Sopenharmony_ci 171fd4e5da5Sopenharmony_ci // Tests called function containing an OpKill instruction. 172fd4e5da5Sopenharmony_ci transformation = TransformationInlineFunction(61, {}); 173fd4e5da5Sopenharmony_ci ASSERT_FALSE( 174fd4e5da5Sopenharmony_ci transformation.IsApplicable(context.get(), transformation_context)); 175fd4e5da5Sopenharmony_ci 176fd4e5da5Sopenharmony_ci // Tests called function containing an OpUnreachable instruction. 177fd4e5da5Sopenharmony_ci transformation = TransformationInlineFunction(63, {}); 178fd4e5da5Sopenharmony_ci ASSERT_FALSE( 179fd4e5da5Sopenharmony_ci transformation.IsApplicable(context.get(), transformation_context)); 180fd4e5da5Sopenharmony_ci 181fd4e5da5Sopenharmony_ci // Tests applicable transformation. 182fd4e5da5Sopenharmony_ci transformation = TransformationInlineFunction(65, {{35, 67}, 183fd4e5da5Sopenharmony_ci {36, 68}, 184fd4e5da5Sopenharmony_ci {37, 69}, 185fd4e5da5Sopenharmony_ci {38, 70}, 186fd4e5da5Sopenharmony_ci {39, 71}, 187fd4e5da5Sopenharmony_ci {40, 72}, 188fd4e5da5Sopenharmony_ci {41, 73}, 189fd4e5da5Sopenharmony_ci {42, 74}, 190fd4e5da5Sopenharmony_ci {43, 75}, 191fd4e5da5Sopenharmony_ci {44, 76}, 192fd4e5da5Sopenharmony_ci {45, 77}, 193fd4e5da5Sopenharmony_ci {46, 78}, 194fd4e5da5Sopenharmony_ci {47, 79}, 195fd4e5da5Sopenharmony_ci {48, 80}, 196fd4e5da5Sopenharmony_ci {49, 81}, 197fd4e5da5Sopenharmony_ci {50, 82}, 198fd4e5da5Sopenharmony_ci {51, 83}}); 199fd4e5da5Sopenharmony_ci ASSERT_TRUE( 200fd4e5da5Sopenharmony_ci transformation.IsApplicable(context.get(), transformation_context)); 201fd4e5da5Sopenharmony_ci} 202fd4e5da5Sopenharmony_ci 203fd4e5da5Sopenharmony_ciTEST(TransformationInlineFunctionTest, Apply) { 204fd4e5da5Sopenharmony_ci std::string reference_shader = R"( 205fd4e5da5Sopenharmony_ci OpCapability Shader 206fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 207fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 208fd4e5da5Sopenharmony_ci OpEntryPoint Vertex %39 "main" 209fd4e5da5Sopenharmony_ci 210fd4e5da5Sopenharmony_ci; Types 211fd4e5da5Sopenharmony_ci %2 = OpTypeFloat 32 212fd4e5da5Sopenharmony_ci %3 = OpTypeVector %2 4 213fd4e5da5Sopenharmony_ci %4 = OpTypePointer Function %3 214fd4e5da5Sopenharmony_ci %5 = OpTypeVoid 215fd4e5da5Sopenharmony_ci %6 = OpTypeFunction %5 216fd4e5da5Sopenharmony_ci %7 = OpTypeFunction %2 %4 %4 217fd4e5da5Sopenharmony_ci 218fd4e5da5Sopenharmony_ci; Constant scalars 219fd4e5da5Sopenharmony_ci %8 = OpConstant %2 1 220fd4e5da5Sopenharmony_ci %9 = OpConstant %2 2 221fd4e5da5Sopenharmony_ci %10 = OpConstant %2 3 222fd4e5da5Sopenharmony_ci %11 = OpConstant %2 4 223fd4e5da5Sopenharmony_ci %12 = OpConstant %2 5 224fd4e5da5Sopenharmony_ci %13 = OpConstant %2 6 225fd4e5da5Sopenharmony_ci %14 = OpConstant %2 7 226fd4e5da5Sopenharmony_ci %15 = OpConstant %2 8 227fd4e5da5Sopenharmony_ci 228fd4e5da5Sopenharmony_ci; Constant vectors 229fd4e5da5Sopenharmony_ci %16 = OpConstantComposite %3 %8 %9 %10 %11 230fd4e5da5Sopenharmony_ci %17 = OpConstantComposite %3 %12 %13 %14 %15 231fd4e5da5Sopenharmony_ci 232fd4e5da5Sopenharmony_ci; dot product function 233fd4e5da5Sopenharmony_ci %18 = OpFunction %2 None %7 234fd4e5da5Sopenharmony_ci %19 = OpFunctionParameter %4 235fd4e5da5Sopenharmony_ci %20 = OpFunctionParameter %4 236fd4e5da5Sopenharmony_ci %21 = OpLabel 237fd4e5da5Sopenharmony_ci %22 = OpLoad %3 %19 238fd4e5da5Sopenharmony_ci %23 = OpLoad %3 %20 239fd4e5da5Sopenharmony_ci %24 = OpCompositeExtract %2 %22 0 240fd4e5da5Sopenharmony_ci %25 = OpCompositeExtract %2 %23 0 241fd4e5da5Sopenharmony_ci %26 = OpFMul %2 %24 %25 242fd4e5da5Sopenharmony_ci %27 = OpCompositeExtract %2 %22 1 243fd4e5da5Sopenharmony_ci %28 = OpCompositeExtract %2 %23 1 244fd4e5da5Sopenharmony_ci %29 = OpFMul %2 %27 %28 245fd4e5da5Sopenharmony_ci %30 = OpCompositeExtract %2 %22 2 246fd4e5da5Sopenharmony_ci %31 = OpCompositeExtract %2 %23 2 247fd4e5da5Sopenharmony_ci %32 = OpFMul %2 %30 %31 248fd4e5da5Sopenharmony_ci %33 = OpCompositeExtract %2 %22 3 249fd4e5da5Sopenharmony_ci %34 = OpCompositeExtract %2 %23 3 250fd4e5da5Sopenharmony_ci %35 = OpFMul %2 %33 %34 251fd4e5da5Sopenharmony_ci %36 = OpFAdd %2 %26 %29 252fd4e5da5Sopenharmony_ci %37 = OpFAdd %2 %32 %36 253fd4e5da5Sopenharmony_ci %38 = OpFAdd %2 %35 %37 254fd4e5da5Sopenharmony_ci OpReturnValue %38 255fd4e5da5Sopenharmony_ci OpFunctionEnd 256fd4e5da5Sopenharmony_ci 257fd4e5da5Sopenharmony_ci; main function 258fd4e5da5Sopenharmony_ci %39 = OpFunction %5 None %6 259fd4e5da5Sopenharmony_ci %40 = OpLabel 260fd4e5da5Sopenharmony_ci %41 = OpVariable %4 Function 261fd4e5da5Sopenharmony_ci %42 = OpVariable %4 Function 262fd4e5da5Sopenharmony_ci OpStore %41 %16 263fd4e5da5Sopenharmony_ci OpStore %42 %17 264fd4e5da5Sopenharmony_ci %43 = OpFunctionCall %2 %18 %41 %42 ; dot product function call 265fd4e5da5Sopenharmony_ci OpBranch %44 266fd4e5da5Sopenharmony_ci %44 = OpLabel 267fd4e5da5Sopenharmony_ci OpReturn 268fd4e5da5Sopenharmony_ci OpFunctionEnd 269fd4e5da5Sopenharmony_ci )"; 270fd4e5da5Sopenharmony_ci 271fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_5; 272fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 273fd4e5da5Sopenharmony_ci const auto context = 274fd4e5da5Sopenharmony_ci BuildModule(env, consumer, reference_shader, kFuzzAssembleOption); 275fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 276fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 277fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 278fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 279fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(context.get()), validator_options); 280fd4e5da5Sopenharmony_ci auto transformation = TransformationInlineFunction(43, {{22, 45}, 281fd4e5da5Sopenharmony_ci {23, 46}, 282fd4e5da5Sopenharmony_ci {24, 47}, 283fd4e5da5Sopenharmony_ci {25, 48}, 284fd4e5da5Sopenharmony_ci {26, 49}, 285fd4e5da5Sopenharmony_ci {27, 50}, 286fd4e5da5Sopenharmony_ci {28, 51}, 287fd4e5da5Sopenharmony_ci {29, 52}, 288fd4e5da5Sopenharmony_ci {30, 53}, 289fd4e5da5Sopenharmony_ci {31, 54}, 290fd4e5da5Sopenharmony_ci {32, 55}, 291fd4e5da5Sopenharmony_ci {33, 56}, 292fd4e5da5Sopenharmony_ci {34, 57}, 293fd4e5da5Sopenharmony_ci {35, 58}, 294fd4e5da5Sopenharmony_ci {36, 59}, 295fd4e5da5Sopenharmony_ci {37, 60}, 296fd4e5da5Sopenharmony_ci {38, 61}}); 297fd4e5da5Sopenharmony_ci ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); 298fd4e5da5Sopenharmony_ci 299fd4e5da5Sopenharmony_ci std::string variant_shader = R"( 300fd4e5da5Sopenharmony_ci OpCapability Shader 301fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 302fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 303fd4e5da5Sopenharmony_ci OpEntryPoint Vertex %39 "main" 304fd4e5da5Sopenharmony_ci 305fd4e5da5Sopenharmony_ci; Types 306fd4e5da5Sopenharmony_ci %2 = OpTypeFloat 32 307fd4e5da5Sopenharmony_ci %3 = OpTypeVector %2 4 308fd4e5da5Sopenharmony_ci %4 = OpTypePointer Function %3 309fd4e5da5Sopenharmony_ci %5 = OpTypeVoid 310fd4e5da5Sopenharmony_ci %6 = OpTypeFunction %5 311fd4e5da5Sopenharmony_ci %7 = OpTypeFunction %2 %4 %4 312fd4e5da5Sopenharmony_ci 313fd4e5da5Sopenharmony_ci; Constant scalars 314fd4e5da5Sopenharmony_ci %8 = OpConstant %2 1 315fd4e5da5Sopenharmony_ci %9 = OpConstant %2 2 316fd4e5da5Sopenharmony_ci %10 = OpConstant %2 3 317fd4e5da5Sopenharmony_ci %11 = OpConstant %2 4 318fd4e5da5Sopenharmony_ci %12 = OpConstant %2 5 319fd4e5da5Sopenharmony_ci %13 = OpConstant %2 6 320fd4e5da5Sopenharmony_ci %14 = OpConstant %2 7 321fd4e5da5Sopenharmony_ci %15 = OpConstant %2 8 322fd4e5da5Sopenharmony_ci 323fd4e5da5Sopenharmony_ci; Constant vectors 324fd4e5da5Sopenharmony_ci %16 = OpConstantComposite %3 %8 %9 %10 %11 325fd4e5da5Sopenharmony_ci %17 = OpConstantComposite %3 %12 %13 %14 %15 326fd4e5da5Sopenharmony_ci 327fd4e5da5Sopenharmony_ci; dot product function 328fd4e5da5Sopenharmony_ci %18 = OpFunction %2 None %7 329fd4e5da5Sopenharmony_ci %19 = OpFunctionParameter %4 330fd4e5da5Sopenharmony_ci %20 = OpFunctionParameter %4 331fd4e5da5Sopenharmony_ci %21 = OpLabel 332fd4e5da5Sopenharmony_ci %22 = OpLoad %3 %19 333fd4e5da5Sopenharmony_ci %23 = OpLoad %3 %20 334fd4e5da5Sopenharmony_ci %24 = OpCompositeExtract %2 %22 0 335fd4e5da5Sopenharmony_ci %25 = OpCompositeExtract %2 %23 0 336fd4e5da5Sopenharmony_ci %26 = OpFMul %2 %24 %25 337fd4e5da5Sopenharmony_ci %27 = OpCompositeExtract %2 %22 1 338fd4e5da5Sopenharmony_ci %28 = OpCompositeExtract %2 %23 1 339fd4e5da5Sopenharmony_ci %29 = OpFMul %2 %27 %28 340fd4e5da5Sopenharmony_ci %30 = OpCompositeExtract %2 %22 2 341fd4e5da5Sopenharmony_ci %31 = OpCompositeExtract %2 %23 2 342fd4e5da5Sopenharmony_ci %32 = OpFMul %2 %30 %31 343fd4e5da5Sopenharmony_ci %33 = OpCompositeExtract %2 %22 3 344fd4e5da5Sopenharmony_ci %34 = OpCompositeExtract %2 %23 3 345fd4e5da5Sopenharmony_ci %35 = OpFMul %2 %33 %34 346fd4e5da5Sopenharmony_ci %36 = OpFAdd %2 %26 %29 347fd4e5da5Sopenharmony_ci %37 = OpFAdd %2 %32 %36 348fd4e5da5Sopenharmony_ci %38 = OpFAdd %2 %35 %37 349fd4e5da5Sopenharmony_ci OpReturnValue %38 350fd4e5da5Sopenharmony_ci OpFunctionEnd 351fd4e5da5Sopenharmony_ci 352fd4e5da5Sopenharmony_ci; main function 353fd4e5da5Sopenharmony_ci %39 = OpFunction %5 None %6 354fd4e5da5Sopenharmony_ci %40 = OpLabel 355fd4e5da5Sopenharmony_ci %41 = OpVariable %4 Function 356fd4e5da5Sopenharmony_ci %42 = OpVariable %4 Function 357fd4e5da5Sopenharmony_ci OpStore %41 %16 358fd4e5da5Sopenharmony_ci OpStore %42 %17 359fd4e5da5Sopenharmony_ci %45 = OpLoad %3 %41 360fd4e5da5Sopenharmony_ci %46 = OpLoad %3 %42 361fd4e5da5Sopenharmony_ci %47 = OpCompositeExtract %2 %45 0 362fd4e5da5Sopenharmony_ci %48 = OpCompositeExtract %2 %46 0 363fd4e5da5Sopenharmony_ci %49 = OpFMul %2 %47 %48 364fd4e5da5Sopenharmony_ci %50 = OpCompositeExtract %2 %45 1 365fd4e5da5Sopenharmony_ci %51 = OpCompositeExtract %2 %46 1 366fd4e5da5Sopenharmony_ci %52 = OpFMul %2 %50 %51 367fd4e5da5Sopenharmony_ci %53 = OpCompositeExtract %2 %45 2 368fd4e5da5Sopenharmony_ci %54 = OpCompositeExtract %2 %46 2 369fd4e5da5Sopenharmony_ci %55 = OpFMul %2 %53 %54 370fd4e5da5Sopenharmony_ci %56 = OpCompositeExtract %2 %45 3 371fd4e5da5Sopenharmony_ci %57 = OpCompositeExtract %2 %46 3 372fd4e5da5Sopenharmony_ci %58 = OpFMul %2 %56 %57 373fd4e5da5Sopenharmony_ci %59 = OpFAdd %2 %49 %52 374fd4e5da5Sopenharmony_ci %60 = OpFAdd %2 %55 %59 375fd4e5da5Sopenharmony_ci %61 = OpFAdd %2 %58 %60 376fd4e5da5Sopenharmony_ci %43 = OpCopyObject %2 %61 377fd4e5da5Sopenharmony_ci OpBranch %44 378fd4e5da5Sopenharmony_ci %44 = OpLabel 379fd4e5da5Sopenharmony_ci OpReturn 380fd4e5da5Sopenharmony_ci OpFunctionEnd 381fd4e5da5Sopenharmony_ci )"; 382fd4e5da5Sopenharmony_ci 383fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 384fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 385fd4e5da5Sopenharmony_ci ASSERT_TRUE(IsEqual(env, variant_shader, context.get())); 386fd4e5da5Sopenharmony_ci} 387fd4e5da5Sopenharmony_ci 388fd4e5da5Sopenharmony_ciTEST(TransformationInlineFunctionTest, ApplyToMultipleFunctions) { 389fd4e5da5Sopenharmony_ci std::string reference_shader = R"( 390fd4e5da5Sopenharmony_ci OpCapability Shader 391fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 392fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 393fd4e5da5Sopenharmony_ci OpEntryPoint Vertex %15 "main" 394fd4e5da5Sopenharmony_ci 395fd4e5da5Sopenharmony_ci; Types 396fd4e5da5Sopenharmony_ci %2 = OpTypeInt 32 1 397fd4e5da5Sopenharmony_ci %3 = OpTypeBool 398fd4e5da5Sopenharmony_ci %4 = OpTypePointer Private %2 399fd4e5da5Sopenharmony_ci %5 = OpTypePointer Function %2 400fd4e5da5Sopenharmony_ci %6 = OpTypeVoid 401fd4e5da5Sopenharmony_ci %7 = OpTypeFunction %6 402fd4e5da5Sopenharmony_ci %8 = OpTypeFunction %2 %5 403fd4e5da5Sopenharmony_ci %9 = OpTypeFunction %2 %2 404fd4e5da5Sopenharmony_ci 405fd4e5da5Sopenharmony_ci; Constants 406fd4e5da5Sopenharmony_ci %10 = OpConstant %2 0 407fd4e5da5Sopenharmony_ci %11 = OpConstant %2 1 408fd4e5da5Sopenharmony_ci %12 = OpConstant %2 2 409fd4e5da5Sopenharmony_ci %13 = OpConstant %2 3 410fd4e5da5Sopenharmony_ci 411fd4e5da5Sopenharmony_ci; Global variable 412fd4e5da5Sopenharmony_ci %14 = OpVariable %4 Private 413fd4e5da5Sopenharmony_ci 414fd4e5da5Sopenharmony_ci; main function 415fd4e5da5Sopenharmony_ci %15 = OpFunction %6 None %7 416fd4e5da5Sopenharmony_ci %16 = OpLabel 417fd4e5da5Sopenharmony_ci %17 = OpVariable %5 Function 418fd4e5da5Sopenharmony_ci %18 = OpVariable %5 Function 419fd4e5da5Sopenharmony_ci %19 = OpVariable %5 Function 420fd4e5da5Sopenharmony_ci OpStore %17 %13 421fd4e5da5Sopenharmony_ci %20 = OpLoad %2 %17 422fd4e5da5Sopenharmony_ci OpStore %18 %20 423fd4e5da5Sopenharmony_ci %21 = OpFunctionCall %2 %36 %18 424fd4e5da5Sopenharmony_ci OpBranch %22 425fd4e5da5Sopenharmony_ci %22 = OpLabel 426fd4e5da5Sopenharmony_ci %23 = OpFunctionCall %2 %36 %18 427fd4e5da5Sopenharmony_ci OpStore %17 %21 428fd4e5da5Sopenharmony_ci %24 = OpLoad %2 %17 429fd4e5da5Sopenharmony_ci %25 = OpFunctionCall %2 %54 %24 430fd4e5da5Sopenharmony_ci OpBranch %26 431fd4e5da5Sopenharmony_ci %26 = OpLabel 432fd4e5da5Sopenharmony_ci %27 = OpFunctionCall %2 %54 %24 433fd4e5da5Sopenharmony_ci %28 = OpLoad %2 %17 434fd4e5da5Sopenharmony_ci %29 = OpIAdd %2 %28 %25 435fd4e5da5Sopenharmony_ci OpStore %17 %29 436fd4e5da5Sopenharmony_ci %30 = OpFunctionCall %6 %67 437fd4e5da5Sopenharmony_ci OpBranch %31 438fd4e5da5Sopenharmony_ci %31 = OpLabel 439fd4e5da5Sopenharmony_ci %32 = OpFunctionCall %6 %67 440fd4e5da5Sopenharmony_ci %33 = OpLoad %2 %14 441fd4e5da5Sopenharmony_ci %34 = OpLoad %2 %17 442fd4e5da5Sopenharmony_ci %35 = OpIAdd %2 %34 %33 443fd4e5da5Sopenharmony_ci OpStore %17 %35 444fd4e5da5Sopenharmony_ci OpReturn 445fd4e5da5Sopenharmony_ci OpFunctionEnd 446fd4e5da5Sopenharmony_ci 447fd4e5da5Sopenharmony_ci; Function %36 448fd4e5da5Sopenharmony_ci %36 = OpFunction %2 None %8 449fd4e5da5Sopenharmony_ci %37 = OpFunctionParameter %5 450fd4e5da5Sopenharmony_ci %38 = OpLabel 451fd4e5da5Sopenharmony_ci %39 = OpVariable %5 Function 452fd4e5da5Sopenharmony_ci %40 = OpVariable %5 Function 453fd4e5da5Sopenharmony_ci OpStore %39 %10 454fd4e5da5Sopenharmony_ci OpBranch %41 455fd4e5da5Sopenharmony_ci %41 = OpLabel 456fd4e5da5Sopenharmony_ci OpLoopMerge %52 %49 None 457fd4e5da5Sopenharmony_ci OpBranch %42 458fd4e5da5Sopenharmony_ci %42 = OpLabel 459fd4e5da5Sopenharmony_ci %43 = OpLoad %2 %39 460fd4e5da5Sopenharmony_ci %44 = OpLoad %2 %37 461fd4e5da5Sopenharmony_ci %45 = OpSLessThan %3 %43 %44 462fd4e5da5Sopenharmony_ci OpBranchConditional %45 %46 %52 463fd4e5da5Sopenharmony_ci %46 = OpLabel 464fd4e5da5Sopenharmony_ci %47 = OpLoad %2 %40 465fd4e5da5Sopenharmony_ci %48 = OpIAdd %2 %47 %11 466fd4e5da5Sopenharmony_ci OpStore %40 %48 467fd4e5da5Sopenharmony_ci OpBranch %49 468fd4e5da5Sopenharmony_ci %49 = OpLabel 469fd4e5da5Sopenharmony_ci %50 = OpLoad %2 %39 470fd4e5da5Sopenharmony_ci %51 = OpIAdd %2 %50 %12 471fd4e5da5Sopenharmony_ci OpStore %39 %51 472fd4e5da5Sopenharmony_ci OpBranch %41 473fd4e5da5Sopenharmony_ci %52 = OpLabel 474fd4e5da5Sopenharmony_ci %53 = OpLoad %2 %40 475fd4e5da5Sopenharmony_ci OpReturnValue %53 476fd4e5da5Sopenharmony_ci OpFunctionEnd 477fd4e5da5Sopenharmony_ci 478fd4e5da5Sopenharmony_ci; Function %54 479fd4e5da5Sopenharmony_ci %54 = OpFunction %2 None %9 480fd4e5da5Sopenharmony_ci %55 = OpFunctionParameter %2 481fd4e5da5Sopenharmony_ci %56 = OpLabel 482fd4e5da5Sopenharmony_ci %57 = OpVariable %5 Function 483fd4e5da5Sopenharmony_ci OpStore %57 %10 484fd4e5da5Sopenharmony_ci %58 = OpSGreaterThan %3 %55 %10 485fd4e5da5Sopenharmony_ci OpSelectionMerge %62 None 486fd4e5da5Sopenharmony_ci OpBranchConditional %58 %64 %59 487fd4e5da5Sopenharmony_ci %59 = OpLabel 488fd4e5da5Sopenharmony_ci %60 = OpLoad %2 %57 489fd4e5da5Sopenharmony_ci %61 = OpISub %2 %60 %12 490fd4e5da5Sopenharmony_ci OpStore %57 %61 491fd4e5da5Sopenharmony_ci OpBranch %62 492fd4e5da5Sopenharmony_ci %62 = OpLabel 493fd4e5da5Sopenharmony_ci %63 = OpLoad %2 %57 494fd4e5da5Sopenharmony_ci OpReturnValue %63 495fd4e5da5Sopenharmony_ci %64 = OpLabel 496fd4e5da5Sopenharmony_ci %65 = OpLoad %2 %57 497fd4e5da5Sopenharmony_ci %66 = OpIAdd %2 %65 %11 498fd4e5da5Sopenharmony_ci OpStore %57 %66 499fd4e5da5Sopenharmony_ci OpBranch %62 500fd4e5da5Sopenharmony_ci OpFunctionEnd 501fd4e5da5Sopenharmony_ci 502fd4e5da5Sopenharmony_ci; Function %67 503fd4e5da5Sopenharmony_ci %67 = OpFunction %6 None %7 504fd4e5da5Sopenharmony_ci %68 = OpLabel 505fd4e5da5Sopenharmony_ci OpStore %14 %12 506fd4e5da5Sopenharmony_ci OpReturn 507fd4e5da5Sopenharmony_ci OpFunctionEnd 508fd4e5da5Sopenharmony_ci )"; 509fd4e5da5Sopenharmony_ci 510fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 511fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 512fd4e5da5Sopenharmony_ci const auto context = 513fd4e5da5Sopenharmony_ci BuildModule(env, consumer, reference_shader, kFuzzAssembleOption); 514fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 515fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 516fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 517fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 518fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(context.get()), validator_options); 519fd4e5da5Sopenharmony_ci auto transformation = TransformationInlineFunction(30, {}); 520fd4e5da5Sopenharmony_ci ASSERT_TRUE( 521fd4e5da5Sopenharmony_ci transformation.IsApplicable(context.get(), transformation_context)); 522fd4e5da5Sopenharmony_ci ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); 523fd4e5da5Sopenharmony_ci 524fd4e5da5Sopenharmony_ci // Tests a parameter included in the id map. 525fd4e5da5Sopenharmony_ci transformation = TransformationInlineFunction(25, {{55, 69}, 526fd4e5da5Sopenharmony_ci {56, 70}, 527fd4e5da5Sopenharmony_ci {57, 71}, 528fd4e5da5Sopenharmony_ci {58, 72}, 529fd4e5da5Sopenharmony_ci {59, 73}, 530fd4e5da5Sopenharmony_ci {60, 74}, 531fd4e5da5Sopenharmony_ci {61, 75}, 532fd4e5da5Sopenharmony_ci {62, 76}, 533fd4e5da5Sopenharmony_ci {63, 77}, 534fd4e5da5Sopenharmony_ci {64, 78}, 535fd4e5da5Sopenharmony_ci {65, 79}, 536fd4e5da5Sopenharmony_ci {66, 80}}); 537fd4e5da5Sopenharmony_ci ASSERT_FALSE( 538fd4e5da5Sopenharmony_ci transformation.IsApplicable(context.get(), transformation_context)); 539fd4e5da5Sopenharmony_ci 540fd4e5da5Sopenharmony_ci#ifndef NDEBUG 541fd4e5da5Sopenharmony_ci // Tests the id of the returned value not included in the id map. 542fd4e5da5Sopenharmony_ci transformation = TransformationInlineFunction(25, {{56, 69}, 543fd4e5da5Sopenharmony_ci {57, 70}, 544fd4e5da5Sopenharmony_ci {58, 71}, 545fd4e5da5Sopenharmony_ci {59, 72}, 546fd4e5da5Sopenharmony_ci {60, 73}, 547fd4e5da5Sopenharmony_ci {61, 74}, 548fd4e5da5Sopenharmony_ci {62, 75}, 549fd4e5da5Sopenharmony_ci {64, 76}, 550fd4e5da5Sopenharmony_ci {65, 77}, 551fd4e5da5Sopenharmony_ci {66, 78}}); 552fd4e5da5Sopenharmony_ci ASSERT_DEATH( 553fd4e5da5Sopenharmony_ci transformation.IsApplicable(context.get(), transformation_context), 554fd4e5da5Sopenharmony_ci "Bad attempt to query whether overflow ids are available."); 555fd4e5da5Sopenharmony_ci#endif 556fd4e5da5Sopenharmony_ci 557fd4e5da5Sopenharmony_ci transformation = TransformationInlineFunction(25, {{57, 69}, 558fd4e5da5Sopenharmony_ci {58, 70}, 559fd4e5da5Sopenharmony_ci {59, 71}, 560fd4e5da5Sopenharmony_ci {60, 72}, 561fd4e5da5Sopenharmony_ci {61, 73}, 562fd4e5da5Sopenharmony_ci {62, 74}, 563fd4e5da5Sopenharmony_ci {63, 75}, 564fd4e5da5Sopenharmony_ci {64, 76}, 565fd4e5da5Sopenharmony_ci {65, 77}, 566fd4e5da5Sopenharmony_ci {66, 78}}); 567fd4e5da5Sopenharmony_ci ASSERT_TRUE( 568fd4e5da5Sopenharmony_ci transformation.IsApplicable(context.get(), transformation_context)); 569fd4e5da5Sopenharmony_ci ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); 570fd4e5da5Sopenharmony_ci 571fd4e5da5Sopenharmony_ci transformation = TransformationInlineFunction(21, {{39, 79}, 572fd4e5da5Sopenharmony_ci {40, 80}, 573fd4e5da5Sopenharmony_ci {41, 81}, 574fd4e5da5Sopenharmony_ci {42, 82}, 575fd4e5da5Sopenharmony_ci {43, 83}, 576fd4e5da5Sopenharmony_ci {44, 84}, 577fd4e5da5Sopenharmony_ci {45, 85}, 578fd4e5da5Sopenharmony_ci {46, 86}, 579fd4e5da5Sopenharmony_ci {47, 87}, 580fd4e5da5Sopenharmony_ci {48, 88}, 581fd4e5da5Sopenharmony_ci {49, 89}, 582fd4e5da5Sopenharmony_ci {50, 90}, 583fd4e5da5Sopenharmony_ci {51, 91}, 584fd4e5da5Sopenharmony_ci {52, 92}, 585fd4e5da5Sopenharmony_ci {53, 93}}); 586fd4e5da5Sopenharmony_ci ASSERT_TRUE( 587fd4e5da5Sopenharmony_ci transformation.IsApplicable(context.get(), transformation_context)); 588fd4e5da5Sopenharmony_ci ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); 589fd4e5da5Sopenharmony_ci 590fd4e5da5Sopenharmony_ci std::string variant_shader = R"( 591fd4e5da5Sopenharmony_ci OpCapability Shader 592fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 593fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 594fd4e5da5Sopenharmony_ci OpEntryPoint Vertex %15 "main" 595fd4e5da5Sopenharmony_ci 596fd4e5da5Sopenharmony_ci; Types 597fd4e5da5Sopenharmony_ci %2 = OpTypeInt 32 1 598fd4e5da5Sopenharmony_ci %3 = OpTypeBool 599fd4e5da5Sopenharmony_ci %4 = OpTypePointer Private %2 600fd4e5da5Sopenharmony_ci %5 = OpTypePointer Function %2 601fd4e5da5Sopenharmony_ci %6 = OpTypeVoid 602fd4e5da5Sopenharmony_ci %7 = OpTypeFunction %6 603fd4e5da5Sopenharmony_ci %8 = OpTypeFunction %2 %5 604fd4e5da5Sopenharmony_ci %9 = OpTypeFunction %2 %2 605fd4e5da5Sopenharmony_ci 606fd4e5da5Sopenharmony_ci; Constants 607fd4e5da5Sopenharmony_ci %10 = OpConstant %2 0 608fd4e5da5Sopenharmony_ci %11 = OpConstant %2 1 609fd4e5da5Sopenharmony_ci %12 = OpConstant %2 2 610fd4e5da5Sopenharmony_ci %13 = OpConstant %2 3 611fd4e5da5Sopenharmony_ci 612fd4e5da5Sopenharmony_ci; Global variable 613fd4e5da5Sopenharmony_ci %14 = OpVariable %4 Private 614fd4e5da5Sopenharmony_ci 615fd4e5da5Sopenharmony_ci; main function 616fd4e5da5Sopenharmony_ci %15 = OpFunction %6 None %7 617fd4e5da5Sopenharmony_ci %16 = OpLabel 618fd4e5da5Sopenharmony_ci %80 = OpVariable %5 Function 619fd4e5da5Sopenharmony_ci %79 = OpVariable %5 Function 620fd4e5da5Sopenharmony_ci %69 = OpVariable %5 Function 621fd4e5da5Sopenharmony_ci %17 = OpVariable %5 Function 622fd4e5da5Sopenharmony_ci %18 = OpVariable %5 Function 623fd4e5da5Sopenharmony_ci %19 = OpVariable %5 Function 624fd4e5da5Sopenharmony_ci OpStore %17 %13 625fd4e5da5Sopenharmony_ci %20 = OpLoad %2 %17 626fd4e5da5Sopenharmony_ci OpStore %18 %20 627fd4e5da5Sopenharmony_ci OpStore %79 %10 628fd4e5da5Sopenharmony_ci OpBranch %81 629fd4e5da5Sopenharmony_ci %81 = OpLabel 630fd4e5da5Sopenharmony_ci OpLoopMerge %92 %89 None 631fd4e5da5Sopenharmony_ci OpBranch %82 632fd4e5da5Sopenharmony_ci %82 = OpLabel 633fd4e5da5Sopenharmony_ci %83 = OpLoad %2 %79 634fd4e5da5Sopenharmony_ci %84 = OpLoad %2 %18 635fd4e5da5Sopenharmony_ci %85 = OpSLessThan %3 %83 %84 636fd4e5da5Sopenharmony_ci OpBranchConditional %85 %86 %92 637fd4e5da5Sopenharmony_ci %86 = OpLabel 638fd4e5da5Sopenharmony_ci %87 = OpLoad %2 %80 639fd4e5da5Sopenharmony_ci %88 = OpIAdd %2 %87 %11 640fd4e5da5Sopenharmony_ci OpStore %80 %88 641fd4e5da5Sopenharmony_ci OpBranch %89 642fd4e5da5Sopenharmony_ci %89 = OpLabel 643fd4e5da5Sopenharmony_ci %90 = OpLoad %2 %79 644fd4e5da5Sopenharmony_ci %91 = OpIAdd %2 %90 %12 645fd4e5da5Sopenharmony_ci OpStore %79 %91 646fd4e5da5Sopenharmony_ci OpBranch %81 647fd4e5da5Sopenharmony_ci %92 = OpLabel 648fd4e5da5Sopenharmony_ci %93 = OpLoad %2 %80 649fd4e5da5Sopenharmony_ci %21 = OpCopyObject %2 %93 650fd4e5da5Sopenharmony_ci OpBranch %22 651fd4e5da5Sopenharmony_ci %22 = OpLabel 652fd4e5da5Sopenharmony_ci %23 = OpFunctionCall %2 %36 %18 653fd4e5da5Sopenharmony_ci OpStore %17 %21 654fd4e5da5Sopenharmony_ci %24 = OpLoad %2 %17 655fd4e5da5Sopenharmony_ci OpStore %69 %10 656fd4e5da5Sopenharmony_ci %70 = OpSGreaterThan %3 %24 %10 657fd4e5da5Sopenharmony_ci OpSelectionMerge %74 None 658fd4e5da5Sopenharmony_ci OpBranchConditional %70 %76 %71 659fd4e5da5Sopenharmony_ci %71 = OpLabel 660fd4e5da5Sopenharmony_ci %72 = OpLoad %2 %69 661fd4e5da5Sopenharmony_ci %73 = OpISub %2 %72 %12 662fd4e5da5Sopenharmony_ci OpStore %69 %73 663fd4e5da5Sopenharmony_ci OpBranch %74 664fd4e5da5Sopenharmony_ci %74 = OpLabel 665fd4e5da5Sopenharmony_ci %75 = OpLoad %2 %69 666fd4e5da5Sopenharmony_ci %25 = OpCopyObject %2 %75 667fd4e5da5Sopenharmony_ci OpBranch %26 668fd4e5da5Sopenharmony_ci %76 = OpLabel 669fd4e5da5Sopenharmony_ci %77 = OpLoad %2 %69 670fd4e5da5Sopenharmony_ci %78 = OpIAdd %2 %77 %11 671fd4e5da5Sopenharmony_ci OpStore %69 %78 672fd4e5da5Sopenharmony_ci OpBranch %74 673fd4e5da5Sopenharmony_ci %26 = OpLabel 674fd4e5da5Sopenharmony_ci %27 = OpFunctionCall %2 %54 %24 675fd4e5da5Sopenharmony_ci %28 = OpLoad %2 %17 676fd4e5da5Sopenharmony_ci %29 = OpIAdd %2 %28 %25 677fd4e5da5Sopenharmony_ci OpStore %17 %29 678fd4e5da5Sopenharmony_ci OpStore %14 %12 679fd4e5da5Sopenharmony_ci OpBranch %31 680fd4e5da5Sopenharmony_ci %31 = OpLabel 681fd4e5da5Sopenharmony_ci %32 = OpFunctionCall %6 %67 682fd4e5da5Sopenharmony_ci %33 = OpLoad %2 %14 683fd4e5da5Sopenharmony_ci %34 = OpLoad %2 %17 684fd4e5da5Sopenharmony_ci %35 = OpIAdd %2 %34 %33 685fd4e5da5Sopenharmony_ci OpStore %17 %35 686fd4e5da5Sopenharmony_ci OpReturn 687fd4e5da5Sopenharmony_ci OpFunctionEnd 688fd4e5da5Sopenharmony_ci 689fd4e5da5Sopenharmony_ci; Function %36 690fd4e5da5Sopenharmony_ci %36 = OpFunction %2 None %8 691fd4e5da5Sopenharmony_ci %37 = OpFunctionParameter %5 692fd4e5da5Sopenharmony_ci %38 = OpLabel 693fd4e5da5Sopenharmony_ci %39 = OpVariable %5 Function 694fd4e5da5Sopenharmony_ci %40 = OpVariable %5 Function 695fd4e5da5Sopenharmony_ci OpStore %39 %10 696fd4e5da5Sopenharmony_ci OpBranch %41 697fd4e5da5Sopenharmony_ci %41 = OpLabel 698fd4e5da5Sopenharmony_ci OpLoopMerge %52 %49 None 699fd4e5da5Sopenharmony_ci OpBranch %42 700fd4e5da5Sopenharmony_ci %42 = OpLabel 701fd4e5da5Sopenharmony_ci %43 = OpLoad %2 %39 702fd4e5da5Sopenharmony_ci %44 = OpLoad %2 %37 703fd4e5da5Sopenharmony_ci %45 = OpSLessThan %3 %43 %44 704fd4e5da5Sopenharmony_ci OpBranchConditional %45 %46 %52 705fd4e5da5Sopenharmony_ci %46 = OpLabel 706fd4e5da5Sopenharmony_ci %47 = OpLoad %2 %40 707fd4e5da5Sopenharmony_ci %48 = OpIAdd %2 %47 %11 708fd4e5da5Sopenharmony_ci OpStore %40 %48 709fd4e5da5Sopenharmony_ci OpBranch %49 710fd4e5da5Sopenharmony_ci %49 = OpLabel 711fd4e5da5Sopenharmony_ci %50 = OpLoad %2 %39 712fd4e5da5Sopenharmony_ci %51 = OpIAdd %2 %50 %12 713fd4e5da5Sopenharmony_ci OpStore %39 %51 714fd4e5da5Sopenharmony_ci OpBranch %41 715fd4e5da5Sopenharmony_ci %52 = OpLabel 716fd4e5da5Sopenharmony_ci %53 = OpLoad %2 %40 717fd4e5da5Sopenharmony_ci OpReturnValue %53 718fd4e5da5Sopenharmony_ci OpFunctionEnd 719fd4e5da5Sopenharmony_ci 720fd4e5da5Sopenharmony_ci; Function %54 721fd4e5da5Sopenharmony_ci %54 = OpFunction %2 None %9 722fd4e5da5Sopenharmony_ci %55 = OpFunctionParameter %2 723fd4e5da5Sopenharmony_ci %56 = OpLabel 724fd4e5da5Sopenharmony_ci %57 = OpVariable %5 Function 725fd4e5da5Sopenharmony_ci OpStore %57 %10 726fd4e5da5Sopenharmony_ci %58 = OpSGreaterThan %3 %55 %10 727fd4e5da5Sopenharmony_ci OpSelectionMerge %62 None 728fd4e5da5Sopenharmony_ci OpBranchConditional %58 %64 %59 729fd4e5da5Sopenharmony_ci %59 = OpLabel 730fd4e5da5Sopenharmony_ci %60 = OpLoad %2 %57 731fd4e5da5Sopenharmony_ci %61 = OpISub %2 %60 %12 732fd4e5da5Sopenharmony_ci OpStore %57 %61 733fd4e5da5Sopenharmony_ci OpBranch %62 734fd4e5da5Sopenharmony_ci %62 = OpLabel 735fd4e5da5Sopenharmony_ci %63 = OpLoad %2 %57 736fd4e5da5Sopenharmony_ci OpReturnValue %63 737fd4e5da5Sopenharmony_ci %64 = OpLabel 738fd4e5da5Sopenharmony_ci %65 = OpLoad %2 %57 739fd4e5da5Sopenharmony_ci %66 = OpIAdd %2 %65 %11 740fd4e5da5Sopenharmony_ci OpStore %57 %66 741fd4e5da5Sopenharmony_ci OpBranch %62 742fd4e5da5Sopenharmony_ci OpFunctionEnd 743fd4e5da5Sopenharmony_ci 744fd4e5da5Sopenharmony_ci; Function %67 745fd4e5da5Sopenharmony_ci %67 = OpFunction %6 None %7 746fd4e5da5Sopenharmony_ci %68 = OpLabel 747fd4e5da5Sopenharmony_ci OpStore %14 %12 748fd4e5da5Sopenharmony_ci OpReturn 749fd4e5da5Sopenharmony_ci OpFunctionEnd 750fd4e5da5Sopenharmony_ci )"; 751fd4e5da5Sopenharmony_ci 752fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 753fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 754fd4e5da5Sopenharmony_ci ASSERT_TRUE(IsEqual(env, variant_shader, context.get())); 755fd4e5da5Sopenharmony_ci} 756fd4e5da5Sopenharmony_ci 757fd4e5da5Sopenharmony_ciTEST(TransformationInlineFunctionTest, HandlesOpPhisInTheSecondBlock) { 758fd4e5da5Sopenharmony_ci std::string shader = R"( 759fd4e5da5Sopenharmony_ci OpCapability Shader 760fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 761fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 762fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 763fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 764fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 765fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 766fd4e5da5Sopenharmony_ci %10 = OpTypeInt 32 0 767fd4e5da5Sopenharmony_ci %11 = OpUndef %10 768fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 769fd4e5da5Sopenharmony_ci %5 = OpLabel 770fd4e5da5Sopenharmony_ci %6 = OpFunctionCall %2 %7 771fd4e5da5Sopenharmony_ci OpBranch %14 772fd4e5da5Sopenharmony_ci %14 = OpLabel 773fd4e5da5Sopenharmony_ci OpReturn 774fd4e5da5Sopenharmony_ci OpFunctionEnd 775fd4e5da5Sopenharmony_ci %7 = OpFunction %2 None %3 776fd4e5da5Sopenharmony_ci %8 = OpLabel 777fd4e5da5Sopenharmony_ci OpBranch %13 778fd4e5da5Sopenharmony_ci %13 = OpLabel 779fd4e5da5Sopenharmony_ci %12 = OpPhi %10 %11 %8 780fd4e5da5Sopenharmony_ci OpReturn 781fd4e5da5Sopenharmony_ci OpFunctionEnd 782fd4e5da5Sopenharmony_ci )"; 783fd4e5da5Sopenharmony_ci 784fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 785fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 786fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); 787fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 788fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 789fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 790fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 791fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(context.get()), validator_options); 792fd4e5da5Sopenharmony_ci TransformationInlineFunction transformation(6, 793fd4e5da5Sopenharmony_ci {{{8, 20}, {13, 21}, {12, 22}}}); 794fd4e5da5Sopenharmony_ci ASSERT_TRUE( 795fd4e5da5Sopenharmony_ci transformation.IsApplicable(context.get(), transformation_context)); 796fd4e5da5Sopenharmony_ci ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); 797fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 798fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 799fd4e5da5Sopenharmony_ci 800fd4e5da5Sopenharmony_ci std::string after_transformation = R"( 801fd4e5da5Sopenharmony_ci OpCapability Shader 802fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 803fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 804fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 805fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 806fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 807fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 808fd4e5da5Sopenharmony_ci %10 = OpTypeInt 32 0 809fd4e5da5Sopenharmony_ci %11 = OpUndef %10 810fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 811fd4e5da5Sopenharmony_ci %5 = OpLabel 812fd4e5da5Sopenharmony_ci OpBranch %21 813fd4e5da5Sopenharmony_ci %21 = OpLabel 814fd4e5da5Sopenharmony_ci %22 = OpPhi %10 %11 %5 815fd4e5da5Sopenharmony_ci OpBranch %14 816fd4e5da5Sopenharmony_ci %14 = OpLabel 817fd4e5da5Sopenharmony_ci OpReturn 818fd4e5da5Sopenharmony_ci OpFunctionEnd 819fd4e5da5Sopenharmony_ci %7 = OpFunction %2 None %3 820fd4e5da5Sopenharmony_ci %8 = OpLabel 821fd4e5da5Sopenharmony_ci OpBranch %13 822fd4e5da5Sopenharmony_ci %13 = OpLabel 823fd4e5da5Sopenharmony_ci %12 = OpPhi %10 %11 %8 824fd4e5da5Sopenharmony_ci OpReturn 825fd4e5da5Sopenharmony_ci OpFunctionEnd 826fd4e5da5Sopenharmony_ci )"; 827fd4e5da5Sopenharmony_ci 828fd4e5da5Sopenharmony_ci ASSERT_TRUE(IsEqual(env, after_transformation, context.get())); 829fd4e5da5Sopenharmony_ci} 830fd4e5da5Sopenharmony_ci 831fd4e5da5Sopenharmony_ciTEST(TransformationInlineFunctionTest, OverflowIds) { 832fd4e5da5Sopenharmony_ci std::string reference_shader = R"( 833fd4e5da5Sopenharmony_ci OpCapability Shader 834fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 835fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 836fd4e5da5Sopenharmony_ci OpEntryPoint Vertex %39 "main" 837fd4e5da5Sopenharmony_ci 838fd4e5da5Sopenharmony_ci; Types 839fd4e5da5Sopenharmony_ci %2 = OpTypeFloat 32 840fd4e5da5Sopenharmony_ci %3 = OpTypeVector %2 4 841fd4e5da5Sopenharmony_ci %4 = OpTypePointer Function %3 842fd4e5da5Sopenharmony_ci %5 = OpTypeVoid 843fd4e5da5Sopenharmony_ci %6 = OpTypeFunction %5 844fd4e5da5Sopenharmony_ci %7 = OpTypeFunction %2 %4 %4 845fd4e5da5Sopenharmony_ci 846fd4e5da5Sopenharmony_ci; Constant scalars 847fd4e5da5Sopenharmony_ci %8 = OpConstant %2 1 848fd4e5da5Sopenharmony_ci %9 = OpConstant %2 2 849fd4e5da5Sopenharmony_ci %10 = OpConstant %2 3 850fd4e5da5Sopenharmony_ci %11 = OpConstant %2 4 851fd4e5da5Sopenharmony_ci %12 = OpConstant %2 5 852fd4e5da5Sopenharmony_ci %13 = OpConstant %2 6 853fd4e5da5Sopenharmony_ci %14 = OpConstant %2 7 854fd4e5da5Sopenharmony_ci %15 = OpConstant %2 8 855fd4e5da5Sopenharmony_ci 856fd4e5da5Sopenharmony_ci; Constant vectors 857fd4e5da5Sopenharmony_ci %16 = OpConstantComposite %3 %8 %9 %10 %11 858fd4e5da5Sopenharmony_ci %17 = OpConstantComposite %3 %12 %13 %14 %15 859fd4e5da5Sopenharmony_ci 860fd4e5da5Sopenharmony_ci; dot product function 861fd4e5da5Sopenharmony_ci %18 = OpFunction %2 None %7 862fd4e5da5Sopenharmony_ci %19 = OpFunctionParameter %4 863fd4e5da5Sopenharmony_ci %20 = OpFunctionParameter %4 864fd4e5da5Sopenharmony_ci %21 = OpLabel 865fd4e5da5Sopenharmony_ci %22 = OpLoad %3 %19 866fd4e5da5Sopenharmony_ci %23 = OpLoad %3 %20 867fd4e5da5Sopenharmony_ci %24 = OpCompositeExtract %2 %22 0 868fd4e5da5Sopenharmony_ci %25 = OpCompositeExtract %2 %23 0 869fd4e5da5Sopenharmony_ci %26 = OpFMul %2 %24 %25 870fd4e5da5Sopenharmony_ci %27 = OpCompositeExtract %2 %22 1 871fd4e5da5Sopenharmony_ci %28 = OpCompositeExtract %2 %23 1 872fd4e5da5Sopenharmony_ci %29 = OpFMul %2 %27 %28 873fd4e5da5Sopenharmony_ci OpBranch %100 874fd4e5da5Sopenharmony_ci %100 = OpLabel 875fd4e5da5Sopenharmony_ci %30 = OpCompositeExtract %2 %22 2 876fd4e5da5Sopenharmony_ci %31 = OpCompositeExtract %2 %23 2 877fd4e5da5Sopenharmony_ci %32 = OpFMul %2 %30 %31 878fd4e5da5Sopenharmony_ci %33 = OpCompositeExtract %2 %22 3 879fd4e5da5Sopenharmony_ci %34 = OpCompositeExtract %2 %23 3 880fd4e5da5Sopenharmony_ci %35 = OpFMul %2 %33 %34 881fd4e5da5Sopenharmony_ci %36 = OpFAdd %2 %26 %29 882fd4e5da5Sopenharmony_ci %37 = OpFAdd %2 %32 %36 883fd4e5da5Sopenharmony_ci %38 = OpFAdd %2 %35 %37 884fd4e5da5Sopenharmony_ci OpReturnValue %38 885fd4e5da5Sopenharmony_ci OpFunctionEnd 886fd4e5da5Sopenharmony_ci 887fd4e5da5Sopenharmony_ci; main function 888fd4e5da5Sopenharmony_ci %39 = OpFunction %5 None %6 889fd4e5da5Sopenharmony_ci %40 = OpLabel 890fd4e5da5Sopenharmony_ci %41 = OpVariable %4 Function 891fd4e5da5Sopenharmony_ci %42 = OpVariable %4 Function 892fd4e5da5Sopenharmony_ci OpStore %41 %16 893fd4e5da5Sopenharmony_ci OpStore %42 %17 894fd4e5da5Sopenharmony_ci %43 = OpFunctionCall %2 %18 %41 %42 ; dot product function call 895fd4e5da5Sopenharmony_ci OpBranch %44 896fd4e5da5Sopenharmony_ci %44 = OpLabel 897fd4e5da5Sopenharmony_ci OpReturn 898fd4e5da5Sopenharmony_ci OpFunctionEnd 899fd4e5da5Sopenharmony_ci )"; 900fd4e5da5Sopenharmony_ci 901fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_5; 902fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 903fd4e5da5Sopenharmony_ci const auto context = 904fd4e5da5Sopenharmony_ci BuildModule(env, consumer, reference_shader, kFuzzAssembleOption); 905fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 906fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 907fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 908fd4e5da5Sopenharmony_ci auto overflow_ids_unique_ptr = MakeUnique<CounterOverflowIdSource>(1000); 909fd4e5da5Sopenharmony_ci auto overflow_ids_ptr = overflow_ids_unique_ptr.get(); 910fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 911fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(context.get()), validator_options, 912fd4e5da5Sopenharmony_ci std::move(overflow_ids_unique_ptr)); 913fd4e5da5Sopenharmony_ci auto transformation = TransformationInlineFunction(43, {{22, 45}, 914fd4e5da5Sopenharmony_ci {23, 46}, 915fd4e5da5Sopenharmony_ci {24, 47}, 916fd4e5da5Sopenharmony_ci {25, 48}, 917fd4e5da5Sopenharmony_ci {26, 49}, 918fd4e5da5Sopenharmony_ci {27, 50}, 919fd4e5da5Sopenharmony_ci {28, 51}, 920fd4e5da5Sopenharmony_ci {29, 52}}); 921fd4e5da5Sopenharmony_ci 922fd4e5da5Sopenharmony_ci // The following ids are left un-mapped; overflow ids will be required for 923fd4e5da5Sopenharmony_ci // them: 30, 31, 32, 33, 34, 35, 36, 37, 38, 100 924fd4e5da5Sopenharmony_ci 925fd4e5da5Sopenharmony_ci ASSERT_TRUE( 926fd4e5da5Sopenharmony_ci transformation.IsApplicable(context.get(), transformation_context)); 927fd4e5da5Sopenharmony_ci 928fd4e5da5Sopenharmony_ci ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context, 929fd4e5da5Sopenharmony_ci overflow_ids_ptr->GetIssuedOverflowIds()); 930fd4e5da5Sopenharmony_ci 931fd4e5da5Sopenharmony_ci std::string variant_shader = R"( 932fd4e5da5Sopenharmony_ci OpCapability Shader 933fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 934fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 935fd4e5da5Sopenharmony_ci OpEntryPoint Vertex %39 "main" 936fd4e5da5Sopenharmony_ci 937fd4e5da5Sopenharmony_ci; Types 938fd4e5da5Sopenharmony_ci %2 = OpTypeFloat 32 939fd4e5da5Sopenharmony_ci %3 = OpTypeVector %2 4 940fd4e5da5Sopenharmony_ci %4 = OpTypePointer Function %3 941fd4e5da5Sopenharmony_ci %5 = OpTypeVoid 942fd4e5da5Sopenharmony_ci %6 = OpTypeFunction %5 943fd4e5da5Sopenharmony_ci %7 = OpTypeFunction %2 %4 %4 944fd4e5da5Sopenharmony_ci 945fd4e5da5Sopenharmony_ci; Constant scalars 946fd4e5da5Sopenharmony_ci %8 = OpConstant %2 1 947fd4e5da5Sopenharmony_ci %9 = OpConstant %2 2 948fd4e5da5Sopenharmony_ci %10 = OpConstant %2 3 949fd4e5da5Sopenharmony_ci %11 = OpConstant %2 4 950fd4e5da5Sopenharmony_ci %12 = OpConstant %2 5 951fd4e5da5Sopenharmony_ci %13 = OpConstant %2 6 952fd4e5da5Sopenharmony_ci %14 = OpConstant %2 7 953fd4e5da5Sopenharmony_ci %15 = OpConstant %2 8 954fd4e5da5Sopenharmony_ci 955fd4e5da5Sopenharmony_ci; Constant vectors 956fd4e5da5Sopenharmony_ci %16 = OpConstantComposite %3 %8 %9 %10 %11 957fd4e5da5Sopenharmony_ci %17 = OpConstantComposite %3 %12 %13 %14 %15 958fd4e5da5Sopenharmony_ci 959fd4e5da5Sopenharmony_ci; dot product function 960fd4e5da5Sopenharmony_ci %18 = OpFunction %2 None %7 961fd4e5da5Sopenharmony_ci %19 = OpFunctionParameter %4 962fd4e5da5Sopenharmony_ci %20 = OpFunctionParameter %4 963fd4e5da5Sopenharmony_ci %21 = OpLabel 964fd4e5da5Sopenharmony_ci %22 = OpLoad %3 %19 965fd4e5da5Sopenharmony_ci %23 = OpLoad %3 %20 966fd4e5da5Sopenharmony_ci %24 = OpCompositeExtract %2 %22 0 967fd4e5da5Sopenharmony_ci %25 = OpCompositeExtract %2 %23 0 968fd4e5da5Sopenharmony_ci %26 = OpFMul %2 %24 %25 969fd4e5da5Sopenharmony_ci %27 = OpCompositeExtract %2 %22 1 970fd4e5da5Sopenharmony_ci %28 = OpCompositeExtract %2 %23 1 971fd4e5da5Sopenharmony_ci %29 = OpFMul %2 %27 %28 972fd4e5da5Sopenharmony_ci OpBranch %100 973fd4e5da5Sopenharmony_ci %100 = OpLabel 974fd4e5da5Sopenharmony_ci %30 = OpCompositeExtract %2 %22 2 975fd4e5da5Sopenharmony_ci %31 = OpCompositeExtract %2 %23 2 976fd4e5da5Sopenharmony_ci %32 = OpFMul %2 %30 %31 977fd4e5da5Sopenharmony_ci %33 = OpCompositeExtract %2 %22 3 978fd4e5da5Sopenharmony_ci %34 = OpCompositeExtract %2 %23 3 979fd4e5da5Sopenharmony_ci %35 = OpFMul %2 %33 %34 980fd4e5da5Sopenharmony_ci %36 = OpFAdd %2 %26 %29 981fd4e5da5Sopenharmony_ci %37 = OpFAdd %2 %32 %36 982fd4e5da5Sopenharmony_ci %38 = OpFAdd %2 %35 %37 983fd4e5da5Sopenharmony_ci OpReturnValue %38 984fd4e5da5Sopenharmony_ci OpFunctionEnd 985fd4e5da5Sopenharmony_ci 986fd4e5da5Sopenharmony_ci; main function 987fd4e5da5Sopenharmony_ci %39 = OpFunction %5 None %6 988fd4e5da5Sopenharmony_ci %40 = OpLabel 989fd4e5da5Sopenharmony_ci %41 = OpVariable %4 Function 990fd4e5da5Sopenharmony_ci %42 = OpVariable %4 Function 991fd4e5da5Sopenharmony_ci OpStore %41 %16 992fd4e5da5Sopenharmony_ci OpStore %42 %17 993fd4e5da5Sopenharmony_ci %45 = OpLoad %3 %41 994fd4e5da5Sopenharmony_ci %46 = OpLoad %3 %42 995fd4e5da5Sopenharmony_ci %47 = OpCompositeExtract %2 %45 0 996fd4e5da5Sopenharmony_ci %48 = OpCompositeExtract %2 %46 0 997fd4e5da5Sopenharmony_ci %49 = OpFMul %2 %47 %48 998fd4e5da5Sopenharmony_ci %50 = OpCompositeExtract %2 %45 1 999fd4e5da5Sopenharmony_ci %51 = OpCompositeExtract %2 %46 1 1000fd4e5da5Sopenharmony_ci %52 = OpFMul %2 %50 %51 1001fd4e5da5Sopenharmony_ci OpBranch %1000 1002fd4e5da5Sopenharmony_ci %1000 = OpLabel 1003fd4e5da5Sopenharmony_ci %1001 = OpCompositeExtract %2 %45 2 1004fd4e5da5Sopenharmony_ci %1002 = OpCompositeExtract %2 %46 2 1005fd4e5da5Sopenharmony_ci %1003 = OpFMul %2 %1001 %1002 1006fd4e5da5Sopenharmony_ci %1004 = OpCompositeExtract %2 %45 3 1007fd4e5da5Sopenharmony_ci %1005 = OpCompositeExtract %2 %46 3 1008fd4e5da5Sopenharmony_ci %1006 = OpFMul %2 %1004 %1005 1009fd4e5da5Sopenharmony_ci %1007 = OpFAdd %2 %49 %52 1010fd4e5da5Sopenharmony_ci %1008 = OpFAdd %2 %1003 %1007 1011fd4e5da5Sopenharmony_ci %1009 = OpFAdd %2 %1006 %1008 1012fd4e5da5Sopenharmony_ci %43 = OpCopyObject %2 %1009 1013fd4e5da5Sopenharmony_ci OpBranch %44 1014fd4e5da5Sopenharmony_ci %44 = OpLabel 1015fd4e5da5Sopenharmony_ci OpReturn 1016fd4e5da5Sopenharmony_ci OpFunctionEnd 1017fd4e5da5Sopenharmony_ci )"; 1018fd4e5da5Sopenharmony_ci 1019fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 1020fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 1021fd4e5da5Sopenharmony_ci ASSERT_TRUE(IsEqual(env, variant_shader, context.get())); 1022fd4e5da5Sopenharmony_ci} 1023fd4e5da5Sopenharmony_ci 1024fd4e5da5Sopenharmony_ciTEST(TransformationInlineFunctionTest, OpPhiInBlockFollowingCall) { 1025fd4e5da5Sopenharmony_ci // This test checks that if the block after the inlined function call has an 1026fd4e5da5Sopenharmony_ci // OpPhi instruction and the called function contains multiple blocks then the 1027fd4e5da5Sopenharmony_ci // OpPhi instruction gets updated to refer to the return block of the inlined 1028fd4e5da5Sopenharmony_ci // function, since the block containing the call will no longer be a 1029fd4e5da5Sopenharmony_ci // predecessor. 1030fd4e5da5Sopenharmony_ci 1031fd4e5da5Sopenharmony_ci std::string reference_shader = R"( 1032fd4e5da5Sopenharmony_ci OpCapability Shader 1033fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 1034fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1035fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 1036fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 1037fd4e5da5Sopenharmony_ci OpSource ESSL 320 1038fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 1039fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 1040fd4e5da5Sopenharmony_ci %13 = OpTypeBool 1041fd4e5da5Sopenharmony_ci %14 = OpConstantTrue %13 1042fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 1043fd4e5da5Sopenharmony_ci %5 = OpLabel 1044fd4e5da5Sopenharmony_ci OpBranch %10 1045fd4e5da5Sopenharmony_ci %10 = OpLabel 1046fd4e5da5Sopenharmony_ci %8 = OpFunctionCall %2 %6 1047fd4e5da5Sopenharmony_ci OpBranch %11 1048fd4e5da5Sopenharmony_ci %11 = OpLabel 1049fd4e5da5Sopenharmony_ci %12 = OpPhi %13 %14 %10 1050fd4e5da5Sopenharmony_ci OpReturn 1051fd4e5da5Sopenharmony_ci OpFunctionEnd 1052fd4e5da5Sopenharmony_ci %6 = OpFunction %2 None %3 1053fd4e5da5Sopenharmony_ci %7 = OpLabel 1054fd4e5da5Sopenharmony_ci OpBranch %20 1055fd4e5da5Sopenharmony_ci %20 = OpLabel 1056fd4e5da5Sopenharmony_ci OpReturn 1057fd4e5da5Sopenharmony_ci OpFunctionEnd 1058fd4e5da5Sopenharmony_ci )"; 1059fd4e5da5Sopenharmony_ci 1060fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_5; 1061fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 1062fd4e5da5Sopenharmony_ci const auto context = 1063fd4e5da5Sopenharmony_ci BuildModule(env, consumer, reference_shader, kFuzzAssembleOption); 1064fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 1065fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 1066fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 1067fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 1068fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(context.get()), validator_options); 1069fd4e5da5Sopenharmony_ci auto transformation = TransformationInlineFunction(8, {{7, 100}, {20, 101}}); 1070fd4e5da5Sopenharmony_ci 1071fd4e5da5Sopenharmony_ci ASSERT_TRUE( 1072fd4e5da5Sopenharmony_ci transformation.IsApplicable(context.get(), transformation_context)); 1073fd4e5da5Sopenharmony_ci 1074fd4e5da5Sopenharmony_ci ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); 1075fd4e5da5Sopenharmony_ci 1076fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 1077fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 1078fd4e5da5Sopenharmony_ci 1079fd4e5da5Sopenharmony_ci std::string variant_shader = R"( 1080fd4e5da5Sopenharmony_ci OpCapability Shader 1081fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 1082fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1083fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 1084fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 1085fd4e5da5Sopenharmony_ci OpSource ESSL 320 1086fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 1087fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 1088fd4e5da5Sopenharmony_ci %13 = OpTypeBool 1089fd4e5da5Sopenharmony_ci %14 = OpConstantTrue %13 1090fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 1091fd4e5da5Sopenharmony_ci %5 = OpLabel 1092fd4e5da5Sopenharmony_ci OpBranch %10 1093fd4e5da5Sopenharmony_ci %10 = OpLabel 1094fd4e5da5Sopenharmony_ci OpBranch %101 1095fd4e5da5Sopenharmony_ci %101 = OpLabel 1096fd4e5da5Sopenharmony_ci OpBranch %11 1097fd4e5da5Sopenharmony_ci %11 = OpLabel 1098fd4e5da5Sopenharmony_ci %12 = OpPhi %13 %14 %101 1099fd4e5da5Sopenharmony_ci OpReturn 1100fd4e5da5Sopenharmony_ci OpFunctionEnd 1101fd4e5da5Sopenharmony_ci %6 = OpFunction %2 None %3 1102fd4e5da5Sopenharmony_ci %7 = OpLabel 1103fd4e5da5Sopenharmony_ci OpBranch %20 1104fd4e5da5Sopenharmony_ci %20 = OpLabel 1105fd4e5da5Sopenharmony_ci OpReturn 1106fd4e5da5Sopenharmony_ci OpFunctionEnd 1107fd4e5da5Sopenharmony_ci )"; 1108fd4e5da5Sopenharmony_ci 1109fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 1110fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 1111fd4e5da5Sopenharmony_ci ASSERT_TRUE(IsEqual(env, variant_shader, context.get())); 1112fd4e5da5Sopenharmony_ci} 1113fd4e5da5Sopenharmony_ci 1114fd4e5da5Sopenharmony_ci} // namespace 1115fd4e5da5Sopenharmony_ci} // namespace fuzz 1116fd4e5da5Sopenharmony_ci} // namespace spvtools 1117