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