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_synonym.h" 16fd4e5da5Sopenharmony_ci 17fd4e5da5Sopenharmony_ci#include "gtest/gtest.h" 18fd4e5da5Sopenharmony_ci#include "source/fuzz/fuzzer_util.h" 19fd4e5da5Sopenharmony_ci#include "source/fuzz/instruction_descriptor.h" 20fd4e5da5Sopenharmony_ci#include "test/fuzz/fuzz_test_util.h" 21fd4e5da5Sopenharmony_ci 22fd4e5da5Sopenharmony_cinamespace spvtools { 23fd4e5da5Sopenharmony_cinamespace fuzz { 24fd4e5da5Sopenharmony_cinamespace { 25fd4e5da5Sopenharmony_ci 26fd4e5da5Sopenharmony_ciTEST(TransformationAddSynonymTest, NotApplicable) { 27fd4e5da5Sopenharmony_ci std::string shader = R"( 28fd4e5da5Sopenharmony_ci OpCapability Shader 29fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 30fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 31fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 32fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 33fd4e5da5Sopenharmony_ci OpSource ESSL 310 34fd4e5da5Sopenharmony_ci OpDecorate %8 RelaxedPrecision 35fd4e5da5Sopenharmony_ci OpDecorate %22 RelaxedPrecision 36fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 37fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 38fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 39fd4e5da5Sopenharmony_ci %7 = OpTypePointer Function %6 40fd4e5da5Sopenharmony_ci %9 = OpConstant %6 3 41fd4e5da5Sopenharmony_ci %10 = OpTypeFloat 32 42fd4e5da5Sopenharmony_ci %11 = OpTypePointer Function %10 43fd4e5da5Sopenharmony_ci %13 = OpConstant %10 4.5 44fd4e5da5Sopenharmony_ci %14 = OpTypeVector %10 2 45fd4e5da5Sopenharmony_ci %15 = OpTypePointer Function %14 46fd4e5da5Sopenharmony_ci %17 = OpConstant %10 3 47fd4e5da5Sopenharmony_ci %18 = OpConstant %10 4 48fd4e5da5Sopenharmony_ci %19 = OpConstantComposite %14 %17 %18 49fd4e5da5Sopenharmony_ci %20 = OpTypeVector %6 2 50fd4e5da5Sopenharmony_ci %21 = OpTypePointer Function %20 51fd4e5da5Sopenharmony_ci %23 = OpConstant %6 4 52fd4e5da5Sopenharmony_ci %24 = OpConstantComposite %20 %9 %23 53fd4e5da5Sopenharmony_ci %26 = OpConstantNull %6 54fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 55fd4e5da5Sopenharmony_ci %5 = OpLabel 56fd4e5da5Sopenharmony_ci %8 = OpVariable %7 Function 57fd4e5da5Sopenharmony_ci %12 = OpVariable %11 Function 58fd4e5da5Sopenharmony_ci %16 = OpVariable %15 Function 59fd4e5da5Sopenharmony_ci %22 = OpVariable %21 Function 60fd4e5da5Sopenharmony_ci OpStore %8 %9 61fd4e5da5Sopenharmony_ci OpStore %12 %13 62fd4e5da5Sopenharmony_ci OpStore %16 %19 63fd4e5da5Sopenharmony_ci OpStore %22 %24 64fd4e5da5Sopenharmony_ci %25 = OpUndef %6 65fd4e5da5Sopenharmony_ci %27 = OpLoad %6 %8 66fd4e5da5Sopenharmony_ci OpReturn 67fd4e5da5Sopenharmony_ci OpFunctionEnd 68fd4e5da5Sopenharmony_ci )"; 69fd4e5da5Sopenharmony_ci 70fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 71fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 72fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); 73fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 74fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 75fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 76fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 77fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(context.get()), validator_options); 78fd4e5da5Sopenharmony_ci transformation_context.GetFactManager()->AddFactIdIsIrrelevant(24); 79fd4e5da5Sopenharmony_ci 80fd4e5da5Sopenharmony_ci auto insert_before = MakeInstructionDescriptor(22, spv::Op::OpReturn, 0); 81fd4e5da5Sopenharmony_ci 82fd4e5da5Sopenharmony_ci#ifndef NDEBUG 83fd4e5da5Sopenharmony_ci ASSERT_DEATH( 84fd4e5da5Sopenharmony_ci TransformationAddSynonym( 85fd4e5da5Sopenharmony_ci 9, static_cast<protobufs::TransformationAddSynonym::SynonymType>(-1), 86fd4e5da5Sopenharmony_ci 40, insert_before) 87fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context), 88fd4e5da5Sopenharmony_ci "Synonym type is invalid"); 89fd4e5da5Sopenharmony_ci#endif 90fd4e5da5Sopenharmony_ci 91fd4e5da5Sopenharmony_ci // These tests should succeed regardless of the synonym type. 92fd4e5da5Sopenharmony_ci for (int i = 0; 93fd4e5da5Sopenharmony_ci i < protobufs::TransformationAddSynonym::SynonymType_descriptor() 94fd4e5da5Sopenharmony_ci ->value_count(); 95fd4e5da5Sopenharmony_ci ++i) { 96fd4e5da5Sopenharmony_ci const auto* synonym_value = 97fd4e5da5Sopenharmony_ci protobufs::TransformationAddSynonym::SynonymType_descriptor()->value(i); 98fd4e5da5Sopenharmony_ci ASSERT_TRUE(protobufs::TransformationAddSynonym::SynonymType_IsValid( 99fd4e5da5Sopenharmony_ci synonym_value->number())); 100fd4e5da5Sopenharmony_ci auto synonym_type = 101fd4e5da5Sopenharmony_ci static_cast<protobufs::TransformationAddSynonym::SynonymType>( 102fd4e5da5Sopenharmony_ci synonym_value->number()); 103fd4e5da5Sopenharmony_ci 104fd4e5da5Sopenharmony_ci // |synonym_fresh_id| is not fresh. 105fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationAddSynonym(9, synonym_type, 9, insert_before) 106fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 107fd4e5da5Sopenharmony_ci 108fd4e5da5Sopenharmony_ci // |result_id| is invalid. 109fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationAddSynonym(40, synonym_type, 40, insert_before) 110fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 111fd4e5da5Sopenharmony_ci 112fd4e5da5Sopenharmony_ci // Instruction with |result_id| has no type id. 113fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationAddSynonym(5, synonym_type, 40, insert_before) 114fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 115fd4e5da5Sopenharmony_ci 116fd4e5da5Sopenharmony_ci // Instruction with |result_id| is an OpUndef. 117fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationAddSynonym(25, synonym_type, 40, insert_before) 118fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 119fd4e5da5Sopenharmony_ci 120fd4e5da5Sopenharmony_ci // Instruction with |result_id| is an OpConstantNull. 121fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationAddSynonym(26, synonym_type, 40, insert_before) 122fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 123fd4e5da5Sopenharmony_ci 124fd4e5da5Sopenharmony_ci // |result_id| is irrelevant. 125fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationAddSynonym(24, synonym_type, 40, insert_before) 126fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 127fd4e5da5Sopenharmony_ci 128fd4e5da5Sopenharmony_ci // |insert_before| is invalid. 129fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationAddSynonym( 130fd4e5da5Sopenharmony_ci 9, synonym_type, 40, 131fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(25, spv::Op::OpStore, 0)) 132fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 133fd4e5da5Sopenharmony_ci 134fd4e5da5Sopenharmony_ci // Can't insert before |insert_before|. 135fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationAddSynonym( 136fd4e5da5Sopenharmony_ci 9, synonym_type, 40, 137fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(5, spv::Op::OpLabel, 0)) 138fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 139fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationAddSynonym( 140fd4e5da5Sopenharmony_ci 9, synonym_type, 40, 141fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(22, spv::Op::OpVariable, 0)) 142fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 143fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationAddSynonym( 144fd4e5da5Sopenharmony_ci 9, synonym_type, 40, 145fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(25, spv::Op::OpFunctionEnd, 0)) 146fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 147fd4e5da5Sopenharmony_ci 148fd4e5da5Sopenharmony_ci // Domination rules are not satisfied. 149fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationAddSynonym( 150fd4e5da5Sopenharmony_ci 27, synonym_type, 40, 151fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(27, spv::Op::OpLoad, 0)) 152fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 153fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationAddSynonym( 154fd4e5da5Sopenharmony_ci 27, synonym_type, 40, 155fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(22, spv::Op::OpStore, 1)) 156fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 157fd4e5da5Sopenharmony_ci } 158fd4e5da5Sopenharmony_ci} 159fd4e5da5Sopenharmony_ci 160fd4e5da5Sopenharmony_ciTEST(TransformationAddSynonymTest, AddZeroSubZeroMulOne) { 161fd4e5da5Sopenharmony_ci std::string shader = R"( 162fd4e5da5Sopenharmony_ci OpCapability Shader 163fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 164fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 165fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 166fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 167fd4e5da5Sopenharmony_ci OpSource ESSL 310 168fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 169fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 170fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 171fd4e5da5Sopenharmony_ci %7 = OpConstant %6 0 172fd4e5da5Sopenharmony_ci %8 = OpConstant %6 1 173fd4e5da5Sopenharmony_ci %9 = OpConstant %6 34 174fd4e5da5Sopenharmony_ci %10 = OpTypeInt 32 0 175fd4e5da5Sopenharmony_ci %13 = OpConstant %10 34 176fd4e5da5Sopenharmony_ci %14 = OpTypeFloat 32 177fd4e5da5Sopenharmony_ci %15 = OpConstant %14 0 178fd4e5da5Sopenharmony_ci %16 = OpConstant %14 1 179fd4e5da5Sopenharmony_ci %17 = OpConstant %14 34 180fd4e5da5Sopenharmony_ci %18 = OpTypeVector %14 2 181fd4e5da5Sopenharmony_ci %19 = OpConstantComposite %18 %15 %15 182fd4e5da5Sopenharmony_ci %20 = OpConstantComposite %18 %16 %16 183fd4e5da5Sopenharmony_ci %21 = OpConstant %14 3 184fd4e5da5Sopenharmony_ci %22 = OpConstant %14 4 185fd4e5da5Sopenharmony_ci %23 = OpConstantComposite %18 %21 %22 186fd4e5da5Sopenharmony_ci %24 = OpTypeVector %6 2 187fd4e5da5Sopenharmony_ci %25 = OpConstantComposite %24 %7 %7 188fd4e5da5Sopenharmony_ci %26 = OpConstantComposite %24 %8 %8 189fd4e5da5Sopenharmony_ci %27 = OpConstant %6 3 190fd4e5da5Sopenharmony_ci %28 = OpConstant %6 4 191fd4e5da5Sopenharmony_ci %29 = OpConstantComposite %24 %27 %28 192fd4e5da5Sopenharmony_ci %30 = OpTypeVector %10 2 193fd4e5da5Sopenharmony_ci %33 = OpConstant %10 3 194fd4e5da5Sopenharmony_ci %34 = OpConstant %10 4 195fd4e5da5Sopenharmony_ci %35 = OpConstantComposite %30 %33 %34 196fd4e5da5Sopenharmony_ci %36 = OpTypeBool 197fd4e5da5Sopenharmony_ci %37 = OpTypeVector %36 2 198fd4e5da5Sopenharmony_ci %38 = OpConstantTrue %36 199fd4e5da5Sopenharmony_ci %39 = OpConstantComposite %37 %38 %38 200fd4e5da5Sopenharmony_ci %40 = OpConstant %6 37 201fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 202fd4e5da5Sopenharmony_ci %5 = OpLabel 203fd4e5da5Sopenharmony_ci OpReturn 204fd4e5da5Sopenharmony_ci OpFunctionEnd 205fd4e5da5Sopenharmony_ci )"; 206fd4e5da5Sopenharmony_ci 207fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 208fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 209fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); 210fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 211fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 212fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 213fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 214fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(context.get()), validator_options); 215fd4e5da5Sopenharmony_ci auto insert_before = MakeInstructionDescriptor(5, spv::Op::OpReturn, 0); 216fd4e5da5Sopenharmony_ci 217fd4e5da5Sopenharmony_ci uint32_t fresh_id = 50; 218fd4e5da5Sopenharmony_ci for (auto synonym_type : {protobufs::TransformationAddSynonym::ADD_ZERO, 219fd4e5da5Sopenharmony_ci protobufs::TransformationAddSynonym::SUB_ZERO, 220fd4e5da5Sopenharmony_ci protobufs::TransformationAddSynonym::MUL_ONE}) { 221fd4e5da5Sopenharmony_ci ASSERT_TRUE( 222fd4e5da5Sopenharmony_ci TransformationAddSynonym::IsAdditionalConstantRequired(synonym_type)); 223fd4e5da5Sopenharmony_ci 224fd4e5da5Sopenharmony_ci // Can't create a synonym of a scalar or a vector of a wrong (in this case - 225fd4e5da5Sopenharmony_ci // boolean) type. 226fd4e5da5Sopenharmony_ci ASSERT_FALSE( 227fd4e5da5Sopenharmony_ci TransformationAddSynonym(38, synonym_type, fresh_id, insert_before) 228fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 229fd4e5da5Sopenharmony_ci ASSERT_FALSE( 230fd4e5da5Sopenharmony_ci TransformationAddSynonym(39, synonym_type, fresh_id, insert_before) 231fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 232fd4e5da5Sopenharmony_ci 233fd4e5da5Sopenharmony_ci // Required constant is not present in the module. 234fd4e5da5Sopenharmony_ci ASSERT_FALSE( 235fd4e5da5Sopenharmony_ci TransformationAddSynonym(13, synonym_type, fresh_id, insert_before) 236fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 237fd4e5da5Sopenharmony_ci ASSERT_FALSE( 238fd4e5da5Sopenharmony_ci TransformationAddSynonym(35, synonym_type, fresh_id, insert_before) 239fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 240fd4e5da5Sopenharmony_ci 241fd4e5da5Sopenharmony_ci for (auto result_id : {9, 17, 23, 29}) { 242fd4e5da5Sopenharmony_ci TransformationAddSynonym transformation(result_id, synonym_type, fresh_id, 243fd4e5da5Sopenharmony_ci insert_before); 244fd4e5da5Sopenharmony_ci ASSERT_TRUE( 245fd4e5da5Sopenharmony_ci transformation.IsApplicable(context.get(), transformation_context)); 246fd4e5da5Sopenharmony_ci ApplyAndCheckFreshIds(transformation, context.get(), 247fd4e5da5Sopenharmony_ci &transformation_context); 248fd4e5da5Sopenharmony_ci ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( 249fd4e5da5Sopenharmony_ci MakeDataDescriptor(result_id, {}), MakeDataDescriptor(fresh_id, {}))); 250fd4e5da5Sopenharmony_ci ++fresh_id; 251fd4e5da5Sopenharmony_ci } 252fd4e5da5Sopenharmony_ci } 253fd4e5da5Sopenharmony_ci { 254fd4e5da5Sopenharmony_ci TransformationAddSynonym transformation( 255fd4e5da5Sopenharmony_ci 40, protobufs::TransformationAddSynonym::BITWISE_OR, fresh_id, 256fd4e5da5Sopenharmony_ci insert_before); 257fd4e5da5Sopenharmony_ci ASSERT_TRUE( 258fd4e5da5Sopenharmony_ci transformation.IsApplicable(context.get(), transformation_context)); 259fd4e5da5Sopenharmony_ci ApplyAndCheckFreshIds(transformation, context.get(), 260fd4e5da5Sopenharmony_ci &transformation_context); 261fd4e5da5Sopenharmony_ci ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( 262fd4e5da5Sopenharmony_ci MakeDataDescriptor(40, {}), MakeDataDescriptor(fresh_id, {}))); 263fd4e5da5Sopenharmony_ci ++fresh_id; 264fd4e5da5Sopenharmony_ci } 265fd4e5da5Sopenharmony_ci { 266fd4e5da5Sopenharmony_ci TransformationAddSynonym transformation( 267fd4e5da5Sopenharmony_ci 40, protobufs::TransformationAddSynonym::BITWISE_XOR, fresh_id, 268fd4e5da5Sopenharmony_ci insert_before); 269fd4e5da5Sopenharmony_ci ASSERT_TRUE( 270fd4e5da5Sopenharmony_ci transformation.IsApplicable(context.get(), transformation_context)); 271fd4e5da5Sopenharmony_ci ApplyAndCheckFreshIds(transformation, context.get(), 272fd4e5da5Sopenharmony_ci &transformation_context); 273fd4e5da5Sopenharmony_ci ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( 274fd4e5da5Sopenharmony_ci MakeDataDescriptor(40, {}), MakeDataDescriptor(fresh_id, {}))); 275fd4e5da5Sopenharmony_ci } 276fd4e5da5Sopenharmony_ci 277fd4e5da5Sopenharmony_ci std::string expected_shader = R"( 278fd4e5da5Sopenharmony_ci OpCapability Shader 279fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 280fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 281fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 282fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 283fd4e5da5Sopenharmony_ci OpSource ESSL 310 284fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 285fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 286fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 287fd4e5da5Sopenharmony_ci %7 = OpConstant %6 0 288fd4e5da5Sopenharmony_ci %8 = OpConstant %6 1 289fd4e5da5Sopenharmony_ci %9 = OpConstant %6 34 290fd4e5da5Sopenharmony_ci %10 = OpTypeInt 32 0 291fd4e5da5Sopenharmony_ci %13 = OpConstant %10 34 292fd4e5da5Sopenharmony_ci %14 = OpTypeFloat 32 293fd4e5da5Sopenharmony_ci %15 = OpConstant %14 0 294fd4e5da5Sopenharmony_ci %16 = OpConstant %14 1 295fd4e5da5Sopenharmony_ci %17 = OpConstant %14 34 296fd4e5da5Sopenharmony_ci %18 = OpTypeVector %14 2 297fd4e5da5Sopenharmony_ci %19 = OpConstantComposite %18 %15 %15 298fd4e5da5Sopenharmony_ci %20 = OpConstantComposite %18 %16 %16 299fd4e5da5Sopenharmony_ci %21 = OpConstant %14 3 300fd4e5da5Sopenharmony_ci %22 = OpConstant %14 4 301fd4e5da5Sopenharmony_ci %23 = OpConstantComposite %18 %21 %22 302fd4e5da5Sopenharmony_ci %24 = OpTypeVector %6 2 303fd4e5da5Sopenharmony_ci %25 = OpConstantComposite %24 %7 %7 304fd4e5da5Sopenharmony_ci %26 = OpConstantComposite %24 %8 %8 305fd4e5da5Sopenharmony_ci %27 = OpConstant %6 3 306fd4e5da5Sopenharmony_ci %28 = OpConstant %6 4 307fd4e5da5Sopenharmony_ci %29 = OpConstantComposite %24 %27 %28 308fd4e5da5Sopenharmony_ci %30 = OpTypeVector %10 2 309fd4e5da5Sopenharmony_ci %33 = OpConstant %10 3 310fd4e5da5Sopenharmony_ci %34 = OpConstant %10 4 311fd4e5da5Sopenharmony_ci %35 = OpConstantComposite %30 %33 %34 312fd4e5da5Sopenharmony_ci %36 = OpTypeBool 313fd4e5da5Sopenharmony_ci %37 = OpTypeVector %36 2 314fd4e5da5Sopenharmony_ci %38 = OpConstantTrue %36 315fd4e5da5Sopenharmony_ci %39 = OpConstantComposite %37 %38 %38 316fd4e5da5Sopenharmony_ci %40 = OpConstant %6 37 317fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 318fd4e5da5Sopenharmony_ci %5 = OpLabel 319fd4e5da5Sopenharmony_ci %50 = OpIAdd %6 %9 %7 320fd4e5da5Sopenharmony_ci %51 = OpFAdd %14 %17 %15 321fd4e5da5Sopenharmony_ci %52 = OpFAdd %18 %23 %19 322fd4e5da5Sopenharmony_ci %53 = OpIAdd %24 %29 %25 323fd4e5da5Sopenharmony_ci %54 = OpISub %6 %9 %7 324fd4e5da5Sopenharmony_ci %55 = OpFSub %14 %17 %15 325fd4e5da5Sopenharmony_ci %56 = OpFSub %18 %23 %19 326fd4e5da5Sopenharmony_ci %57 = OpISub %24 %29 %25 327fd4e5da5Sopenharmony_ci %58 = OpIMul %6 %9 %8 328fd4e5da5Sopenharmony_ci %59 = OpFMul %14 %17 %16 329fd4e5da5Sopenharmony_ci %60 = OpFMul %18 %23 %20 330fd4e5da5Sopenharmony_ci %61 = OpIMul %24 %29 %26 331fd4e5da5Sopenharmony_ci %62 = OpBitwiseOr %6 %40 %7 332fd4e5da5Sopenharmony_ci %63 = OpBitwiseXor %6 %40 %7 333fd4e5da5Sopenharmony_ci OpReturn 334fd4e5da5Sopenharmony_ci OpFunctionEnd 335fd4e5da5Sopenharmony_ci )"; 336fd4e5da5Sopenharmony_ci 337fd4e5da5Sopenharmony_ci ASSERT_TRUE(IsEqual(env, expected_shader, context.get())); 338fd4e5da5Sopenharmony_ci} 339fd4e5da5Sopenharmony_ci 340fd4e5da5Sopenharmony_ciTEST(TransformationAddSynonymTest, LogicalAndLogicalOr) { 341fd4e5da5Sopenharmony_ci std::string shader = R"( 342fd4e5da5Sopenharmony_ci OpCapability Shader 343fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 344fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 345fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 346fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 347fd4e5da5Sopenharmony_ci OpSource ESSL 310 348fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 349fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 350fd4e5da5Sopenharmony_ci %6 = OpTypeBool 351fd4e5da5Sopenharmony_ci %7 = OpConstantFalse %6 352fd4e5da5Sopenharmony_ci %9 = OpConstantTrue %6 353fd4e5da5Sopenharmony_ci %10 = OpTypeVector %6 2 354fd4e5da5Sopenharmony_ci %11 = OpConstantComposite %10 %7 %9 355fd4e5da5Sopenharmony_ci %12 = OpConstantComposite %10 %7 %7 356fd4e5da5Sopenharmony_ci %13 = OpConstantComposite %10 %9 %9 357fd4e5da5Sopenharmony_ci %14 = OpTypeFloat 32 358fd4e5da5Sopenharmony_ci %17 = OpConstant %14 35 359fd4e5da5Sopenharmony_ci %18 = OpTypeVector %14 2 360fd4e5da5Sopenharmony_ci %21 = OpConstant %14 3 361fd4e5da5Sopenharmony_ci %22 = OpConstant %14 4 362fd4e5da5Sopenharmony_ci %23 = OpConstantComposite %18 %21 %22 363fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 364fd4e5da5Sopenharmony_ci %5 = OpLabel 365fd4e5da5Sopenharmony_ci OpReturn 366fd4e5da5Sopenharmony_ci OpFunctionEnd 367fd4e5da5Sopenharmony_ci )"; 368fd4e5da5Sopenharmony_ci 369fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 370fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 371fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); 372fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 373fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 374fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 375fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 376fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(context.get()), validator_options); 377fd4e5da5Sopenharmony_ci auto insert_before = MakeInstructionDescriptor(5, spv::Op::OpReturn, 0); 378fd4e5da5Sopenharmony_ci 379fd4e5da5Sopenharmony_ci uint32_t fresh_id = 50; 380fd4e5da5Sopenharmony_ci for (auto synonym_type : {protobufs::TransformationAddSynonym::LOGICAL_AND, 381fd4e5da5Sopenharmony_ci protobufs::TransformationAddSynonym::LOGICAL_OR}) { 382fd4e5da5Sopenharmony_ci ASSERT_TRUE( 383fd4e5da5Sopenharmony_ci TransformationAddSynonym::IsAdditionalConstantRequired(synonym_type)); 384fd4e5da5Sopenharmony_ci 385fd4e5da5Sopenharmony_ci // Can't create a synonym of a scalar or a vector of a wrong (in this case - 386fd4e5da5Sopenharmony_ci // float) type. 387fd4e5da5Sopenharmony_ci ASSERT_FALSE( 388fd4e5da5Sopenharmony_ci TransformationAddSynonym(17, synonym_type, fresh_id, insert_before) 389fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 390fd4e5da5Sopenharmony_ci ASSERT_FALSE( 391fd4e5da5Sopenharmony_ci TransformationAddSynonym(23, synonym_type, fresh_id, insert_before) 392fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 393fd4e5da5Sopenharmony_ci 394fd4e5da5Sopenharmony_ci for (auto result_id : {9, 11}) { 395fd4e5da5Sopenharmony_ci TransformationAddSynonym transformation(result_id, synonym_type, fresh_id, 396fd4e5da5Sopenharmony_ci insert_before); 397fd4e5da5Sopenharmony_ci ASSERT_TRUE( 398fd4e5da5Sopenharmony_ci transformation.IsApplicable(context.get(), transformation_context)); 399fd4e5da5Sopenharmony_ci ApplyAndCheckFreshIds(transformation, context.get(), 400fd4e5da5Sopenharmony_ci &transformation_context); 401fd4e5da5Sopenharmony_ci ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( 402fd4e5da5Sopenharmony_ci MakeDataDescriptor(result_id, {}), MakeDataDescriptor(fresh_id, {}))); 403fd4e5da5Sopenharmony_ci ++fresh_id; 404fd4e5da5Sopenharmony_ci } 405fd4e5da5Sopenharmony_ci } 406fd4e5da5Sopenharmony_ci 407fd4e5da5Sopenharmony_ci std::string expected_shader = R"( 408fd4e5da5Sopenharmony_ci OpCapability Shader 409fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 410fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 411fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 412fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 413fd4e5da5Sopenharmony_ci OpSource ESSL 310 414fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 415fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 416fd4e5da5Sopenharmony_ci %6 = OpTypeBool 417fd4e5da5Sopenharmony_ci %7 = OpConstantFalse %6 418fd4e5da5Sopenharmony_ci %9 = OpConstantTrue %6 419fd4e5da5Sopenharmony_ci %10 = OpTypeVector %6 2 420fd4e5da5Sopenharmony_ci %11 = OpConstantComposite %10 %7 %9 421fd4e5da5Sopenharmony_ci %12 = OpConstantComposite %10 %7 %7 422fd4e5da5Sopenharmony_ci %13 = OpConstantComposite %10 %9 %9 423fd4e5da5Sopenharmony_ci %14 = OpTypeFloat 32 424fd4e5da5Sopenharmony_ci %17 = OpConstant %14 35 425fd4e5da5Sopenharmony_ci %18 = OpTypeVector %14 2 426fd4e5da5Sopenharmony_ci %21 = OpConstant %14 3 427fd4e5da5Sopenharmony_ci %22 = OpConstant %14 4 428fd4e5da5Sopenharmony_ci %23 = OpConstantComposite %18 %21 %22 429fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 430fd4e5da5Sopenharmony_ci %5 = OpLabel 431fd4e5da5Sopenharmony_ci %50 = OpLogicalAnd %6 %9 %9 432fd4e5da5Sopenharmony_ci %51 = OpLogicalAnd %10 %11 %13 433fd4e5da5Sopenharmony_ci %52 = OpLogicalOr %6 %9 %7 434fd4e5da5Sopenharmony_ci %53 = OpLogicalOr %10 %11 %12 435fd4e5da5Sopenharmony_ci OpReturn 436fd4e5da5Sopenharmony_ci OpFunctionEnd 437fd4e5da5Sopenharmony_ci )"; 438fd4e5da5Sopenharmony_ci 439fd4e5da5Sopenharmony_ci ASSERT_TRUE(IsEqual(env, expected_shader, context.get())); 440fd4e5da5Sopenharmony_ci} 441fd4e5da5Sopenharmony_ci 442fd4e5da5Sopenharmony_ciTEST(TransformationAddSynonymTest, LogicalAndConstantIsNotPresent) { 443fd4e5da5Sopenharmony_ci std::string shader = R"( 444fd4e5da5Sopenharmony_ci OpCapability Shader 445fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 446fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 447fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 448fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 449fd4e5da5Sopenharmony_ci OpSource ESSL 310 450fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 451fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 452fd4e5da5Sopenharmony_ci %6 = OpTypeBool 453fd4e5da5Sopenharmony_ci %7 = OpConstantFalse %6 454fd4e5da5Sopenharmony_ci %10 = OpTypeVector %6 2 455fd4e5da5Sopenharmony_ci %12 = OpConstantComposite %10 %7 %7 456fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 457fd4e5da5Sopenharmony_ci %5 = OpLabel 458fd4e5da5Sopenharmony_ci OpReturn 459fd4e5da5Sopenharmony_ci OpFunctionEnd 460fd4e5da5Sopenharmony_ci )"; 461fd4e5da5Sopenharmony_ci 462fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 463fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 464fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); 465fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 466fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 467fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 468fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 469fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(context.get()), validator_options); 470fd4e5da5Sopenharmony_ci auto insert_before = MakeInstructionDescriptor(5, spv::Op::OpReturn, 0); 471fd4e5da5Sopenharmony_ci const auto synonym_type = protobufs::TransformationAddSynonym::LOGICAL_AND; 472fd4e5da5Sopenharmony_ci 473fd4e5da5Sopenharmony_ci // Required constant is not present in the module. 474fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationAddSynonym(7, synonym_type, 50, insert_before) 475fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 476fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationAddSynonym(12, synonym_type, 50, insert_before) 477fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 478fd4e5da5Sopenharmony_ci} 479fd4e5da5Sopenharmony_ci 480fd4e5da5Sopenharmony_ciTEST(TransformationAddSynonymTest, LogicalOrConstantIsNotPresent) { 481fd4e5da5Sopenharmony_ci std::string shader = R"( 482fd4e5da5Sopenharmony_ci OpCapability Shader 483fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 484fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 485fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 486fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 487fd4e5da5Sopenharmony_ci OpSource ESSL 310 488fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 489fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 490fd4e5da5Sopenharmony_ci %6 = OpTypeBool 491fd4e5da5Sopenharmony_ci %7 = OpConstantTrue %6 492fd4e5da5Sopenharmony_ci %10 = OpTypeVector %6 2 493fd4e5da5Sopenharmony_ci %12 = OpConstantComposite %10 %7 %7 494fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 495fd4e5da5Sopenharmony_ci %5 = OpLabel 496fd4e5da5Sopenharmony_ci OpReturn 497fd4e5da5Sopenharmony_ci OpFunctionEnd 498fd4e5da5Sopenharmony_ci )"; 499fd4e5da5Sopenharmony_ci 500fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 501fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 502fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); 503fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 504fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 505fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 506fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 507fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(context.get()), validator_options); 508fd4e5da5Sopenharmony_ci auto insert_before = MakeInstructionDescriptor(5, spv::Op::OpReturn, 0); 509fd4e5da5Sopenharmony_ci const auto synonym_type = protobufs::TransformationAddSynonym::LOGICAL_OR; 510fd4e5da5Sopenharmony_ci 511fd4e5da5Sopenharmony_ci // Required constant is not present in the module. 512fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationAddSynonym(7, synonym_type, 50, insert_before) 513fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 514fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationAddSynonym(12, synonym_type, 50, insert_before) 515fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 516fd4e5da5Sopenharmony_ci} 517fd4e5da5Sopenharmony_ci 518fd4e5da5Sopenharmony_ciTEST(TransformationAddSynonymTest, CopyObject) { 519fd4e5da5Sopenharmony_ci std::string shader = R"( 520fd4e5da5Sopenharmony_ci OpCapability Shader 521fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 522fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 523fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 524fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 525fd4e5da5Sopenharmony_ci OpSource ESSL 310 526fd4e5da5Sopenharmony_ci OpDecorate %8 RelaxedPrecision 527fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 528fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 529fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 530fd4e5da5Sopenharmony_ci %7 = OpTypePointer Function %6 531fd4e5da5Sopenharmony_ci %9 = OpConstant %6 4 532fd4e5da5Sopenharmony_ci %10 = OpTypeFloat 32 533fd4e5da5Sopenharmony_ci %11 = OpTypePointer Function %10 534fd4e5da5Sopenharmony_ci %13 = OpConstant %10 4 535fd4e5da5Sopenharmony_ci %14 = OpTypeVector %10 2 536fd4e5da5Sopenharmony_ci %15 = OpTypePointer Function %14 537fd4e5da5Sopenharmony_ci %17 = OpConstant %10 3.4000001 538fd4e5da5Sopenharmony_ci %18 = OpConstantComposite %14 %17 %17 539fd4e5da5Sopenharmony_ci %19 = OpTypeBool 540fd4e5da5Sopenharmony_ci %20 = OpTypeStruct %19 541fd4e5da5Sopenharmony_ci %21 = OpTypePointer Function %20 542fd4e5da5Sopenharmony_ci %23 = OpConstantTrue %19 543fd4e5da5Sopenharmony_ci %24 = OpConstantComposite %20 %23 544fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 545fd4e5da5Sopenharmony_ci %5 = OpLabel 546fd4e5da5Sopenharmony_ci %8 = OpVariable %7 Function 547fd4e5da5Sopenharmony_ci %12 = OpVariable %11 Function 548fd4e5da5Sopenharmony_ci %16 = OpVariable %15 Function 549fd4e5da5Sopenharmony_ci %22 = OpVariable %21 Function 550fd4e5da5Sopenharmony_ci OpStore %8 %9 551fd4e5da5Sopenharmony_ci OpStore %12 %13 552fd4e5da5Sopenharmony_ci OpStore %16 %18 553fd4e5da5Sopenharmony_ci OpStore %22 %24 554fd4e5da5Sopenharmony_ci OpReturn 555fd4e5da5Sopenharmony_ci OpFunctionEnd 556fd4e5da5Sopenharmony_ci )"; 557fd4e5da5Sopenharmony_ci 558fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 559fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 560fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); 561fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 562fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 563fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 564fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 565fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(context.get()), validator_options); 566fd4e5da5Sopenharmony_ci auto insert_before = MakeInstructionDescriptor(5, spv::Op::OpReturn, 0); 567fd4e5da5Sopenharmony_ci const auto synonym_type = protobufs::TransformationAddSynonym::COPY_OBJECT; 568fd4e5da5Sopenharmony_ci 569fd4e5da5Sopenharmony_ci ASSERT_FALSE( 570fd4e5da5Sopenharmony_ci TransformationAddSynonym::IsAdditionalConstantRequired(synonym_type)); 571fd4e5da5Sopenharmony_ci 572fd4e5da5Sopenharmony_ci uint32_t fresh_id = 50; 573fd4e5da5Sopenharmony_ci for (auto result_id : {9, 13, 17, 18, 23, 24, 22}) { 574fd4e5da5Sopenharmony_ci TransformationAddSynonym transformation(result_id, synonym_type, fresh_id, 575fd4e5da5Sopenharmony_ci insert_before); 576fd4e5da5Sopenharmony_ci ASSERT_TRUE( 577fd4e5da5Sopenharmony_ci transformation.IsApplicable(context.get(), transformation_context)); 578fd4e5da5Sopenharmony_ci ApplyAndCheckFreshIds(transformation, context.get(), 579fd4e5da5Sopenharmony_ci &transformation_context); 580fd4e5da5Sopenharmony_ci ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( 581fd4e5da5Sopenharmony_ci MakeDataDescriptor(result_id, {}), MakeDataDescriptor(fresh_id, {}))); 582fd4e5da5Sopenharmony_ci ++fresh_id; 583fd4e5da5Sopenharmony_ci } 584fd4e5da5Sopenharmony_ci 585fd4e5da5Sopenharmony_ci std::string expected_shader = R"( 586fd4e5da5Sopenharmony_ci OpCapability Shader 587fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 588fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 589fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 590fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 591fd4e5da5Sopenharmony_ci OpSource ESSL 310 592fd4e5da5Sopenharmony_ci OpDecorate %8 RelaxedPrecision 593fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 594fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 595fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 596fd4e5da5Sopenharmony_ci %7 = OpTypePointer Function %6 597fd4e5da5Sopenharmony_ci %9 = OpConstant %6 4 598fd4e5da5Sopenharmony_ci %10 = OpTypeFloat 32 599fd4e5da5Sopenharmony_ci %11 = OpTypePointer Function %10 600fd4e5da5Sopenharmony_ci %13 = OpConstant %10 4 601fd4e5da5Sopenharmony_ci %14 = OpTypeVector %10 2 602fd4e5da5Sopenharmony_ci %15 = OpTypePointer Function %14 603fd4e5da5Sopenharmony_ci %17 = OpConstant %10 3.4000001 604fd4e5da5Sopenharmony_ci %18 = OpConstantComposite %14 %17 %17 605fd4e5da5Sopenharmony_ci %19 = OpTypeBool 606fd4e5da5Sopenharmony_ci %20 = OpTypeStruct %19 607fd4e5da5Sopenharmony_ci %21 = OpTypePointer Function %20 608fd4e5da5Sopenharmony_ci %23 = OpConstantTrue %19 609fd4e5da5Sopenharmony_ci %24 = OpConstantComposite %20 %23 610fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 611fd4e5da5Sopenharmony_ci %5 = OpLabel 612fd4e5da5Sopenharmony_ci %8 = OpVariable %7 Function 613fd4e5da5Sopenharmony_ci %12 = OpVariable %11 Function 614fd4e5da5Sopenharmony_ci %16 = OpVariable %15 Function 615fd4e5da5Sopenharmony_ci %22 = OpVariable %21 Function 616fd4e5da5Sopenharmony_ci OpStore %8 %9 617fd4e5da5Sopenharmony_ci OpStore %12 %13 618fd4e5da5Sopenharmony_ci OpStore %16 %18 619fd4e5da5Sopenharmony_ci OpStore %22 %24 620fd4e5da5Sopenharmony_ci %50 = OpCopyObject %6 %9 621fd4e5da5Sopenharmony_ci %51 = OpCopyObject %10 %13 622fd4e5da5Sopenharmony_ci %52 = OpCopyObject %10 %17 623fd4e5da5Sopenharmony_ci %53 = OpCopyObject %14 %18 624fd4e5da5Sopenharmony_ci %54 = OpCopyObject %19 %23 625fd4e5da5Sopenharmony_ci %55 = OpCopyObject %20 %24 626fd4e5da5Sopenharmony_ci %56 = OpCopyObject %21 %22 627fd4e5da5Sopenharmony_ci OpReturn 628fd4e5da5Sopenharmony_ci OpFunctionEnd 629fd4e5da5Sopenharmony_ci )"; 630fd4e5da5Sopenharmony_ci 631fd4e5da5Sopenharmony_ci ASSERT_TRUE(IsEqual(env, expected_shader, context.get())); 632fd4e5da5Sopenharmony_ci} 633fd4e5da5Sopenharmony_ci 634fd4e5da5Sopenharmony_ciTEST(TransformationAddSynonymTest, CopyBooleanConstants) { 635fd4e5da5Sopenharmony_ci std::string shader = R"( 636fd4e5da5Sopenharmony_ci OpCapability Shader 637fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 638fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 639fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 640fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 641fd4e5da5Sopenharmony_ci OpSource ESSL 310 642fd4e5da5Sopenharmony_ci OpName %4 "main" 643fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 644fd4e5da5Sopenharmony_ci %6 = OpTypeBool 645fd4e5da5Sopenharmony_ci %7 = OpConstantTrue %6 646fd4e5da5Sopenharmony_ci %8 = OpConstantFalse %6 647fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 648fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 649fd4e5da5Sopenharmony_ci %5 = OpLabel 650fd4e5da5Sopenharmony_ci OpReturn 651fd4e5da5Sopenharmony_ci OpFunctionEnd 652fd4e5da5Sopenharmony_ci )"; 653fd4e5da5Sopenharmony_ci 654fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 655fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 656fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); 657fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 658fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 659fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 660fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 661fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(context.get()), validator_options); 662fd4e5da5Sopenharmony_ci ASSERT_EQ(0, transformation_context.GetFactManager() 663fd4e5da5Sopenharmony_ci ->GetIdsForWhichSynonymsAreKnown() 664fd4e5da5Sopenharmony_ci .size()); 665fd4e5da5Sopenharmony_ci 666fd4e5da5Sopenharmony_ci { 667fd4e5da5Sopenharmony_ci TransformationAddSynonym copy_true( 668fd4e5da5Sopenharmony_ci 7, protobufs::TransformationAddSynonym::COPY_OBJECT, 100, 669fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(5, spv::Op::OpReturn, 0)); 670fd4e5da5Sopenharmony_ci ASSERT_TRUE(copy_true.IsApplicable(context.get(), transformation_context)); 671fd4e5da5Sopenharmony_ci ApplyAndCheckFreshIds(copy_true, context.get(), &transformation_context); 672fd4e5da5Sopenharmony_ci 673fd4e5da5Sopenharmony_ci std::vector<uint32_t> ids_for_which_synonyms_are_known = 674fd4e5da5Sopenharmony_ci transformation_context.GetFactManager() 675fd4e5da5Sopenharmony_ci ->GetIdsForWhichSynonymsAreKnown(); 676fd4e5da5Sopenharmony_ci ASSERT_EQ(2, ids_for_which_synonyms_are_known.size()); 677fd4e5da5Sopenharmony_ci ASSERT_TRUE(std::find(ids_for_which_synonyms_are_known.begin(), 678fd4e5da5Sopenharmony_ci ids_for_which_synonyms_are_known.end(), 679fd4e5da5Sopenharmony_ci 7) != ids_for_which_synonyms_are_known.end()); 680fd4e5da5Sopenharmony_ci ASSERT_EQ( 681fd4e5da5Sopenharmony_ci 2, transformation_context.GetFactManager()->GetSynonymsForId(7).size()); 682fd4e5da5Sopenharmony_ci protobufs::DataDescriptor descriptor_100 = MakeDataDescriptor(100, {}); 683fd4e5da5Sopenharmony_ci ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( 684fd4e5da5Sopenharmony_ci MakeDataDescriptor(7, {}), descriptor_100)); 685fd4e5da5Sopenharmony_ci } 686fd4e5da5Sopenharmony_ci 687fd4e5da5Sopenharmony_ci { 688fd4e5da5Sopenharmony_ci TransformationAddSynonym copy_false( 689fd4e5da5Sopenharmony_ci 8, protobufs::TransformationAddSynonym::COPY_OBJECT, 101, 690fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(100, spv::Op::OpReturn, 0)); 691fd4e5da5Sopenharmony_ci ASSERT_TRUE(copy_false.IsApplicable(context.get(), transformation_context)); 692fd4e5da5Sopenharmony_ci ApplyAndCheckFreshIds(copy_false, context.get(), &transformation_context); 693fd4e5da5Sopenharmony_ci std::vector<uint32_t> ids_for_which_synonyms_are_known = 694fd4e5da5Sopenharmony_ci transformation_context.GetFactManager() 695fd4e5da5Sopenharmony_ci ->GetIdsForWhichSynonymsAreKnown(); 696fd4e5da5Sopenharmony_ci ASSERT_EQ(4, ids_for_which_synonyms_are_known.size()); 697fd4e5da5Sopenharmony_ci ASSERT_TRUE(std::find(ids_for_which_synonyms_are_known.begin(), 698fd4e5da5Sopenharmony_ci ids_for_which_synonyms_are_known.end(), 699fd4e5da5Sopenharmony_ci 8) != ids_for_which_synonyms_are_known.end()); 700fd4e5da5Sopenharmony_ci ASSERT_EQ( 701fd4e5da5Sopenharmony_ci 2, transformation_context.GetFactManager()->GetSynonymsForId(8).size()); 702fd4e5da5Sopenharmony_ci protobufs::DataDescriptor descriptor_101 = MakeDataDescriptor(101, {}); 703fd4e5da5Sopenharmony_ci ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( 704fd4e5da5Sopenharmony_ci MakeDataDescriptor(8, {}), descriptor_101)); 705fd4e5da5Sopenharmony_ci } 706fd4e5da5Sopenharmony_ci 707fd4e5da5Sopenharmony_ci { 708fd4e5da5Sopenharmony_ci TransformationAddSynonym copy_false_again( 709fd4e5da5Sopenharmony_ci 101, protobufs::TransformationAddSynonym::COPY_OBJECT, 102, 710fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(5, spv::Op::OpReturn, 0)); 711fd4e5da5Sopenharmony_ci ASSERT_TRUE( 712fd4e5da5Sopenharmony_ci copy_false_again.IsApplicable(context.get(), transformation_context)); 713fd4e5da5Sopenharmony_ci ApplyAndCheckFreshIds(copy_false_again, context.get(), 714fd4e5da5Sopenharmony_ci &transformation_context); 715fd4e5da5Sopenharmony_ci std::vector<uint32_t> ids_for_which_synonyms_are_known = 716fd4e5da5Sopenharmony_ci transformation_context.GetFactManager() 717fd4e5da5Sopenharmony_ci ->GetIdsForWhichSynonymsAreKnown(); 718fd4e5da5Sopenharmony_ci ASSERT_EQ(5, ids_for_which_synonyms_are_known.size()); 719fd4e5da5Sopenharmony_ci ASSERT_TRUE(std::find(ids_for_which_synonyms_are_known.begin(), 720fd4e5da5Sopenharmony_ci ids_for_which_synonyms_are_known.end(), 721fd4e5da5Sopenharmony_ci 101) != ids_for_which_synonyms_are_known.end()); 722fd4e5da5Sopenharmony_ci ASSERT_EQ( 723fd4e5da5Sopenharmony_ci 3, 724fd4e5da5Sopenharmony_ci transformation_context.GetFactManager()->GetSynonymsForId(101).size()); 725fd4e5da5Sopenharmony_ci protobufs::DataDescriptor descriptor_102 = MakeDataDescriptor(102, {}); 726fd4e5da5Sopenharmony_ci ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( 727fd4e5da5Sopenharmony_ci MakeDataDescriptor(101, {}), descriptor_102)); 728fd4e5da5Sopenharmony_ci } 729fd4e5da5Sopenharmony_ci 730fd4e5da5Sopenharmony_ci { 731fd4e5da5Sopenharmony_ci TransformationAddSynonym copy_true_again( 732fd4e5da5Sopenharmony_ci 7, protobufs::TransformationAddSynonym::COPY_OBJECT, 103, 733fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(102, spv::Op::OpReturn, 0)); 734fd4e5da5Sopenharmony_ci ASSERT_TRUE( 735fd4e5da5Sopenharmony_ci copy_true_again.IsApplicable(context.get(), transformation_context)); 736fd4e5da5Sopenharmony_ci ApplyAndCheckFreshIds(copy_true_again, context.get(), 737fd4e5da5Sopenharmony_ci &transformation_context); 738fd4e5da5Sopenharmony_ci std::vector<uint32_t> ids_for_which_synonyms_are_known = 739fd4e5da5Sopenharmony_ci transformation_context.GetFactManager() 740fd4e5da5Sopenharmony_ci ->GetIdsForWhichSynonymsAreKnown(); 741fd4e5da5Sopenharmony_ci ASSERT_EQ(6, ids_for_which_synonyms_are_known.size()); 742fd4e5da5Sopenharmony_ci ASSERT_TRUE(std::find(ids_for_which_synonyms_are_known.begin(), 743fd4e5da5Sopenharmony_ci ids_for_which_synonyms_are_known.end(), 744fd4e5da5Sopenharmony_ci 7) != ids_for_which_synonyms_are_known.end()); 745fd4e5da5Sopenharmony_ci ASSERT_EQ( 746fd4e5da5Sopenharmony_ci 3, transformation_context.GetFactManager()->GetSynonymsForId(7).size()); 747fd4e5da5Sopenharmony_ci protobufs::DataDescriptor descriptor_103 = MakeDataDescriptor(103, {}); 748fd4e5da5Sopenharmony_ci ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( 749fd4e5da5Sopenharmony_ci MakeDataDescriptor(7, {}), descriptor_103)); 750fd4e5da5Sopenharmony_ci } 751fd4e5da5Sopenharmony_ci 752fd4e5da5Sopenharmony_ci std::string after_transformation = R"( 753fd4e5da5Sopenharmony_ci OpCapability Shader 754fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 755fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 756fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 757fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 758fd4e5da5Sopenharmony_ci OpSource ESSL 310 759fd4e5da5Sopenharmony_ci OpName %4 "main" 760fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 761fd4e5da5Sopenharmony_ci %6 = OpTypeBool 762fd4e5da5Sopenharmony_ci %7 = OpConstantTrue %6 763fd4e5da5Sopenharmony_ci %8 = OpConstantFalse %6 764fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 765fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 766fd4e5da5Sopenharmony_ci %5 = OpLabel 767fd4e5da5Sopenharmony_ci %100 = OpCopyObject %6 %7 768fd4e5da5Sopenharmony_ci %101 = OpCopyObject %6 %8 769fd4e5da5Sopenharmony_ci %102 = OpCopyObject %6 %101 770fd4e5da5Sopenharmony_ci %103 = OpCopyObject %6 %7 771fd4e5da5Sopenharmony_ci OpReturn 772fd4e5da5Sopenharmony_ci OpFunctionEnd 773fd4e5da5Sopenharmony_ci )"; 774fd4e5da5Sopenharmony_ci 775fd4e5da5Sopenharmony_ci ASSERT_TRUE(IsEqual(env, after_transformation, context.get())); 776fd4e5da5Sopenharmony_ci} 777fd4e5da5Sopenharmony_ci 778fd4e5da5Sopenharmony_ciTEST(TransformationAddSynonymTest, CheckIllegalCases) { 779fd4e5da5Sopenharmony_ci // The following SPIR-V comes from this GLSL, pushed through spirv-opt 780fd4e5da5Sopenharmony_ci // and then doctored a bit. 781fd4e5da5Sopenharmony_ci // 782fd4e5da5Sopenharmony_ci // #version 310 es 783fd4e5da5Sopenharmony_ci // 784fd4e5da5Sopenharmony_ci // precision highp float; 785fd4e5da5Sopenharmony_ci // 786fd4e5da5Sopenharmony_ci // struct S { 787fd4e5da5Sopenharmony_ci // int a; 788fd4e5da5Sopenharmony_ci // float b; 789fd4e5da5Sopenharmony_ci // }; 790fd4e5da5Sopenharmony_ci // 791fd4e5da5Sopenharmony_ci // layout(set = 0, binding = 2) uniform block { 792fd4e5da5Sopenharmony_ci // S s; 793fd4e5da5Sopenharmony_ci // lowp float f; 794fd4e5da5Sopenharmony_ci // int ii; 795fd4e5da5Sopenharmony_ci // } ubuf; 796fd4e5da5Sopenharmony_ci // 797fd4e5da5Sopenharmony_ci // layout(location = 0) out vec4 color; 798fd4e5da5Sopenharmony_ci // 799fd4e5da5Sopenharmony_ci // void main() { 800fd4e5da5Sopenharmony_ci // float c = 0.0; 801fd4e5da5Sopenharmony_ci // lowp float d = 0.0; 802fd4e5da5Sopenharmony_ci // S localS = ubuf.s; 803fd4e5da5Sopenharmony_ci // for (int i = 0; i < ubuf.s.a; i++) { 804fd4e5da5Sopenharmony_ci // switch (ubuf.ii) { 805fd4e5da5Sopenharmony_ci // case 0: 806fd4e5da5Sopenharmony_ci // c += 0.1; 807fd4e5da5Sopenharmony_ci // d += 0.2; 808fd4e5da5Sopenharmony_ci // case 1: 809fd4e5da5Sopenharmony_ci // c += 0.1; 810fd4e5da5Sopenharmony_ci // if (c > d) { 811fd4e5da5Sopenharmony_ci // d += 0.2; 812fd4e5da5Sopenharmony_ci // } else { 813fd4e5da5Sopenharmony_ci // d += c; 814fd4e5da5Sopenharmony_ci // } 815fd4e5da5Sopenharmony_ci // break; 816fd4e5da5Sopenharmony_ci // default: 817fd4e5da5Sopenharmony_ci // i += 1; 818fd4e5da5Sopenharmony_ci // localS.b += d; 819fd4e5da5Sopenharmony_ci // } 820fd4e5da5Sopenharmony_ci // } 821fd4e5da5Sopenharmony_ci // color = vec4(c, d, localS.b, 1.0); 822fd4e5da5Sopenharmony_ci // } 823fd4e5da5Sopenharmony_ci 824fd4e5da5Sopenharmony_ci std::string shader = R"( 825fd4e5da5Sopenharmony_ci OpCapability Shader 826fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 827fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 828fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" %80 829fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 830fd4e5da5Sopenharmony_ci OpSource ESSL 310 831fd4e5da5Sopenharmony_ci OpName %4 "main" 832fd4e5da5Sopenharmony_ci OpName %12 "S" 833fd4e5da5Sopenharmony_ci OpMemberName %12 0 "a" 834fd4e5da5Sopenharmony_ci OpMemberName %12 1 "b" 835fd4e5da5Sopenharmony_ci OpName %15 "S" 836fd4e5da5Sopenharmony_ci OpMemberName %15 0 "a" 837fd4e5da5Sopenharmony_ci OpMemberName %15 1 "b" 838fd4e5da5Sopenharmony_ci OpName %16 "block" 839fd4e5da5Sopenharmony_ci OpMemberName %16 0 "s" 840fd4e5da5Sopenharmony_ci OpMemberName %16 1 "f" 841fd4e5da5Sopenharmony_ci OpMemberName %16 2 "ii" 842fd4e5da5Sopenharmony_ci OpName %18 "ubuf" 843fd4e5da5Sopenharmony_ci OpName %80 "color" 844fd4e5da5Sopenharmony_ci OpMemberDecorate %12 0 RelaxedPrecision 845fd4e5da5Sopenharmony_ci OpMemberDecorate %15 0 RelaxedPrecision 846fd4e5da5Sopenharmony_ci OpMemberDecorate %15 0 Offset 0 847fd4e5da5Sopenharmony_ci OpMemberDecorate %15 1 Offset 4 848fd4e5da5Sopenharmony_ci OpMemberDecorate %16 0 Offset 0 849fd4e5da5Sopenharmony_ci OpMemberDecorate %16 1 RelaxedPrecision 850fd4e5da5Sopenharmony_ci OpMemberDecorate %16 1 Offset 16 851fd4e5da5Sopenharmony_ci OpMemberDecorate %16 2 RelaxedPrecision 852fd4e5da5Sopenharmony_ci OpMemberDecorate %16 2 Offset 20 853fd4e5da5Sopenharmony_ci OpDecorate %16 Block 854fd4e5da5Sopenharmony_ci OpDecorate %18 DescriptorSet 0 855fd4e5da5Sopenharmony_ci OpDecorate %18 Binding 2 856fd4e5da5Sopenharmony_ci OpDecorate %38 RelaxedPrecision 857fd4e5da5Sopenharmony_ci OpDecorate %43 RelaxedPrecision 858fd4e5da5Sopenharmony_ci OpDecorate %53 RelaxedPrecision 859fd4e5da5Sopenharmony_ci OpDecorate %62 RelaxedPrecision 860fd4e5da5Sopenharmony_ci OpDecorate %69 RelaxedPrecision 861fd4e5da5Sopenharmony_ci OpDecorate %77 RelaxedPrecision 862fd4e5da5Sopenharmony_ci OpDecorate %80 Location 0 863fd4e5da5Sopenharmony_ci OpDecorate %101 RelaxedPrecision 864fd4e5da5Sopenharmony_ci OpDecorate %102 RelaxedPrecision 865fd4e5da5Sopenharmony_ci OpDecorate %96 RelaxedPrecision 866fd4e5da5Sopenharmony_ci OpDecorate %108 RelaxedPrecision 867fd4e5da5Sopenharmony_ci OpDecorate %107 RelaxedPrecision 868fd4e5da5Sopenharmony_ci OpDecorate %98 RelaxedPrecision 869fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 870fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 871fd4e5da5Sopenharmony_ci %6 = OpTypeFloat 32 872fd4e5da5Sopenharmony_ci %9 = OpConstant %6 0 873fd4e5da5Sopenharmony_ci %11 = OpTypeInt 32 1 874fd4e5da5Sopenharmony_ci %12 = OpTypeStruct %11 %6 875fd4e5da5Sopenharmony_ci %15 = OpTypeStruct %11 %6 876fd4e5da5Sopenharmony_ci %16 = OpTypeStruct %15 %6 %11 877fd4e5da5Sopenharmony_ci %17 = OpTypePointer Uniform %16 878fd4e5da5Sopenharmony_ci %18 = OpVariable %17 Uniform 879fd4e5da5Sopenharmony_ci %19 = OpConstant %11 0 880fd4e5da5Sopenharmony_ci %20 = OpTypePointer Uniform %15 881fd4e5da5Sopenharmony_ci %27 = OpConstant %11 1 882fd4e5da5Sopenharmony_ci %36 = OpTypePointer Uniform %11 883fd4e5da5Sopenharmony_ci %39 = OpTypeBool 884fd4e5da5Sopenharmony_ci %41 = OpConstant %11 2 885fd4e5da5Sopenharmony_ci %48 = OpConstant %6 0.100000001 886fd4e5da5Sopenharmony_ci %51 = OpConstant %6 0.200000003 887fd4e5da5Sopenharmony_ci %78 = OpTypeVector %6 4 888fd4e5da5Sopenharmony_ci %79 = OpTypePointer Output %78 889fd4e5da5Sopenharmony_ci %80 = OpVariable %79 Output 890fd4e5da5Sopenharmony_ci %85 = OpConstant %6 1 891fd4e5da5Sopenharmony_ci %95 = OpUndef %12 892fd4e5da5Sopenharmony_ci %112 = OpTypePointer Uniform %6 893fd4e5da5Sopenharmony_ci %113 = OpTypeInt 32 0 894fd4e5da5Sopenharmony_ci %114 = OpConstant %113 1 895fd4e5da5Sopenharmony_ci %179 = OpTypePointer Function %39 896fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 897fd4e5da5Sopenharmony_ci %5 = OpLabel 898fd4e5da5Sopenharmony_ci %180 = OpVariable %179 Function 899fd4e5da5Sopenharmony_ci %181 = OpVariable %179 Function 900fd4e5da5Sopenharmony_ci %182 = OpVariable %179 Function 901fd4e5da5Sopenharmony_ci %21 = OpAccessChain %20 %18 %19 902fd4e5da5Sopenharmony_ci %115 = OpAccessChain %112 %21 %114 903fd4e5da5Sopenharmony_ci %116 = OpLoad %6 %115 904fd4e5da5Sopenharmony_ci %90 = OpCompositeInsert %12 %116 %95 1 905fd4e5da5Sopenharmony_ci OpBranch %30 906fd4e5da5Sopenharmony_ci %30 = OpLabel 907fd4e5da5Sopenharmony_ci %99 = OpPhi %12 %90 %5 %109 %47 908fd4e5da5Sopenharmony_ci %98 = OpPhi %6 %9 %5 %107 %47 909fd4e5da5Sopenharmony_ci %97 = OpPhi %6 %9 %5 %105 %47 910fd4e5da5Sopenharmony_ci %96 = OpPhi %11 %19 %5 %77 %47 911fd4e5da5Sopenharmony_ci %37 = OpAccessChain %36 %18 %19 %19 912fd4e5da5Sopenharmony_ci %38 = OpLoad %11 %37 913fd4e5da5Sopenharmony_ci %40 = OpSLessThan %39 %96 %38 914fd4e5da5Sopenharmony_ci OpLoopMerge %32 %47 None 915fd4e5da5Sopenharmony_ci OpBranchConditional %40 %31 %32 916fd4e5da5Sopenharmony_ci %31 = OpLabel 917fd4e5da5Sopenharmony_ci %42 = OpAccessChain %36 %18 %41 918fd4e5da5Sopenharmony_ci %43 = OpLoad %11 %42 919fd4e5da5Sopenharmony_ci OpSelectionMerge %45 None 920fd4e5da5Sopenharmony_ci OpSwitch %43 %46 0 %44 1 %45 921fd4e5da5Sopenharmony_ci %46 = OpLabel 922fd4e5da5Sopenharmony_ci %69 = OpIAdd %11 %96 %27 923fd4e5da5Sopenharmony_ci %72 = OpCompositeExtract %6 %99 1 924fd4e5da5Sopenharmony_ci %73 = OpFAdd %6 %72 %98 925fd4e5da5Sopenharmony_ci %93 = OpCompositeInsert %12 %73 %99 1 926fd4e5da5Sopenharmony_ci OpBranch %47 927fd4e5da5Sopenharmony_ci %44 = OpLabel 928fd4e5da5Sopenharmony_ci %50 = OpFAdd %6 %97 %48 929fd4e5da5Sopenharmony_ci %53 = OpFAdd %6 %98 %51 930fd4e5da5Sopenharmony_ci OpBranch %45 931fd4e5da5Sopenharmony_ci %45 = OpLabel 932fd4e5da5Sopenharmony_ci %101 = OpPhi %6 %98 %31 %53 %44 933fd4e5da5Sopenharmony_ci %100 = OpPhi %6 %97 %31 %50 %44 934fd4e5da5Sopenharmony_ci %55 = OpFAdd %6 %100 %48 935fd4e5da5Sopenharmony_ci %58 = OpFOrdGreaterThan %39 %55 %101 936fd4e5da5Sopenharmony_ci OpSelectionMerge %60 None 937fd4e5da5Sopenharmony_ci OpBranchConditional %58 %59 %63 938fd4e5da5Sopenharmony_ci %59 = OpLabel 939fd4e5da5Sopenharmony_ci %62 = OpFAdd %6 %101 %51 940fd4e5da5Sopenharmony_ci OpBranch %60 941fd4e5da5Sopenharmony_ci %63 = OpLabel 942fd4e5da5Sopenharmony_ci %66 = OpFAdd %6 %101 %55 943fd4e5da5Sopenharmony_ci OpBranch %60 944fd4e5da5Sopenharmony_ci %60 = OpLabel 945fd4e5da5Sopenharmony_ci %108 = OpPhi %6 %62 %59 %66 %63 946fd4e5da5Sopenharmony_ci OpBranch %47 947fd4e5da5Sopenharmony_ci %47 = OpLabel 948fd4e5da5Sopenharmony_ci %109 = OpPhi %12 %93 %46 %99 %60 949fd4e5da5Sopenharmony_ci %107 = OpPhi %6 %98 %46 %108 %60 950fd4e5da5Sopenharmony_ci %105 = OpPhi %6 %97 %46 %55 %60 951fd4e5da5Sopenharmony_ci %102 = OpPhi %11 %69 %46 %96 %60 952fd4e5da5Sopenharmony_ci %77 = OpIAdd %11 %102 %27 953fd4e5da5Sopenharmony_ci OpBranch %30 954fd4e5da5Sopenharmony_ci %32 = OpLabel 955fd4e5da5Sopenharmony_ci %84 = OpCompositeExtract %6 %99 1 956fd4e5da5Sopenharmony_ci %86 = OpCompositeConstruct %78 %97 %98 %84 %85 957fd4e5da5Sopenharmony_ci OpStore %80 %86 958fd4e5da5Sopenharmony_ci OpReturn 959fd4e5da5Sopenharmony_ci OpFunctionEnd 960fd4e5da5Sopenharmony_ci )"; 961fd4e5da5Sopenharmony_ci 962fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 963fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 964fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); 965fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 966fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 967fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 968fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 969fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(context.get()), validator_options); 970fd4e5da5Sopenharmony_ci // Inapplicable because %18 is decorated. 971fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationAddSynonym( 972fd4e5da5Sopenharmony_ci 18, protobufs::TransformationAddSynonym::COPY_OBJECT, 200, 973fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(21, spv::Op::OpAccessChain, 0)) 974fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 975fd4e5da5Sopenharmony_ci 976fd4e5da5Sopenharmony_ci // Inapplicable because %77 is decorated. 977fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationAddSynonym( 978fd4e5da5Sopenharmony_ci 77, protobufs::TransformationAddSynonym::COPY_OBJECT, 200, 979fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(77, spv::Op::OpBranch, 0)) 980fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 981fd4e5da5Sopenharmony_ci 982fd4e5da5Sopenharmony_ci // Inapplicable because %80 is decorated. 983fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationAddSynonym( 984fd4e5da5Sopenharmony_ci 80, protobufs::TransformationAddSynonym::COPY_OBJECT, 200, 985fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(77, spv::Op::OpIAdd, 0)) 986fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 987fd4e5da5Sopenharmony_ci 988fd4e5da5Sopenharmony_ci // Inapplicable because %84 is not available at the requested point 989fd4e5da5Sopenharmony_ci ASSERT_FALSE( 990fd4e5da5Sopenharmony_ci TransformationAddSynonym( 991fd4e5da5Sopenharmony_ci 84, protobufs::TransformationAddSynonym::COPY_OBJECT, 200, 992fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(32, spv::Op::OpCompositeExtract, 0)) 993fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 994fd4e5da5Sopenharmony_ci 995fd4e5da5Sopenharmony_ci // Fine because %84 is available at the requested point 996fd4e5da5Sopenharmony_ci ASSERT_TRUE( 997fd4e5da5Sopenharmony_ci TransformationAddSynonym( 998fd4e5da5Sopenharmony_ci 84, protobufs::TransformationAddSynonym::COPY_OBJECT, 200, 999fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(32, spv::Op::OpCompositeConstruct, 0)) 1000fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 1001fd4e5da5Sopenharmony_ci 1002fd4e5da5Sopenharmony_ci // Inapplicable because id %9 is already in use 1003fd4e5da5Sopenharmony_ci ASSERT_FALSE( 1004fd4e5da5Sopenharmony_ci TransformationAddSynonym( 1005fd4e5da5Sopenharmony_ci 84, protobufs::TransformationAddSynonym::COPY_OBJECT, 9, 1006fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(32, spv::Op::OpCompositeConstruct, 0)) 1007fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 1008fd4e5da5Sopenharmony_ci 1009fd4e5da5Sopenharmony_ci // Inapplicable because the requested point does not exist 1010fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationAddSynonym( 1011fd4e5da5Sopenharmony_ci 84, protobufs::TransformationAddSynonym::COPY_OBJECT, 200, 1012fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(86, spv::Op::OpReturn, 2)) 1013fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 1014fd4e5da5Sopenharmony_ci 1015fd4e5da5Sopenharmony_ci // Inapplicable because %9 is not in a function 1016fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationAddSynonym( 1017fd4e5da5Sopenharmony_ci 9, protobufs::TransformationAddSynonym::COPY_OBJECT, 200, 1018fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(9, spv::Op::OpTypeInt, 0)) 1019fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 1020fd4e5da5Sopenharmony_ci 1021fd4e5da5Sopenharmony_ci // Inapplicable because the insert point is right before, or inside, a chunk 1022fd4e5da5Sopenharmony_ci // of OpPhis 1023fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationAddSynonym( 1024fd4e5da5Sopenharmony_ci 9, protobufs::TransformationAddSynonym::COPY_OBJECT, 200, 1025fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(30, spv::Op::OpPhi, 0)) 1026fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 1027fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationAddSynonym( 1028fd4e5da5Sopenharmony_ci 9, protobufs::TransformationAddSynonym::COPY_OBJECT, 200, 1029fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(99, spv::Op::OpPhi, 1)) 1030fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 1031fd4e5da5Sopenharmony_ci 1032fd4e5da5Sopenharmony_ci // OK, because the insert point is just after a chunk of OpPhis. 1033fd4e5da5Sopenharmony_ci ASSERT_TRUE(TransformationAddSynonym( 1034fd4e5da5Sopenharmony_ci 9, protobufs::TransformationAddSynonym::COPY_OBJECT, 200, 1035fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(96, spv::Op::OpAccessChain, 0)) 1036fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 1037fd4e5da5Sopenharmony_ci 1038fd4e5da5Sopenharmony_ci // Inapplicable because the insert point is right after an OpSelectionMerge 1039fd4e5da5Sopenharmony_ci ASSERT_FALSE( 1040fd4e5da5Sopenharmony_ci TransformationAddSynonym( 1041fd4e5da5Sopenharmony_ci 9, protobufs::TransformationAddSynonym::COPY_OBJECT, 200, 1042fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(58, spv::Op::OpBranchConditional, 0)) 1043fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 1044fd4e5da5Sopenharmony_ci 1045fd4e5da5Sopenharmony_ci // OK, because the insert point is right before the OpSelectionMerge 1046fd4e5da5Sopenharmony_ci ASSERT_TRUE(TransformationAddSynonym( 1047fd4e5da5Sopenharmony_ci 9, protobufs::TransformationAddSynonym::COPY_OBJECT, 200, 1048fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(58, spv::Op::OpSelectionMerge, 0)) 1049fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 1050fd4e5da5Sopenharmony_ci 1051fd4e5da5Sopenharmony_ci // Inapplicable because the insert point is right after an OpSelectionMerge 1052fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationAddSynonym( 1053fd4e5da5Sopenharmony_ci 9, protobufs::TransformationAddSynonym::COPY_OBJECT, 200, 1054fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(43, spv::Op::OpSwitch, 0)) 1055fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 1056fd4e5da5Sopenharmony_ci 1057fd4e5da5Sopenharmony_ci // OK, because the insert point is right before the OpSelectionMerge 1058fd4e5da5Sopenharmony_ci ASSERT_TRUE(TransformationAddSynonym( 1059fd4e5da5Sopenharmony_ci 9, protobufs::TransformationAddSynonym::COPY_OBJECT, 200, 1060fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(43, spv::Op::OpSelectionMerge, 0)) 1061fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 1062fd4e5da5Sopenharmony_ci 1063fd4e5da5Sopenharmony_ci // Inapplicable because the insert point is right after an OpLoopMerge 1064fd4e5da5Sopenharmony_ci ASSERT_FALSE( 1065fd4e5da5Sopenharmony_ci TransformationAddSynonym( 1066fd4e5da5Sopenharmony_ci 9, protobufs::TransformationAddSynonym::COPY_OBJECT, 200, 1067fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(40, spv::Op::OpBranchConditional, 0)) 1068fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 1069fd4e5da5Sopenharmony_ci 1070fd4e5da5Sopenharmony_ci // OK, because the insert point is right before the OpLoopMerge 1071fd4e5da5Sopenharmony_ci ASSERT_TRUE(TransformationAddSynonym( 1072fd4e5da5Sopenharmony_ci 9, protobufs::TransformationAddSynonym::COPY_OBJECT, 200, 1073fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(40, spv::Op::OpLoopMerge, 0)) 1074fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 1075fd4e5da5Sopenharmony_ci 1076fd4e5da5Sopenharmony_ci // Inapplicable because id %300 does not exist 1077fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationAddSynonym( 1078fd4e5da5Sopenharmony_ci 300, protobufs::TransformationAddSynonym::COPY_OBJECT, 200, 1079fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(40, spv::Op::OpLoopMerge, 0)) 1080fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 1081fd4e5da5Sopenharmony_ci 1082fd4e5da5Sopenharmony_ci // Inapplicable because the following instruction is OpVariable 1083fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationAddSynonym( 1084fd4e5da5Sopenharmony_ci 9, protobufs::TransformationAddSynonym::COPY_OBJECT, 200, 1085fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(180, spv::Op::OpVariable, 0)) 1086fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 1087fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationAddSynonym( 1088fd4e5da5Sopenharmony_ci 9, protobufs::TransformationAddSynonym::COPY_OBJECT, 200, 1089fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(181, spv::Op::OpVariable, 0)) 1090fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 1091fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationAddSynonym( 1092fd4e5da5Sopenharmony_ci 9, protobufs::TransformationAddSynonym::COPY_OBJECT, 200, 1093fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(182, spv::Op::OpVariable, 0)) 1094fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 1095fd4e5da5Sopenharmony_ci 1096fd4e5da5Sopenharmony_ci // OK, because this is just past the group of OpVariable instructions. 1097fd4e5da5Sopenharmony_ci ASSERT_TRUE(TransformationAddSynonym( 1098fd4e5da5Sopenharmony_ci 9, protobufs::TransformationAddSynonym::COPY_OBJECT, 200, 1099fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(182, spv::Op::OpAccessChain, 0)) 1100fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 1101fd4e5da5Sopenharmony_ci} 1102fd4e5da5Sopenharmony_ci 1103fd4e5da5Sopenharmony_ciTEST(TransformationAddSynonymTest, MiscellaneousCopies) { 1104fd4e5da5Sopenharmony_ci // The following SPIR-V comes from this GLSL: 1105fd4e5da5Sopenharmony_ci // 1106fd4e5da5Sopenharmony_ci // #version 310 es 1107fd4e5da5Sopenharmony_ci // 1108fd4e5da5Sopenharmony_ci // precision highp float; 1109fd4e5da5Sopenharmony_ci // 1110fd4e5da5Sopenharmony_ci // float g; 1111fd4e5da5Sopenharmony_ci // 1112fd4e5da5Sopenharmony_ci // vec4 h; 1113fd4e5da5Sopenharmony_ci // 1114fd4e5da5Sopenharmony_ci // void main() { 1115fd4e5da5Sopenharmony_ci // int a; 1116fd4e5da5Sopenharmony_ci // int b; 1117fd4e5da5Sopenharmony_ci // b = int(g); 1118fd4e5da5Sopenharmony_ci // h.x = float(a); 1119fd4e5da5Sopenharmony_ci // } 1120fd4e5da5Sopenharmony_ci 1121fd4e5da5Sopenharmony_ci std::string shader = R"( 1122fd4e5da5Sopenharmony_ci OpCapability Shader 1123fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 1124fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1125fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 1126fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 1127fd4e5da5Sopenharmony_ci OpSource ESSL 310 1128fd4e5da5Sopenharmony_ci OpName %4 "main" 1129fd4e5da5Sopenharmony_ci OpName %8 "b" 1130fd4e5da5Sopenharmony_ci OpName %11 "g" 1131fd4e5da5Sopenharmony_ci OpName %16 "h" 1132fd4e5da5Sopenharmony_ci OpName %17 "a" 1133fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 1134fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 1135fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 1136fd4e5da5Sopenharmony_ci %7 = OpTypePointer Function %6 1137fd4e5da5Sopenharmony_ci %9 = OpTypeFloat 32 1138fd4e5da5Sopenharmony_ci %10 = OpTypePointer Private %9 1139fd4e5da5Sopenharmony_ci %11 = OpVariable %10 Private 1140fd4e5da5Sopenharmony_ci %14 = OpTypeVector %9 4 1141fd4e5da5Sopenharmony_ci %15 = OpTypePointer Private %14 1142fd4e5da5Sopenharmony_ci %16 = OpVariable %15 Private 1143fd4e5da5Sopenharmony_ci %20 = OpTypeInt 32 0 1144fd4e5da5Sopenharmony_ci %21 = OpConstant %20 0 1145fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 1146fd4e5da5Sopenharmony_ci %5 = OpLabel 1147fd4e5da5Sopenharmony_ci %8 = OpVariable %7 Function 1148fd4e5da5Sopenharmony_ci %17 = OpVariable %7 Function 1149fd4e5da5Sopenharmony_ci %12 = OpLoad %9 %11 1150fd4e5da5Sopenharmony_ci %13 = OpConvertFToS %6 %12 1151fd4e5da5Sopenharmony_ci OpStore %8 %13 1152fd4e5da5Sopenharmony_ci %18 = OpLoad %6 %17 1153fd4e5da5Sopenharmony_ci %19 = OpConvertSToF %9 %18 1154fd4e5da5Sopenharmony_ci %22 = OpAccessChain %10 %16 %21 1155fd4e5da5Sopenharmony_ci OpStore %22 %19 1156fd4e5da5Sopenharmony_ci OpReturn 1157fd4e5da5Sopenharmony_ci OpFunctionEnd 1158fd4e5da5Sopenharmony_ci )"; 1159fd4e5da5Sopenharmony_ci 1160fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 1161fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 1162fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); 1163fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 1164fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 1165fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 1166fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 1167fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(context.get()), validator_options); 1168fd4e5da5Sopenharmony_ci std::vector<TransformationAddSynonym> transformations = { 1169fd4e5da5Sopenharmony_ci TransformationAddSynonym( 1170fd4e5da5Sopenharmony_ci 19, protobufs::TransformationAddSynonym::COPY_OBJECT, 100, 1171fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(22, spv::Op::OpStore, 0)), 1172fd4e5da5Sopenharmony_ci TransformationAddSynonym( 1173fd4e5da5Sopenharmony_ci 22, protobufs::TransformationAddSynonym::COPY_OBJECT, 101, 1174fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(22, spv::Op::OpCopyObject, 0)), 1175fd4e5da5Sopenharmony_ci TransformationAddSynonym( 1176fd4e5da5Sopenharmony_ci 12, protobufs::TransformationAddSynonym::COPY_OBJECT, 102, 1177fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(22, spv::Op::OpCopyObject, 0)), 1178fd4e5da5Sopenharmony_ci TransformationAddSynonym( 1179fd4e5da5Sopenharmony_ci 11, protobufs::TransformationAddSynonym::COPY_OBJECT, 103, 1180fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(22, spv::Op::OpCopyObject, 0)), 1181fd4e5da5Sopenharmony_ci TransformationAddSynonym( 1182fd4e5da5Sopenharmony_ci 16, protobufs::TransformationAddSynonym::COPY_OBJECT, 104, 1183fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(22, spv::Op::OpCopyObject, 0)), 1184fd4e5da5Sopenharmony_ci TransformationAddSynonym( 1185fd4e5da5Sopenharmony_ci 8, protobufs::TransformationAddSynonym::COPY_OBJECT, 105, 1186fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(22, spv::Op::OpCopyObject, 0)), 1187fd4e5da5Sopenharmony_ci TransformationAddSynonym( 1188fd4e5da5Sopenharmony_ci 17, protobufs::TransformationAddSynonym::COPY_OBJECT, 106, 1189fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(22, spv::Op::OpCopyObject, 0))}; 1190fd4e5da5Sopenharmony_ci 1191fd4e5da5Sopenharmony_ci for (auto& transformation : transformations) { 1192fd4e5da5Sopenharmony_ci ASSERT_TRUE( 1193fd4e5da5Sopenharmony_ci transformation.IsApplicable(context.get(), transformation_context)); 1194fd4e5da5Sopenharmony_ci ApplyAndCheckFreshIds(transformation, context.get(), 1195fd4e5da5Sopenharmony_ci &transformation_context); 1196fd4e5da5Sopenharmony_ci } 1197fd4e5da5Sopenharmony_ci 1198fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 1199fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 1200fd4e5da5Sopenharmony_ci 1201fd4e5da5Sopenharmony_ci std::string after_transformation = R"( 1202fd4e5da5Sopenharmony_ci OpCapability Shader 1203fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 1204fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1205fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 1206fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 1207fd4e5da5Sopenharmony_ci OpSource ESSL 310 1208fd4e5da5Sopenharmony_ci OpName %4 "main" 1209fd4e5da5Sopenharmony_ci OpName %8 "b" 1210fd4e5da5Sopenharmony_ci OpName %11 "g" 1211fd4e5da5Sopenharmony_ci OpName %16 "h" 1212fd4e5da5Sopenharmony_ci OpName %17 "a" 1213fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 1214fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 1215fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 1216fd4e5da5Sopenharmony_ci %7 = OpTypePointer Function %6 1217fd4e5da5Sopenharmony_ci %9 = OpTypeFloat 32 1218fd4e5da5Sopenharmony_ci %10 = OpTypePointer Private %9 1219fd4e5da5Sopenharmony_ci %11 = OpVariable %10 Private 1220fd4e5da5Sopenharmony_ci %14 = OpTypeVector %9 4 1221fd4e5da5Sopenharmony_ci %15 = OpTypePointer Private %14 1222fd4e5da5Sopenharmony_ci %16 = OpVariable %15 Private 1223fd4e5da5Sopenharmony_ci %20 = OpTypeInt 32 0 1224fd4e5da5Sopenharmony_ci %21 = OpConstant %20 0 1225fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 1226fd4e5da5Sopenharmony_ci %5 = OpLabel 1227fd4e5da5Sopenharmony_ci %8 = OpVariable %7 Function 1228fd4e5da5Sopenharmony_ci %17 = OpVariable %7 Function 1229fd4e5da5Sopenharmony_ci %12 = OpLoad %9 %11 1230fd4e5da5Sopenharmony_ci %13 = OpConvertFToS %6 %12 1231fd4e5da5Sopenharmony_ci OpStore %8 %13 1232fd4e5da5Sopenharmony_ci %18 = OpLoad %6 %17 1233fd4e5da5Sopenharmony_ci %19 = OpConvertSToF %9 %18 1234fd4e5da5Sopenharmony_ci %22 = OpAccessChain %10 %16 %21 1235fd4e5da5Sopenharmony_ci %106 = OpCopyObject %7 %17 1236fd4e5da5Sopenharmony_ci %105 = OpCopyObject %7 %8 1237fd4e5da5Sopenharmony_ci %104 = OpCopyObject %15 %16 1238fd4e5da5Sopenharmony_ci %103 = OpCopyObject %10 %11 1239fd4e5da5Sopenharmony_ci %102 = OpCopyObject %9 %12 1240fd4e5da5Sopenharmony_ci %101 = OpCopyObject %10 %22 1241fd4e5da5Sopenharmony_ci %100 = OpCopyObject %9 %19 1242fd4e5da5Sopenharmony_ci OpStore %22 %19 1243fd4e5da5Sopenharmony_ci OpReturn 1244fd4e5da5Sopenharmony_ci OpFunctionEnd 1245fd4e5da5Sopenharmony_ci )"; 1246fd4e5da5Sopenharmony_ci 1247fd4e5da5Sopenharmony_ci ASSERT_TRUE(IsEqual(env, after_transformation, context.get())); 1248fd4e5da5Sopenharmony_ci} 1249fd4e5da5Sopenharmony_ci 1250fd4e5da5Sopenharmony_ciTEST(TransformationAddSynonymTest, DoNotCopyNullPointers) { 1251fd4e5da5Sopenharmony_ci std::string shader = R"( 1252fd4e5da5Sopenharmony_ci OpCapability Shader 1253fd4e5da5Sopenharmony_ci OpCapability VariablePointers 1254fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 1255fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1256fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 1257fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 1258fd4e5da5Sopenharmony_ci OpSource ESSL 310 1259fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 1260fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 1261fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 1262fd4e5da5Sopenharmony_ci %7 = OpTypePointer Function %6 1263fd4e5da5Sopenharmony_ci %8 = OpConstantNull %7 1264fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 1265fd4e5da5Sopenharmony_ci %5 = OpLabel 1266fd4e5da5Sopenharmony_ci OpReturn 1267fd4e5da5Sopenharmony_ci OpFunctionEnd 1268fd4e5da5Sopenharmony_ci )"; 1269fd4e5da5Sopenharmony_ci 1270fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 1271fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 1272fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); 1273fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 1274fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 1275fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 1276fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 1277fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(context.get()), validator_options); 1278fd4e5da5Sopenharmony_ci // Illegal to copy null. 1279fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationAddSynonym( 1280fd4e5da5Sopenharmony_ci 8, protobufs::TransformationAddSynonym::COPY_OBJECT, 100, 1281fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(5, spv::Op::OpReturn, 0)) 1282fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 1283fd4e5da5Sopenharmony_ci} 1284fd4e5da5Sopenharmony_ci 1285fd4e5da5Sopenharmony_ciTEST(TransformationAddSynonymTest, PropagateIrrelevantPointeeFact) { 1286fd4e5da5Sopenharmony_ci // Checks that if a pointer is known to have an irrelevant value, the same 1287fd4e5da5Sopenharmony_ci // holds after the pointer is copied. 1288fd4e5da5Sopenharmony_ci 1289fd4e5da5Sopenharmony_ci std::string shader = R"( 1290fd4e5da5Sopenharmony_ci OpCapability Shader 1291fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 1292fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1293fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 1294fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 1295fd4e5da5Sopenharmony_ci OpSource ESSL 310 1296fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 1297fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 1298fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 1299fd4e5da5Sopenharmony_ci %7 = OpTypePointer Function %6 1300fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 1301fd4e5da5Sopenharmony_ci %5 = OpLabel 1302fd4e5da5Sopenharmony_ci %8 = OpVariable %7 Function 1303fd4e5da5Sopenharmony_ci %9 = OpVariable %7 Function 1304fd4e5da5Sopenharmony_ci OpReturn 1305fd4e5da5Sopenharmony_ci OpFunctionEnd 1306fd4e5da5Sopenharmony_ci )"; 1307fd4e5da5Sopenharmony_ci 1308fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 1309fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 1310fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); 1311fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 1312fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 1313fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 1314fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 1315fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(context.get()), validator_options); 1316fd4e5da5Sopenharmony_ci transformation_context.GetFactManager()->AddFactValueOfPointeeIsIrrelevant(8); 1317fd4e5da5Sopenharmony_ci 1318fd4e5da5Sopenharmony_ci TransformationAddSynonym transformation1( 1319fd4e5da5Sopenharmony_ci 8, protobufs::TransformationAddSynonym::COPY_OBJECT, 100, 1320fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(9, spv::Op::OpReturn, 0)); 1321fd4e5da5Sopenharmony_ci TransformationAddSynonym transformation2( 1322fd4e5da5Sopenharmony_ci 9, protobufs::TransformationAddSynonym::COPY_OBJECT, 101, 1323fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(9, spv::Op::OpReturn, 0)); 1324fd4e5da5Sopenharmony_ci TransformationAddSynonym transformation3( 1325fd4e5da5Sopenharmony_ci 100, protobufs::TransformationAddSynonym::COPY_OBJECT, 102, 1326fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(9, spv::Op::OpReturn, 0)); 1327fd4e5da5Sopenharmony_ci 1328fd4e5da5Sopenharmony_ci ASSERT_TRUE( 1329fd4e5da5Sopenharmony_ci transformation1.IsApplicable(context.get(), transformation_context)); 1330fd4e5da5Sopenharmony_ci ApplyAndCheckFreshIds(transformation1, context.get(), 1331fd4e5da5Sopenharmony_ci &transformation_context); 1332fd4e5da5Sopenharmony_ci ASSERT_TRUE( 1333fd4e5da5Sopenharmony_ci transformation2.IsApplicable(context.get(), transformation_context)); 1334fd4e5da5Sopenharmony_ci ApplyAndCheckFreshIds(transformation2, context.get(), 1335fd4e5da5Sopenharmony_ci &transformation_context); 1336fd4e5da5Sopenharmony_ci ASSERT_TRUE( 1337fd4e5da5Sopenharmony_ci transformation3.IsApplicable(context.get(), transformation_context)); 1338fd4e5da5Sopenharmony_ci ApplyAndCheckFreshIds(transformation3, context.get(), 1339fd4e5da5Sopenharmony_ci &transformation_context); 1340fd4e5da5Sopenharmony_ci 1341fd4e5da5Sopenharmony_ci ASSERT_TRUE( 1342fd4e5da5Sopenharmony_ci transformation_context.GetFactManager()->PointeeValueIsIrrelevant(8)); 1343fd4e5da5Sopenharmony_ci ASSERT_TRUE( 1344fd4e5da5Sopenharmony_ci transformation_context.GetFactManager()->PointeeValueIsIrrelevant(100)); 1345fd4e5da5Sopenharmony_ci ASSERT_TRUE( 1346fd4e5da5Sopenharmony_ci transformation_context.GetFactManager()->PointeeValueIsIrrelevant(102)); 1347fd4e5da5Sopenharmony_ci ASSERT_FALSE( 1348fd4e5da5Sopenharmony_ci transformation_context.GetFactManager()->PointeeValueIsIrrelevant(9)); 1349fd4e5da5Sopenharmony_ci ASSERT_FALSE( 1350fd4e5da5Sopenharmony_ci transformation_context.GetFactManager()->PointeeValueIsIrrelevant(101)); 1351fd4e5da5Sopenharmony_ci} 1352fd4e5da5Sopenharmony_ci 1353fd4e5da5Sopenharmony_ciTEST(TransformationAddSynonymTest, DoNotCopyOpSampledImage) { 1354fd4e5da5Sopenharmony_ci // This checks that we do not try to copy the result id of an OpSampledImage 1355fd4e5da5Sopenharmony_ci // instruction. 1356fd4e5da5Sopenharmony_ci std::string shader = R"( 1357fd4e5da5Sopenharmony_ci OpCapability Shader 1358fd4e5da5Sopenharmony_ci OpCapability SampledBuffer 1359fd4e5da5Sopenharmony_ci OpCapability ImageBuffer 1360fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 1361fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1362fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %2 "main" %40 %41 1363fd4e5da5Sopenharmony_ci OpExecutionMode %2 OriginUpperLeft 1364fd4e5da5Sopenharmony_ci OpSource GLSL 450 1365fd4e5da5Sopenharmony_ci OpDecorate %40 DescriptorSet 0 1366fd4e5da5Sopenharmony_ci OpDecorate %40 Binding 69 1367fd4e5da5Sopenharmony_ci OpDecorate %41 DescriptorSet 0 1368fd4e5da5Sopenharmony_ci OpDecorate %41 Binding 1 1369fd4e5da5Sopenharmony_ci %54 = OpTypeFloat 32 1370fd4e5da5Sopenharmony_ci %76 = OpTypeVector %54 4 1371fd4e5da5Sopenharmony_ci %55 = OpConstant %54 0 1372fd4e5da5Sopenharmony_ci %56 = OpTypeVector %54 3 1373fd4e5da5Sopenharmony_ci %94 = OpTypeVector %54 2 1374fd4e5da5Sopenharmony_ci %112 = OpConstantComposite %94 %55 %55 1375fd4e5da5Sopenharmony_ci %57 = OpConstantComposite %56 %55 %55 %55 1376fd4e5da5Sopenharmony_ci %15 = OpTypeImage %54 2D 2 0 0 1 Unknown 1377fd4e5da5Sopenharmony_ci %114 = OpTypePointer UniformConstant %15 1378fd4e5da5Sopenharmony_ci %38 = OpTypeSampler 1379fd4e5da5Sopenharmony_ci %125 = OpTypePointer UniformConstant %38 1380fd4e5da5Sopenharmony_ci %132 = OpTypeVoid 1381fd4e5da5Sopenharmony_ci %133 = OpTypeFunction %132 1382fd4e5da5Sopenharmony_ci %45 = OpTypeSampledImage %15 1383fd4e5da5Sopenharmony_ci %40 = OpVariable %114 UniformConstant 1384fd4e5da5Sopenharmony_ci %41 = OpVariable %125 UniformConstant 1385fd4e5da5Sopenharmony_ci %2 = OpFunction %132 None %133 1386fd4e5da5Sopenharmony_ci %164 = OpLabel 1387fd4e5da5Sopenharmony_ci %184 = OpLoad %15 %40 1388fd4e5da5Sopenharmony_ci %213 = OpLoad %38 %41 1389fd4e5da5Sopenharmony_ci %216 = OpSampledImage %45 %184 %213 1390fd4e5da5Sopenharmony_ci %217 = OpImageSampleImplicitLod %76 %216 %112 Bias %55 1391fd4e5da5Sopenharmony_ci OpReturn 1392fd4e5da5Sopenharmony_ci OpFunctionEnd 1393fd4e5da5Sopenharmony_ci )"; 1394fd4e5da5Sopenharmony_ci 1395fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 1396fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 1397fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); 1398fd4e5da5Sopenharmony_ci 1399fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 1400fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 1401fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(context.get()), validator_options); 1402fd4e5da5Sopenharmony_ci ASSERT_FALSE( 1403fd4e5da5Sopenharmony_ci TransformationAddSynonym( 1404fd4e5da5Sopenharmony_ci 216, protobufs::TransformationAddSynonym::COPY_OBJECT, 500, 1405fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(217, spv::Op::OpImageSampleImplicitLod, 0)) 1406fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 1407fd4e5da5Sopenharmony_ci} 1408fd4e5da5Sopenharmony_ci 1409fd4e5da5Sopenharmony_ciTEST(TransformationAddSynonymTest, DoNotCopyVoidRunctionResult) { 1410fd4e5da5Sopenharmony_ci // This checks that we do not try to copy the result of a void function. 1411fd4e5da5Sopenharmony_ci std::string shader = R"( 1412fd4e5da5Sopenharmony_ci OpCapability Shader 1413fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 1414fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1415fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 1416fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 1417fd4e5da5Sopenharmony_ci OpSource ESSL 320 1418fd4e5da5Sopenharmony_ci OpName %4 "main" 1419fd4e5da5Sopenharmony_ci OpName %6 "foo(" 1420fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 1421fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 1422fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 1423fd4e5da5Sopenharmony_ci %5 = OpLabel 1424fd4e5da5Sopenharmony_ci %8 = OpFunctionCall %2 %6 1425fd4e5da5Sopenharmony_ci OpReturn 1426fd4e5da5Sopenharmony_ci OpFunctionEnd 1427fd4e5da5Sopenharmony_ci %6 = OpFunction %2 None %3 1428fd4e5da5Sopenharmony_ci %7 = OpLabel 1429fd4e5da5Sopenharmony_ci OpReturn 1430fd4e5da5Sopenharmony_ci OpFunctionEnd 1431fd4e5da5Sopenharmony_ci )"; 1432fd4e5da5Sopenharmony_ci 1433fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 1434fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 1435fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); 1436fd4e5da5Sopenharmony_ci 1437fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 1438fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 1439fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(context.get()), validator_options); 1440fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationAddSynonym( 1441fd4e5da5Sopenharmony_ci 8, protobufs::TransformationAddSynonym::COPY_OBJECT, 500, 1442fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(8, spv::Op::OpReturn, 0)) 1443fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 1444fd4e5da5Sopenharmony_ci} 1445fd4e5da5Sopenharmony_ci 1446fd4e5da5Sopenharmony_ciTEST(TransformationAddSynonymTest, HandlesDeadBlocks) { 1447fd4e5da5Sopenharmony_ci std::string shader = R"( 1448fd4e5da5Sopenharmony_ci OpCapability Shader 1449fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 1450fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1451fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 1452fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 1453fd4e5da5Sopenharmony_ci OpSource ESSL 320 1454fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 1455fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 1456fd4e5da5Sopenharmony_ci %6 = OpTypeBool 1457fd4e5da5Sopenharmony_ci %7 = OpConstantTrue %6 1458fd4e5da5Sopenharmony_ci %11 = OpTypePointer Function %6 1459fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 1460fd4e5da5Sopenharmony_ci %5 = OpLabel 1461fd4e5da5Sopenharmony_ci %12 = OpVariable %11 Function 1462fd4e5da5Sopenharmony_ci OpSelectionMerge %10 None 1463fd4e5da5Sopenharmony_ci OpBranchConditional %7 %8 %9 1464fd4e5da5Sopenharmony_ci %8 = OpLabel 1465fd4e5da5Sopenharmony_ci OpBranch %10 1466fd4e5da5Sopenharmony_ci %9 = OpLabel 1467fd4e5da5Sopenharmony_ci OpBranch %10 1468fd4e5da5Sopenharmony_ci %10 = OpLabel 1469fd4e5da5Sopenharmony_ci OpReturn 1470fd4e5da5Sopenharmony_ci OpFunctionEnd 1471fd4e5da5Sopenharmony_ci )"; 1472fd4e5da5Sopenharmony_ci 1473fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 1474fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 1475fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); 1476fd4e5da5Sopenharmony_ci 1477fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 1478fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 1479fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(context.get()), validator_options); 1480fd4e5da5Sopenharmony_ci 1481fd4e5da5Sopenharmony_ci transformation_context.GetFactManager()->AddFactBlockIsDead(9); 1482fd4e5da5Sopenharmony_ci 1483fd4e5da5Sopenharmony_ci auto insert_before = MakeInstructionDescriptor(9, spv::Op::OpBranch, 0); 1484fd4e5da5Sopenharmony_ci 1485fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationAddSynonym( 1486fd4e5da5Sopenharmony_ci 7, protobufs::TransformationAddSynonym::COPY_OBJECT, 100, 1487fd4e5da5Sopenharmony_ci insert_before) 1488fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 1489fd4e5da5Sopenharmony_ci 1490fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationAddSynonym( 1491fd4e5da5Sopenharmony_ci 12, protobufs::TransformationAddSynonym::COPY_OBJECT, 100, 1492fd4e5da5Sopenharmony_ci insert_before) 1493fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 1494fd4e5da5Sopenharmony_ci} 1495fd4e5da5Sopenharmony_ci 1496fd4e5da5Sopenharmony_ci} // namespace 1497fd4e5da5Sopenharmony_ci} // namespace fuzz 1498fd4e5da5Sopenharmony_ci} // namespace spvtools 1499