1fd4e5da5Sopenharmony_ci// Copyright (c) 2019 Google LLC 2fd4e5da5Sopenharmony_ci// 3fd4e5da5Sopenharmony_ci// Licensed under the Apache License, Version 2.0 (the "License"); 4fd4e5da5Sopenharmony_ci// you may not use this file except in compliance with the License. 5fd4e5da5Sopenharmony_ci// You may obtain a copy of the License at 6fd4e5da5Sopenharmony_ci// 7fd4e5da5Sopenharmony_ci// http://www.apache.org/licenses/LICENSE-2.0 8fd4e5da5Sopenharmony_ci// 9fd4e5da5Sopenharmony_ci// Unless required by applicable law or agreed to in writing, software 10fd4e5da5Sopenharmony_ci// distributed under the License is distributed on an "AS IS" BASIS, 11fd4e5da5Sopenharmony_ci// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12fd4e5da5Sopenharmony_ci// See the License for the specific language governing permissions and 13fd4e5da5Sopenharmony_ci// limitations under the License. 14fd4e5da5Sopenharmony_ci 15fd4e5da5Sopenharmony_ci#include "source/fuzz/data_descriptor.h" 16fd4e5da5Sopenharmony_ci 17fd4e5da5Sopenharmony_ci#include "gtest/gtest.h" 18fd4e5da5Sopenharmony_ci#include "source/fuzz/fuzzer_util.h" 19fd4e5da5Sopenharmony_ci#include "source/fuzz/id_use_descriptor.h" 20fd4e5da5Sopenharmony_ci#include "source/fuzz/instruction_descriptor.h" 21fd4e5da5Sopenharmony_ci#include "source/fuzz/transformation_composite_extract.h" 22fd4e5da5Sopenharmony_ci#include "source/fuzz/transformation_replace_id_with_synonym.h" 23fd4e5da5Sopenharmony_ci#include "source/fuzz/transformation_vector_shuffle.h" 24fd4e5da5Sopenharmony_ci#include "test/fuzz/fuzz_test_util.h" 25fd4e5da5Sopenharmony_ci 26fd4e5da5Sopenharmony_cinamespace spvtools { 27fd4e5da5Sopenharmony_cinamespace fuzz { 28fd4e5da5Sopenharmony_cinamespace { 29fd4e5da5Sopenharmony_ci 30fd4e5da5Sopenharmony_ci// This file captures tests that check correctness of the collective use of a 31fd4e5da5Sopenharmony_ci// number of transformations that relate to data synonyms. 32fd4e5da5Sopenharmony_ci 33fd4e5da5Sopenharmony_ciprotobufs::Fact MakeSynonymFact(uint32_t first_id, 34fd4e5da5Sopenharmony_ci const std::vector<uint32_t>& first_indices, 35fd4e5da5Sopenharmony_ci uint32_t second_id, 36fd4e5da5Sopenharmony_ci const std::vector<uint32_t>& second_indices) { 37fd4e5da5Sopenharmony_ci protobufs::FactDataSynonym data_synonym_fact; 38fd4e5da5Sopenharmony_ci *data_synonym_fact.mutable_data1() = 39fd4e5da5Sopenharmony_ci MakeDataDescriptor(first_id, first_indices); 40fd4e5da5Sopenharmony_ci *data_synonym_fact.mutable_data2() = 41fd4e5da5Sopenharmony_ci MakeDataDescriptor(second_id, second_indices); 42fd4e5da5Sopenharmony_ci protobufs::Fact result; 43fd4e5da5Sopenharmony_ci *result.mutable_data_synonym_fact() = data_synonym_fact; 44fd4e5da5Sopenharmony_ci return result; 45fd4e5da5Sopenharmony_ci} 46fd4e5da5Sopenharmony_ci 47fd4e5da5Sopenharmony_ciTEST(DataSynonymTransformationTest, ArrayCompositeSynonyms) { 48fd4e5da5Sopenharmony_ci std::string shader = R"( 49fd4e5da5Sopenharmony_ci OpCapability Shader 50fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 51fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 52fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 53fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 54fd4e5da5Sopenharmony_ci OpSource ESSL 310 55fd4e5da5Sopenharmony_ci OpName %4 "main" 56fd4e5da5Sopenharmony_ci OpName %11 "A" 57fd4e5da5Sopenharmony_ci OpName %20 "B" 58fd4e5da5Sopenharmony_ci OpName %31 "g" 59fd4e5da5Sopenharmony_ci OpName %35 "h" 60fd4e5da5Sopenharmony_ci OpDecorate %11 RelaxedPrecision 61fd4e5da5Sopenharmony_ci OpDecorate %22 RelaxedPrecision 62fd4e5da5Sopenharmony_ci OpDecorate %27 RelaxedPrecision 63fd4e5da5Sopenharmony_ci OpDecorate %35 RelaxedPrecision 64fd4e5da5Sopenharmony_ci OpDecorate %36 RelaxedPrecision 65fd4e5da5Sopenharmony_ci OpDecorate %40 RelaxedPrecision 66fd4e5da5Sopenharmony_ci OpDecorate %41 RelaxedPrecision 67fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 68fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 69fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 70fd4e5da5Sopenharmony_ci %7 = OpTypeInt 32 0 71fd4e5da5Sopenharmony_ci %8 = OpConstant %7 3 72fd4e5da5Sopenharmony_ci %9 = OpTypeArray %6 %8 73fd4e5da5Sopenharmony_ci %10 = OpTypePointer Function %9 74fd4e5da5Sopenharmony_ci %12 = OpConstant %6 0 75fd4e5da5Sopenharmony_ci %13 = OpConstant %6 3 76fd4e5da5Sopenharmony_ci %14 = OpTypePointer Function %6 77fd4e5da5Sopenharmony_ci %16 = OpTypeFloat 32 78fd4e5da5Sopenharmony_ci %17 = OpConstant %7 4 79fd4e5da5Sopenharmony_ci %18 = OpTypeArray %16 %17 80fd4e5da5Sopenharmony_ci %19 = OpTypePointer Function %18 81fd4e5da5Sopenharmony_ci %24 = OpTypePointer Function %16 82fd4e5da5Sopenharmony_ci %28 = OpConstant %16 42 83fd4e5da5Sopenharmony_ci %30 = OpConstant %6 2 84fd4e5da5Sopenharmony_ci %34 = OpConstant %6 1 85fd4e5da5Sopenharmony_ci %38 = OpConstant %6 42 86fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 87fd4e5da5Sopenharmony_ci %5 = OpLabel 88fd4e5da5Sopenharmony_ci %11 = OpVariable %10 Function 89fd4e5da5Sopenharmony_ci %20 = OpVariable %19 Function 90fd4e5da5Sopenharmony_ci %31 = OpVariable %24 Function 91fd4e5da5Sopenharmony_ci %35 = OpVariable %14 Function 92fd4e5da5Sopenharmony_ci %15 = OpAccessChain %14 %11 %12 93fd4e5da5Sopenharmony_ci %21 = OpAccessChain %14 %11 %12 94fd4e5da5Sopenharmony_ci %22 = OpLoad %6 %21 95fd4e5da5Sopenharmony_ci %100 = OpCompositeConstruct %9 %12 %13 %22 96fd4e5da5Sopenharmony_ci OpStore %15 %13 97fd4e5da5Sopenharmony_ci %23 = OpConvertSToF %16 %22 98fd4e5da5Sopenharmony_ci %25 = OpAccessChain %24 %20 %12 99fd4e5da5Sopenharmony_ci OpStore %25 %23 100fd4e5da5Sopenharmony_ci %26 = OpAccessChain %14 %11 %12 101fd4e5da5Sopenharmony_ci %27 = OpLoad %6 %26 102fd4e5da5Sopenharmony_ci %29 = OpAccessChain %24 %20 %27 103fd4e5da5Sopenharmony_ci OpStore %29 %28 104fd4e5da5Sopenharmony_ci %32 = OpLoad %16 %31 105fd4e5da5Sopenharmony_ci %101 = OpCompositeConstruct %18 %28 %23 %32 %23 106fd4e5da5Sopenharmony_ci %50 = OpCopyObject %16 %23 107fd4e5da5Sopenharmony_ci %51 = OpCopyObject %16 %23 108fd4e5da5Sopenharmony_ci %33 = OpAccessChain %24 %20 %30 109fd4e5da5Sopenharmony_ci OpStore %33 %28 110fd4e5da5Sopenharmony_ci OpStore %33 %32 111fd4e5da5Sopenharmony_ci %36 = OpLoad %6 %35 112fd4e5da5Sopenharmony_ci %37 = OpAccessChain %14 %11 %34 113fd4e5da5Sopenharmony_ci OpStore %37 %36 114fd4e5da5Sopenharmony_ci %39 = OpAccessChain %14 %11 %12 115fd4e5da5Sopenharmony_ci %40 = OpLoad %6 %39 116fd4e5da5Sopenharmony_ci %41 = OpIAdd %6 %38 %40 117fd4e5da5Sopenharmony_ci %42 = OpAccessChain %14 %11 %30 118fd4e5da5Sopenharmony_ci OpStore %42 %41 119fd4e5da5Sopenharmony_ci OpReturn 120fd4e5da5Sopenharmony_ci OpFunctionEnd 121fd4e5da5Sopenharmony_ci )"; 122fd4e5da5Sopenharmony_ci 123fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 124fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 125fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); 126fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 127fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 128fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 129fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 130fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(context.get()), validator_options); 131fd4e5da5Sopenharmony_ci 132fd4e5da5Sopenharmony_ci transformation_context.GetFactManager()->MaybeAddFact( 133fd4e5da5Sopenharmony_ci MakeSynonymFact(12, {}, 100, {0})); 134fd4e5da5Sopenharmony_ci transformation_context.GetFactManager()->MaybeAddFact( 135fd4e5da5Sopenharmony_ci MakeSynonymFact(13, {}, 100, {1})); 136fd4e5da5Sopenharmony_ci transformation_context.GetFactManager()->MaybeAddFact( 137fd4e5da5Sopenharmony_ci MakeSynonymFact(22, {}, 100, {2})); 138fd4e5da5Sopenharmony_ci transformation_context.GetFactManager()->MaybeAddFact( 139fd4e5da5Sopenharmony_ci MakeSynonymFact(28, {}, 101, {0})); 140fd4e5da5Sopenharmony_ci transformation_context.GetFactManager()->MaybeAddFact( 141fd4e5da5Sopenharmony_ci MakeSynonymFact(23, {}, 101, {1})); 142fd4e5da5Sopenharmony_ci transformation_context.GetFactManager()->MaybeAddFact( 143fd4e5da5Sopenharmony_ci MakeSynonymFact(32, {}, 101, {2})); 144fd4e5da5Sopenharmony_ci transformation_context.GetFactManager()->MaybeAddFact( 145fd4e5da5Sopenharmony_ci MakeSynonymFact(23, {}, 101, {3})); 146fd4e5da5Sopenharmony_ci 147fd4e5da5Sopenharmony_ci // Replace %12 with %100[0] in '%25 = OpAccessChain %24 %20 %12' 148fd4e5da5Sopenharmony_ci auto instruction_descriptor_1 = 149fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(25, spv::Op::OpAccessChain, 0); 150fd4e5da5Sopenharmony_ci auto good_extract_1 = 151fd4e5da5Sopenharmony_ci TransformationCompositeExtract(instruction_descriptor_1, 102, 100, {0}); 152fd4e5da5Sopenharmony_ci // Bad: id already in use 153fd4e5da5Sopenharmony_ci auto bad_extract_1 = TransformationCompositeExtract( 154fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(25, spv::Op::OpAccessChain, 0), 25, 100, {0}); 155fd4e5da5Sopenharmony_ci ASSERT_TRUE( 156fd4e5da5Sopenharmony_ci good_extract_1.IsApplicable(context.get(), transformation_context)); 157fd4e5da5Sopenharmony_ci ASSERT_FALSE( 158fd4e5da5Sopenharmony_ci bad_extract_1.IsApplicable(context.get(), transformation_context)); 159fd4e5da5Sopenharmony_ci good_extract_1.Apply(context.get(), &transformation_context); 160fd4e5da5Sopenharmony_ci auto replacement_1 = TransformationReplaceIdWithSynonym( 161fd4e5da5Sopenharmony_ci MakeIdUseDescriptor(12, instruction_descriptor_1, 1), 102); 162fd4e5da5Sopenharmony_ci ASSERT_TRUE( 163fd4e5da5Sopenharmony_ci replacement_1.IsApplicable(context.get(), transformation_context)); 164fd4e5da5Sopenharmony_ci replacement_1.Apply(context.get(), &transformation_context); 165fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 166fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 167fd4e5da5Sopenharmony_ci 168fd4e5da5Sopenharmony_ci // Replace %13 with %100[1] in 'OpStore %15 %13' 169fd4e5da5Sopenharmony_ci auto instruction_descriptor_2 = 170fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(100, spv::Op::OpStore, 0); 171fd4e5da5Sopenharmony_ci auto good_extract_2 = 172fd4e5da5Sopenharmony_ci TransformationCompositeExtract(instruction_descriptor_2, 103, 100, {1}); 173fd4e5da5Sopenharmony_ci // No bad example provided here. 174fd4e5da5Sopenharmony_ci ASSERT_TRUE( 175fd4e5da5Sopenharmony_ci good_extract_2.IsApplicable(context.get(), transformation_context)); 176fd4e5da5Sopenharmony_ci good_extract_2.Apply(context.get(), &transformation_context); 177fd4e5da5Sopenharmony_ci auto replacement_2 = TransformationReplaceIdWithSynonym( 178fd4e5da5Sopenharmony_ci MakeIdUseDescriptor(13, instruction_descriptor_2, 1), 103); 179fd4e5da5Sopenharmony_ci ASSERT_TRUE( 180fd4e5da5Sopenharmony_ci replacement_2.IsApplicable(context.get(), transformation_context)); 181fd4e5da5Sopenharmony_ci replacement_2.Apply(context.get(), &transformation_context); 182fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 183fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 184fd4e5da5Sopenharmony_ci 185fd4e5da5Sopenharmony_ci // Replace %22 with %100[2] in '%23 = OpConvertSToF %16 %22' 186fd4e5da5Sopenharmony_ci auto instruction_descriptor_3 = 187fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(23, spv::Op::OpConvertSToF, 0); 188fd4e5da5Sopenharmony_ci auto good_extract_3 = 189fd4e5da5Sopenharmony_ci TransformationCompositeExtract(instruction_descriptor_3, 104, 100, {2}); 190fd4e5da5Sopenharmony_ci ASSERT_TRUE( 191fd4e5da5Sopenharmony_ci good_extract_3.IsApplicable(context.get(), transformation_context)); 192fd4e5da5Sopenharmony_ci good_extract_3.Apply(context.get(), &transformation_context); 193fd4e5da5Sopenharmony_ci auto replacement_3 = TransformationReplaceIdWithSynonym( 194fd4e5da5Sopenharmony_ci MakeIdUseDescriptor(22, instruction_descriptor_3, 0), 104); 195fd4e5da5Sopenharmony_ci // Bad: wrong input operand index 196fd4e5da5Sopenharmony_ci auto bad_replacement_3 = TransformationReplaceIdWithSynonym( 197fd4e5da5Sopenharmony_ci MakeIdUseDescriptor(22, instruction_descriptor_3, 1), 104); 198fd4e5da5Sopenharmony_ci ASSERT_TRUE( 199fd4e5da5Sopenharmony_ci replacement_3.IsApplicable(context.get(), transformation_context)); 200fd4e5da5Sopenharmony_ci ASSERT_FALSE( 201fd4e5da5Sopenharmony_ci bad_replacement_3.IsApplicable(context.get(), transformation_context)); 202fd4e5da5Sopenharmony_ci replacement_3.Apply(context.get(), &transformation_context); 203fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 204fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 205fd4e5da5Sopenharmony_ci 206fd4e5da5Sopenharmony_ci // Replace %28 with %101[0] in 'OpStore %33 %28' 207fd4e5da5Sopenharmony_ci auto instruction_descriptor_4 = 208fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(33, spv::Op::OpStore, 0); 209fd4e5da5Sopenharmony_ci auto good_extract_4 = 210fd4e5da5Sopenharmony_ci TransformationCompositeExtract(instruction_descriptor_4, 105, 101, {0}); 211fd4e5da5Sopenharmony_ci // Bad: instruction descriptor does not identify an appropriate instruction 212fd4e5da5Sopenharmony_ci auto bad_extract_4 = TransformationCompositeExtract( 213fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(33, spv::Op::OpCopyObject, 0), 105, 101, {0}); 214fd4e5da5Sopenharmony_ci ASSERT_TRUE( 215fd4e5da5Sopenharmony_ci good_extract_4.IsApplicable(context.get(), transformation_context)); 216fd4e5da5Sopenharmony_ci ASSERT_FALSE( 217fd4e5da5Sopenharmony_ci bad_extract_4.IsApplicable(context.get(), transformation_context)); 218fd4e5da5Sopenharmony_ci good_extract_4.Apply(context.get(), &transformation_context); 219fd4e5da5Sopenharmony_ci auto replacement_4 = TransformationReplaceIdWithSynonym( 220fd4e5da5Sopenharmony_ci MakeIdUseDescriptor(28, instruction_descriptor_4, 1), 105); 221fd4e5da5Sopenharmony_ci ASSERT_TRUE( 222fd4e5da5Sopenharmony_ci replacement_4.IsApplicable(context.get(), transformation_context)); 223fd4e5da5Sopenharmony_ci replacement_4.Apply(context.get(), &transformation_context); 224fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 225fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 226fd4e5da5Sopenharmony_ci 227fd4e5da5Sopenharmony_ci // Replace %23 with %101[1] in '%50 = OpCopyObject %16 %23' 228fd4e5da5Sopenharmony_ci auto instruction_descriptor_5 = 229fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(50, spv::Op::OpCopyObject, 0); 230fd4e5da5Sopenharmony_ci auto good_extract_5 = 231fd4e5da5Sopenharmony_ci TransformationCompositeExtract(instruction_descriptor_5, 106, 101, {1}); 232fd4e5da5Sopenharmony_ci ASSERT_TRUE( 233fd4e5da5Sopenharmony_ci good_extract_5.IsApplicable(context.get(), transformation_context)); 234fd4e5da5Sopenharmony_ci good_extract_5.Apply(context.get(), &transformation_context); 235fd4e5da5Sopenharmony_ci auto replacement_5 = TransformationReplaceIdWithSynonym( 236fd4e5da5Sopenharmony_ci MakeIdUseDescriptor(23, instruction_descriptor_5, 0), 106); 237fd4e5da5Sopenharmony_ci // Bad: wrong synonym fact being used 238fd4e5da5Sopenharmony_ci auto bad_replacement_5 = TransformationReplaceIdWithSynonym( 239fd4e5da5Sopenharmony_ci MakeIdUseDescriptor(23, instruction_descriptor_5, 0), 105); 240fd4e5da5Sopenharmony_ci ASSERT_TRUE( 241fd4e5da5Sopenharmony_ci replacement_5.IsApplicable(context.get(), transformation_context)); 242fd4e5da5Sopenharmony_ci ASSERT_FALSE( 243fd4e5da5Sopenharmony_ci bad_replacement_5.IsApplicable(context.get(), transformation_context)); 244fd4e5da5Sopenharmony_ci replacement_5.Apply(context.get(), &transformation_context); 245fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 246fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 247fd4e5da5Sopenharmony_ci 248fd4e5da5Sopenharmony_ci // Replace %32 with %101[2] in 'OpStore %33 %32' 249fd4e5da5Sopenharmony_ci auto instruction_descriptor_6 = 250fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(33, spv::Op::OpStore, 1); 251fd4e5da5Sopenharmony_ci auto good_extract_6 = 252fd4e5da5Sopenharmony_ci TransformationCompositeExtract(instruction_descriptor_6, 107, 101, {2}); 253fd4e5da5Sopenharmony_ci // Bad: id 1001 does not exist 254fd4e5da5Sopenharmony_ci auto bad_extract_6 = 255fd4e5da5Sopenharmony_ci TransformationCompositeExtract(instruction_descriptor_6, 107, 1001, {2}); 256fd4e5da5Sopenharmony_ci ASSERT_TRUE( 257fd4e5da5Sopenharmony_ci good_extract_6.IsApplicable(context.get(), transformation_context)); 258fd4e5da5Sopenharmony_ci ASSERT_FALSE( 259fd4e5da5Sopenharmony_ci bad_extract_6.IsApplicable(context.get(), transformation_context)); 260fd4e5da5Sopenharmony_ci good_extract_6.Apply(context.get(), &transformation_context); 261fd4e5da5Sopenharmony_ci auto replacement_6 = TransformationReplaceIdWithSynonym( 262fd4e5da5Sopenharmony_ci MakeIdUseDescriptor(32, instruction_descriptor_6, 1), 107); 263fd4e5da5Sopenharmony_ci ASSERT_TRUE( 264fd4e5da5Sopenharmony_ci replacement_6.IsApplicable(context.get(), transformation_context)); 265fd4e5da5Sopenharmony_ci replacement_6.Apply(context.get(), &transformation_context); 266fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 267fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 268fd4e5da5Sopenharmony_ci 269fd4e5da5Sopenharmony_ci // Replace %23 with %101[3] in '%51 = OpCopyObject %16 %23' 270fd4e5da5Sopenharmony_ci auto instruction_descriptor_7 = 271fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(51, spv::Op::OpCopyObject, 0); 272fd4e5da5Sopenharmony_ci auto good_extract_7 = 273fd4e5da5Sopenharmony_ci TransformationCompositeExtract(instruction_descriptor_7, 108, 101, {3}); 274fd4e5da5Sopenharmony_ci ASSERT_TRUE( 275fd4e5da5Sopenharmony_ci good_extract_7.IsApplicable(context.get(), transformation_context)); 276fd4e5da5Sopenharmony_ci good_extract_7.Apply(context.get(), &transformation_context); 277fd4e5da5Sopenharmony_ci auto replacement_7 = TransformationReplaceIdWithSynonym( 278fd4e5da5Sopenharmony_ci MakeIdUseDescriptor(23, instruction_descriptor_7, 0), 108); 279fd4e5da5Sopenharmony_ci // Bad: use id 0 is invalid 280fd4e5da5Sopenharmony_ci auto bad_replacement_7 = TransformationReplaceIdWithSynonym( 281fd4e5da5Sopenharmony_ci MakeIdUseDescriptor(0, instruction_descriptor_7, 0), 108); 282fd4e5da5Sopenharmony_ci ASSERT_TRUE( 283fd4e5da5Sopenharmony_ci replacement_7.IsApplicable(context.get(), transformation_context)); 284fd4e5da5Sopenharmony_ci ASSERT_FALSE( 285fd4e5da5Sopenharmony_ci bad_replacement_7.IsApplicable(context.get(), transformation_context)); 286fd4e5da5Sopenharmony_ci replacement_7.Apply(context.get(), &transformation_context); 287fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 288fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 289fd4e5da5Sopenharmony_ci 290fd4e5da5Sopenharmony_ci const std::string after_transformation = R"( 291fd4e5da5Sopenharmony_ci OpCapability Shader 292fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 293fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 294fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 295fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 296fd4e5da5Sopenharmony_ci OpSource ESSL 310 297fd4e5da5Sopenharmony_ci OpName %4 "main" 298fd4e5da5Sopenharmony_ci OpName %11 "A" 299fd4e5da5Sopenharmony_ci OpName %20 "B" 300fd4e5da5Sopenharmony_ci OpName %31 "g" 301fd4e5da5Sopenharmony_ci OpName %35 "h" 302fd4e5da5Sopenharmony_ci OpDecorate %11 RelaxedPrecision 303fd4e5da5Sopenharmony_ci OpDecorate %22 RelaxedPrecision 304fd4e5da5Sopenharmony_ci OpDecorate %27 RelaxedPrecision 305fd4e5da5Sopenharmony_ci OpDecorate %35 RelaxedPrecision 306fd4e5da5Sopenharmony_ci OpDecorate %36 RelaxedPrecision 307fd4e5da5Sopenharmony_ci OpDecorate %40 RelaxedPrecision 308fd4e5da5Sopenharmony_ci OpDecorate %41 RelaxedPrecision 309fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 310fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 311fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 312fd4e5da5Sopenharmony_ci %7 = OpTypeInt 32 0 313fd4e5da5Sopenharmony_ci %8 = OpConstant %7 3 314fd4e5da5Sopenharmony_ci %9 = OpTypeArray %6 %8 315fd4e5da5Sopenharmony_ci %10 = OpTypePointer Function %9 316fd4e5da5Sopenharmony_ci %12 = OpConstant %6 0 317fd4e5da5Sopenharmony_ci %13 = OpConstant %6 3 318fd4e5da5Sopenharmony_ci %14 = OpTypePointer Function %6 319fd4e5da5Sopenharmony_ci %16 = OpTypeFloat 32 320fd4e5da5Sopenharmony_ci %17 = OpConstant %7 4 321fd4e5da5Sopenharmony_ci %18 = OpTypeArray %16 %17 322fd4e5da5Sopenharmony_ci %19 = OpTypePointer Function %18 323fd4e5da5Sopenharmony_ci %24 = OpTypePointer Function %16 324fd4e5da5Sopenharmony_ci %28 = OpConstant %16 42 325fd4e5da5Sopenharmony_ci %30 = OpConstant %6 2 326fd4e5da5Sopenharmony_ci %34 = OpConstant %6 1 327fd4e5da5Sopenharmony_ci %38 = OpConstant %6 42 328fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 329fd4e5da5Sopenharmony_ci %5 = OpLabel 330fd4e5da5Sopenharmony_ci %11 = OpVariable %10 Function 331fd4e5da5Sopenharmony_ci %20 = OpVariable %19 Function 332fd4e5da5Sopenharmony_ci %31 = OpVariable %24 Function 333fd4e5da5Sopenharmony_ci %35 = OpVariable %14 Function 334fd4e5da5Sopenharmony_ci %15 = OpAccessChain %14 %11 %12 335fd4e5da5Sopenharmony_ci %21 = OpAccessChain %14 %11 %12 336fd4e5da5Sopenharmony_ci %22 = OpLoad %6 %21 337fd4e5da5Sopenharmony_ci %100 = OpCompositeConstruct %9 %12 %13 %22 338fd4e5da5Sopenharmony_ci %103 = OpCompositeExtract %6 %100 1 339fd4e5da5Sopenharmony_ci OpStore %15 %103 340fd4e5da5Sopenharmony_ci %104 = OpCompositeExtract %6 %100 2 341fd4e5da5Sopenharmony_ci %23 = OpConvertSToF %16 %104 342fd4e5da5Sopenharmony_ci %102 = OpCompositeExtract %6 %100 0 343fd4e5da5Sopenharmony_ci %25 = OpAccessChain %24 %20 %102 344fd4e5da5Sopenharmony_ci OpStore %25 %23 345fd4e5da5Sopenharmony_ci %26 = OpAccessChain %14 %11 %12 346fd4e5da5Sopenharmony_ci %27 = OpLoad %6 %26 347fd4e5da5Sopenharmony_ci %29 = OpAccessChain %24 %20 %27 348fd4e5da5Sopenharmony_ci OpStore %29 %28 349fd4e5da5Sopenharmony_ci %32 = OpLoad %16 %31 350fd4e5da5Sopenharmony_ci %101 = OpCompositeConstruct %18 %28 %23 %32 %23 351fd4e5da5Sopenharmony_ci %106 = OpCompositeExtract %16 %101 1 352fd4e5da5Sopenharmony_ci %50 = OpCopyObject %16 %106 353fd4e5da5Sopenharmony_ci %108 = OpCompositeExtract %16 %101 3 354fd4e5da5Sopenharmony_ci %51 = OpCopyObject %16 %108 355fd4e5da5Sopenharmony_ci %33 = OpAccessChain %24 %20 %30 356fd4e5da5Sopenharmony_ci %105 = OpCompositeExtract %16 %101 0 357fd4e5da5Sopenharmony_ci OpStore %33 %105 358fd4e5da5Sopenharmony_ci %107 = OpCompositeExtract %16 %101 2 359fd4e5da5Sopenharmony_ci OpStore %33 %107 360fd4e5da5Sopenharmony_ci %36 = OpLoad %6 %35 361fd4e5da5Sopenharmony_ci %37 = OpAccessChain %14 %11 %34 362fd4e5da5Sopenharmony_ci OpStore %37 %36 363fd4e5da5Sopenharmony_ci %39 = OpAccessChain %14 %11 %12 364fd4e5da5Sopenharmony_ci %40 = OpLoad %6 %39 365fd4e5da5Sopenharmony_ci %41 = OpIAdd %6 %38 %40 366fd4e5da5Sopenharmony_ci %42 = OpAccessChain %14 %11 %30 367fd4e5da5Sopenharmony_ci OpStore %42 %41 368fd4e5da5Sopenharmony_ci OpReturn 369fd4e5da5Sopenharmony_ci OpFunctionEnd 370fd4e5da5Sopenharmony_ci )"; 371fd4e5da5Sopenharmony_ci 372fd4e5da5Sopenharmony_ci ASSERT_TRUE(IsEqual(env, after_transformation, context.get())); 373fd4e5da5Sopenharmony_ci} 374fd4e5da5Sopenharmony_ci 375fd4e5da5Sopenharmony_ciTEST(DataSynonymTransformationTest, MatrixCompositeSynonyms) { 376fd4e5da5Sopenharmony_ci std::string shader = R"( 377fd4e5da5Sopenharmony_ci OpCapability Shader 378fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 379fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 380fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 381fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 382fd4e5da5Sopenharmony_ci OpSource ESSL 310 383fd4e5da5Sopenharmony_ci OpName %4 "main" 384fd4e5da5Sopenharmony_ci OpName %10 "m" 385fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 386fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 387fd4e5da5Sopenharmony_ci %6 = OpTypeFloat 32 388fd4e5da5Sopenharmony_ci %7 = OpTypeVector %6 4 389fd4e5da5Sopenharmony_ci %50 = OpUndef %7 390fd4e5da5Sopenharmony_ci %8 = OpTypeMatrix %7 3 391fd4e5da5Sopenharmony_ci %9 = OpTypePointer Function %8 392fd4e5da5Sopenharmony_ci %11 = OpTypeInt 32 1 393fd4e5da5Sopenharmony_ci %12 = OpConstant %11 0 394fd4e5da5Sopenharmony_ci %13 = OpConstant %6 1 395fd4e5da5Sopenharmony_ci %14 = OpConstantComposite %7 %13 %13 %13 %13 396fd4e5da5Sopenharmony_ci %15 = OpTypePointer Function %7 397fd4e5da5Sopenharmony_ci %17 = OpConstant %11 1 398fd4e5da5Sopenharmony_ci %18 = OpConstant %6 2 399fd4e5da5Sopenharmony_ci %19 = OpConstantComposite %7 %18 %18 %18 %18 400fd4e5da5Sopenharmony_ci %21 = OpConstant %11 2 401fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 402fd4e5da5Sopenharmony_ci %5 = OpLabel 403fd4e5da5Sopenharmony_ci %10 = OpVariable %9 Function 404fd4e5da5Sopenharmony_ci %16 = OpAccessChain %15 %10 %12 405fd4e5da5Sopenharmony_ci OpStore %16 %14 406fd4e5da5Sopenharmony_ci %20 = OpAccessChain %15 %10 %17 407fd4e5da5Sopenharmony_ci OpStore %20 %19 408fd4e5da5Sopenharmony_ci %22 = OpAccessChain %15 %10 %12 409fd4e5da5Sopenharmony_ci %23 = OpLoad %7 %22 410fd4e5da5Sopenharmony_ci %24 = OpAccessChain %15 %10 %17 411fd4e5da5Sopenharmony_ci %25 = OpLoad %7 %24 412fd4e5da5Sopenharmony_ci %100 = OpCompositeConstruct %8 %23 %25 %50 413fd4e5da5Sopenharmony_ci %26 = OpFAdd %7 %23 %25 414fd4e5da5Sopenharmony_ci %27 = OpAccessChain %15 %10 %21 415fd4e5da5Sopenharmony_ci OpStore %27 %26 416fd4e5da5Sopenharmony_ci OpReturn 417fd4e5da5Sopenharmony_ci OpFunctionEnd 418fd4e5da5Sopenharmony_ci )"; 419fd4e5da5Sopenharmony_ci 420fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 421fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 422fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); 423fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 424fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 425fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 426fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 427fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(context.get()), validator_options); 428fd4e5da5Sopenharmony_ci 429fd4e5da5Sopenharmony_ci transformation_context.GetFactManager()->MaybeAddFact( 430fd4e5da5Sopenharmony_ci MakeSynonymFact(23, {}, 100, {0})); 431fd4e5da5Sopenharmony_ci transformation_context.GetFactManager()->MaybeAddFact( 432fd4e5da5Sopenharmony_ci MakeSynonymFact(25, {}, 100, {1})); 433fd4e5da5Sopenharmony_ci transformation_context.GetFactManager()->MaybeAddFact( 434fd4e5da5Sopenharmony_ci MakeSynonymFact(50, {}, 100, {2})); 435fd4e5da5Sopenharmony_ci 436fd4e5da5Sopenharmony_ci // Replace %23 with %100[0] in '%26 = OpFAdd %7 %23 %25' 437fd4e5da5Sopenharmony_ci auto instruction_descriptor_1 = 438fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(26, spv::Op::OpFAdd, 0); 439fd4e5da5Sopenharmony_ci auto extract_1 = 440fd4e5da5Sopenharmony_ci TransformationCompositeExtract(instruction_descriptor_1, 101, 100, {0}); 441fd4e5da5Sopenharmony_ci ASSERT_TRUE(extract_1.IsApplicable(context.get(), transformation_context)); 442fd4e5da5Sopenharmony_ci extract_1.Apply(context.get(), &transformation_context); 443fd4e5da5Sopenharmony_ci auto replacement_1 = TransformationReplaceIdWithSynonym( 444fd4e5da5Sopenharmony_ci MakeIdUseDescriptor(23, instruction_descriptor_1, 0), 101); 445fd4e5da5Sopenharmony_ci ASSERT_TRUE( 446fd4e5da5Sopenharmony_ci replacement_1.IsApplicable(context.get(), transformation_context)); 447fd4e5da5Sopenharmony_ci replacement_1.Apply(context.get(), &transformation_context); 448fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 449fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 450fd4e5da5Sopenharmony_ci 451fd4e5da5Sopenharmony_ci // Replace %25 with %100[1] in '%26 = OpFAdd %7 %23 %25' 452fd4e5da5Sopenharmony_ci auto instruction_descriptor_2 = 453fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(26, spv::Op::OpFAdd, 0); 454fd4e5da5Sopenharmony_ci auto extract_2 = 455fd4e5da5Sopenharmony_ci TransformationCompositeExtract(instruction_descriptor_2, 102, 100, {1}); 456fd4e5da5Sopenharmony_ci ASSERT_TRUE(extract_2.IsApplicable(context.get(), transformation_context)); 457fd4e5da5Sopenharmony_ci extract_2.Apply(context.get(), &transformation_context); 458fd4e5da5Sopenharmony_ci auto replacement_2 = TransformationReplaceIdWithSynonym( 459fd4e5da5Sopenharmony_ci MakeIdUseDescriptor(25, instruction_descriptor_2, 1), 102); 460fd4e5da5Sopenharmony_ci ASSERT_TRUE( 461fd4e5da5Sopenharmony_ci replacement_2.IsApplicable(context.get(), transformation_context)); 462fd4e5da5Sopenharmony_ci replacement_2.Apply(context.get(), &transformation_context); 463fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 464fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 465fd4e5da5Sopenharmony_ci 466fd4e5da5Sopenharmony_ci const std::string after_transformation = R"( 467fd4e5da5Sopenharmony_ci OpCapability Shader 468fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 469fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 470fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 471fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 472fd4e5da5Sopenharmony_ci OpSource ESSL 310 473fd4e5da5Sopenharmony_ci OpName %4 "main" 474fd4e5da5Sopenharmony_ci OpName %10 "m" 475fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 476fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 477fd4e5da5Sopenharmony_ci %6 = OpTypeFloat 32 478fd4e5da5Sopenharmony_ci %7 = OpTypeVector %6 4 479fd4e5da5Sopenharmony_ci %50 = OpUndef %7 480fd4e5da5Sopenharmony_ci %8 = OpTypeMatrix %7 3 481fd4e5da5Sopenharmony_ci %9 = OpTypePointer Function %8 482fd4e5da5Sopenharmony_ci %11 = OpTypeInt 32 1 483fd4e5da5Sopenharmony_ci %12 = OpConstant %11 0 484fd4e5da5Sopenharmony_ci %13 = OpConstant %6 1 485fd4e5da5Sopenharmony_ci %14 = OpConstantComposite %7 %13 %13 %13 %13 486fd4e5da5Sopenharmony_ci %15 = OpTypePointer Function %7 487fd4e5da5Sopenharmony_ci %17 = OpConstant %11 1 488fd4e5da5Sopenharmony_ci %18 = OpConstant %6 2 489fd4e5da5Sopenharmony_ci %19 = OpConstantComposite %7 %18 %18 %18 %18 490fd4e5da5Sopenharmony_ci %21 = OpConstant %11 2 491fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 492fd4e5da5Sopenharmony_ci %5 = OpLabel 493fd4e5da5Sopenharmony_ci %10 = OpVariable %9 Function 494fd4e5da5Sopenharmony_ci %16 = OpAccessChain %15 %10 %12 495fd4e5da5Sopenharmony_ci OpStore %16 %14 496fd4e5da5Sopenharmony_ci %20 = OpAccessChain %15 %10 %17 497fd4e5da5Sopenharmony_ci OpStore %20 %19 498fd4e5da5Sopenharmony_ci %22 = OpAccessChain %15 %10 %12 499fd4e5da5Sopenharmony_ci %23 = OpLoad %7 %22 500fd4e5da5Sopenharmony_ci %24 = OpAccessChain %15 %10 %17 501fd4e5da5Sopenharmony_ci %25 = OpLoad %7 %24 502fd4e5da5Sopenharmony_ci %100 = OpCompositeConstruct %8 %23 %25 %50 503fd4e5da5Sopenharmony_ci %101 = OpCompositeExtract %7 %100 0 504fd4e5da5Sopenharmony_ci %102 = OpCompositeExtract %7 %100 1 505fd4e5da5Sopenharmony_ci %26 = OpFAdd %7 %101 %102 506fd4e5da5Sopenharmony_ci %27 = OpAccessChain %15 %10 %21 507fd4e5da5Sopenharmony_ci OpStore %27 %26 508fd4e5da5Sopenharmony_ci OpReturn 509fd4e5da5Sopenharmony_ci OpFunctionEnd 510fd4e5da5Sopenharmony_ci )"; 511fd4e5da5Sopenharmony_ci 512fd4e5da5Sopenharmony_ci ASSERT_TRUE(IsEqual(env, after_transformation, context.get())); 513fd4e5da5Sopenharmony_ci} 514fd4e5da5Sopenharmony_ci 515fd4e5da5Sopenharmony_ciTEST(DataSynonymTransformationTest, StructCompositeSynonyms) { 516fd4e5da5Sopenharmony_ci std::string shader = R"( 517fd4e5da5Sopenharmony_ci OpCapability Shader 518fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 519fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 520fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 521fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 522fd4e5da5Sopenharmony_ci OpSource ESSL 310 523fd4e5da5Sopenharmony_ci OpName %4 "main" 524fd4e5da5Sopenharmony_ci OpName %9 "Inner" 525fd4e5da5Sopenharmony_ci OpMemberName %9 0 "a" 526fd4e5da5Sopenharmony_ci OpMemberName %9 1 "b" 527fd4e5da5Sopenharmony_ci OpName %11 "i1" 528fd4e5da5Sopenharmony_ci OpName %17 "i2" 529fd4e5da5Sopenharmony_ci OpName %31 "Point" 530fd4e5da5Sopenharmony_ci OpMemberName %31 0 "x" 531fd4e5da5Sopenharmony_ci OpMemberName %31 1 "y" 532fd4e5da5Sopenharmony_ci OpMemberName %31 2 "z" 533fd4e5da5Sopenharmony_ci OpName %32 "Outer" 534fd4e5da5Sopenharmony_ci OpMemberName %32 0 "c" 535fd4e5da5Sopenharmony_ci OpMemberName %32 1 "d" 536fd4e5da5Sopenharmony_ci OpName %34 "o1" 537fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 538fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 539fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 540fd4e5da5Sopenharmony_ci %7 = OpTypeFloat 32 541fd4e5da5Sopenharmony_ci %8 = OpTypeVector %7 2 542fd4e5da5Sopenharmony_ci %9 = OpTypeStruct %6 %8 543fd4e5da5Sopenharmony_ci %10 = OpTypePointer Function %9 544fd4e5da5Sopenharmony_ci %12 = OpConstant %6 1 545fd4e5da5Sopenharmony_ci %13 = OpConstant %7 2 546fd4e5da5Sopenharmony_ci %14 = OpConstant %7 3 547fd4e5da5Sopenharmony_ci %15 = OpConstantComposite %8 %13 %14 548fd4e5da5Sopenharmony_ci %16 = OpConstantComposite %9 %12 %15 549fd4e5da5Sopenharmony_ci %18 = OpConstant %6 0 550fd4e5da5Sopenharmony_ci %19 = OpTypePointer Function %6 551fd4e5da5Sopenharmony_ci %24 = OpTypePointer Function %8 552fd4e5da5Sopenharmony_ci %27 = OpConstant %7 4 553fd4e5da5Sopenharmony_ci %31 = OpTypeStruct %7 %7 %7 554fd4e5da5Sopenharmony_ci %32 = OpTypeStruct %9 %31 555fd4e5da5Sopenharmony_ci %33 = OpTypePointer Function %32 556fd4e5da5Sopenharmony_ci %36 = OpConstant %7 10 557fd4e5da5Sopenharmony_ci %37 = OpTypeInt 32 0 558fd4e5da5Sopenharmony_ci %38 = OpConstant %37 0 559fd4e5da5Sopenharmony_ci %39 = OpTypePointer Function %7 560fd4e5da5Sopenharmony_ci %42 = OpConstant %37 1 561fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 562fd4e5da5Sopenharmony_ci %5 = OpLabel 563fd4e5da5Sopenharmony_ci %11 = OpVariable %10 Function 564fd4e5da5Sopenharmony_ci %17 = OpVariable %10 Function 565fd4e5da5Sopenharmony_ci %34 = OpVariable %33 Function 566fd4e5da5Sopenharmony_ci %101 = OpCompositeConstruct %31 %27 %36 %27 567fd4e5da5Sopenharmony_ci OpStore %11 %16 568fd4e5da5Sopenharmony_ci %20 = OpAccessChain %19 %11 %18 569fd4e5da5Sopenharmony_ci %21 = OpLoad %6 %20 570fd4e5da5Sopenharmony_ci %22 = OpIAdd %6 %21 %12 571fd4e5da5Sopenharmony_ci %102 = OpCompositeConstruct %9 %22 %15 572fd4e5da5Sopenharmony_ci %23 = OpAccessChain %19 %17 %18 573fd4e5da5Sopenharmony_ci OpStore %23 %22 574fd4e5da5Sopenharmony_ci %25 = OpAccessChain %24 %17 %12 575fd4e5da5Sopenharmony_ci %26 = OpLoad %8 %25 576fd4e5da5Sopenharmony_ci %28 = OpCompositeConstruct %8 %27 %27 577fd4e5da5Sopenharmony_ci %29 = OpFAdd %8 %26 %28 578fd4e5da5Sopenharmony_ci %30 = OpAccessChain %24 %17 %12 579fd4e5da5Sopenharmony_ci OpStore %30 %29 580fd4e5da5Sopenharmony_ci %35 = OpLoad %9 %11 581fd4e5da5Sopenharmony_ci %40 = OpAccessChain %39 %11 %12 %38 582fd4e5da5Sopenharmony_ci %41 = OpLoad %7 %40 583fd4e5da5Sopenharmony_ci %43 = OpAccessChain %39 %11 %12 %42 584fd4e5da5Sopenharmony_ci %44 = OpLoad %7 %43 585fd4e5da5Sopenharmony_ci %45 = OpCompositeConstruct %31 %36 %41 %44 586fd4e5da5Sopenharmony_ci %100 = OpCompositeConstruct %32 %16 %45 587fd4e5da5Sopenharmony_ci %46 = OpCompositeConstruct %32 %35 %45 588fd4e5da5Sopenharmony_ci OpStore %34 %46 589fd4e5da5Sopenharmony_ci OpReturn 590fd4e5da5Sopenharmony_ci OpFunctionEnd 591fd4e5da5Sopenharmony_ci )"; 592fd4e5da5Sopenharmony_ci 593fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 594fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 595fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); 596fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 597fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 598fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 599fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 600fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(context.get()), validator_options); 601fd4e5da5Sopenharmony_ci 602fd4e5da5Sopenharmony_ci transformation_context.GetFactManager()->MaybeAddFact( 603fd4e5da5Sopenharmony_ci MakeSynonymFact(16, {}, 100, {0})); 604fd4e5da5Sopenharmony_ci transformation_context.GetFactManager()->MaybeAddFact( 605fd4e5da5Sopenharmony_ci MakeSynonymFact(45, {}, 100, {1})); 606fd4e5da5Sopenharmony_ci transformation_context.GetFactManager()->MaybeAddFact( 607fd4e5da5Sopenharmony_ci MakeSynonymFact(27, {}, 101, {0})); 608fd4e5da5Sopenharmony_ci transformation_context.GetFactManager()->MaybeAddFact( 609fd4e5da5Sopenharmony_ci MakeSynonymFact(36, {}, 101, {1})); 610fd4e5da5Sopenharmony_ci transformation_context.GetFactManager()->MaybeAddFact( 611fd4e5da5Sopenharmony_ci MakeSynonymFact(27, {}, 101, {2})); 612fd4e5da5Sopenharmony_ci transformation_context.GetFactManager()->MaybeAddFact( 613fd4e5da5Sopenharmony_ci MakeSynonymFact(22, {}, 102, {0})); 614fd4e5da5Sopenharmony_ci transformation_context.GetFactManager()->MaybeAddFact( 615fd4e5da5Sopenharmony_ci MakeSynonymFact(15, {}, 102, {1})); 616fd4e5da5Sopenharmony_ci 617fd4e5da5Sopenharmony_ci // Replace %45 with %100[1] in '%46 = OpCompositeConstruct %32 %35 %45' 618fd4e5da5Sopenharmony_ci auto instruction_descriptor_1 = 619fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(46, spv::Op::OpCompositeConstruct, 0); 620fd4e5da5Sopenharmony_ci auto extract_1 = 621fd4e5da5Sopenharmony_ci TransformationCompositeExtract(instruction_descriptor_1, 201, 100, {1}); 622fd4e5da5Sopenharmony_ci ASSERT_TRUE(extract_1.IsApplicable(context.get(), transformation_context)); 623fd4e5da5Sopenharmony_ci extract_1.Apply(context.get(), &transformation_context); 624fd4e5da5Sopenharmony_ci auto replacement_1 = TransformationReplaceIdWithSynonym( 625fd4e5da5Sopenharmony_ci MakeIdUseDescriptor(45, instruction_descriptor_1, 1), 201); 626fd4e5da5Sopenharmony_ci ASSERT_TRUE( 627fd4e5da5Sopenharmony_ci replacement_1.IsApplicable(context.get(), transformation_context)); 628fd4e5da5Sopenharmony_ci replacement_1.Apply(context.get(), &transformation_context); 629fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 630fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 631fd4e5da5Sopenharmony_ci 632fd4e5da5Sopenharmony_ci // Replace second occurrence of %27 with %101[0] in '%28 = 633fd4e5da5Sopenharmony_ci // OpCompositeConstruct %8 %27 %27' 634fd4e5da5Sopenharmony_ci auto instruction_descriptor_2 = 635fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(28, spv::Op::OpCompositeConstruct, 0); 636fd4e5da5Sopenharmony_ci auto extract_2 = 637fd4e5da5Sopenharmony_ci TransformationCompositeExtract(instruction_descriptor_2, 202, 101, {0}); 638fd4e5da5Sopenharmony_ci ASSERT_TRUE(extract_2.IsApplicable(context.get(), transformation_context)); 639fd4e5da5Sopenharmony_ci extract_2.Apply(context.get(), &transformation_context); 640fd4e5da5Sopenharmony_ci auto replacement_2 = TransformationReplaceIdWithSynonym( 641fd4e5da5Sopenharmony_ci MakeIdUseDescriptor(27, instruction_descriptor_2, 1), 202); 642fd4e5da5Sopenharmony_ci ASSERT_TRUE( 643fd4e5da5Sopenharmony_ci replacement_2.IsApplicable(context.get(), transformation_context)); 644fd4e5da5Sopenharmony_ci replacement_2.Apply(context.get(), &transformation_context); 645fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 646fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 647fd4e5da5Sopenharmony_ci 648fd4e5da5Sopenharmony_ci // Replace %36 with %101[1] in '%45 = OpCompositeConstruct %31 %36 %41 %44' 649fd4e5da5Sopenharmony_ci auto instruction_descriptor_3 = 650fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(45, spv::Op::OpCompositeConstruct, 0); 651fd4e5da5Sopenharmony_ci auto extract_3 = 652fd4e5da5Sopenharmony_ci TransformationCompositeExtract(instruction_descriptor_3, 203, 101, {1}); 653fd4e5da5Sopenharmony_ci ASSERT_TRUE(extract_3.IsApplicable(context.get(), transformation_context)); 654fd4e5da5Sopenharmony_ci extract_3.Apply(context.get(), &transformation_context); 655fd4e5da5Sopenharmony_ci auto replacement_3 = TransformationReplaceIdWithSynonym( 656fd4e5da5Sopenharmony_ci MakeIdUseDescriptor(36, instruction_descriptor_3, 0), 203); 657fd4e5da5Sopenharmony_ci ASSERT_TRUE( 658fd4e5da5Sopenharmony_ci replacement_3.IsApplicable(context.get(), transformation_context)); 659fd4e5da5Sopenharmony_ci replacement_3.Apply(context.get(), &transformation_context); 660fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 661fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 662fd4e5da5Sopenharmony_ci 663fd4e5da5Sopenharmony_ci // Replace first occurrence of %27 with %101[2] in '%28 = OpCompositeConstruct 664fd4e5da5Sopenharmony_ci // %8 %27 %27' 665fd4e5da5Sopenharmony_ci auto instruction_descriptor_4 = 666fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(28, spv::Op::OpCompositeConstruct, 0); 667fd4e5da5Sopenharmony_ci auto extract_4 = 668fd4e5da5Sopenharmony_ci TransformationCompositeExtract(instruction_descriptor_4, 204, 101, {2}); 669fd4e5da5Sopenharmony_ci ASSERT_TRUE(extract_4.IsApplicable(context.get(), transformation_context)); 670fd4e5da5Sopenharmony_ci extract_4.Apply(context.get(), &transformation_context); 671fd4e5da5Sopenharmony_ci auto replacement_4 = TransformationReplaceIdWithSynonym( 672fd4e5da5Sopenharmony_ci MakeIdUseDescriptor(27, instruction_descriptor_4, 0), 204); 673fd4e5da5Sopenharmony_ci ASSERT_TRUE( 674fd4e5da5Sopenharmony_ci replacement_4.IsApplicable(context.get(), transformation_context)); 675fd4e5da5Sopenharmony_ci replacement_4.Apply(context.get(), &transformation_context); 676fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 677fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 678fd4e5da5Sopenharmony_ci 679fd4e5da5Sopenharmony_ci // Replace %22 with %102[0] in 'OpStore %23 %22' 680fd4e5da5Sopenharmony_ci auto instruction_descriptor_5 = 681fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(23, spv::Op::OpStore, 0); 682fd4e5da5Sopenharmony_ci auto extract_5 = 683fd4e5da5Sopenharmony_ci TransformationCompositeExtract(instruction_descriptor_5, 205, 102, {0}); 684fd4e5da5Sopenharmony_ci ASSERT_TRUE(extract_5.IsApplicable(context.get(), transformation_context)); 685fd4e5da5Sopenharmony_ci extract_5.Apply(context.get(), &transformation_context); 686fd4e5da5Sopenharmony_ci auto replacement_5 = TransformationReplaceIdWithSynonym( 687fd4e5da5Sopenharmony_ci MakeIdUseDescriptor(22, instruction_descriptor_5, 1), 205); 688fd4e5da5Sopenharmony_ci ASSERT_TRUE( 689fd4e5da5Sopenharmony_ci replacement_5.IsApplicable(context.get(), transformation_context)); 690fd4e5da5Sopenharmony_ci replacement_5.Apply(context.get(), &transformation_context); 691fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 692fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 693fd4e5da5Sopenharmony_ci 694fd4e5da5Sopenharmony_ci const std::string after_transformation = R"( 695fd4e5da5Sopenharmony_ci OpCapability Shader 696fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 697fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 698fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 699fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 700fd4e5da5Sopenharmony_ci OpSource ESSL 310 701fd4e5da5Sopenharmony_ci OpName %4 "main" 702fd4e5da5Sopenharmony_ci OpName %9 "Inner" 703fd4e5da5Sopenharmony_ci OpMemberName %9 0 "a" 704fd4e5da5Sopenharmony_ci OpMemberName %9 1 "b" 705fd4e5da5Sopenharmony_ci OpName %11 "i1" 706fd4e5da5Sopenharmony_ci OpName %17 "i2" 707fd4e5da5Sopenharmony_ci OpName %31 "Point" 708fd4e5da5Sopenharmony_ci OpMemberName %31 0 "x" 709fd4e5da5Sopenharmony_ci OpMemberName %31 1 "y" 710fd4e5da5Sopenharmony_ci OpMemberName %31 2 "z" 711fd4e5da5Sopenharmony_ci OpName %32 "Outer" 712fd4e5da5Sopenharmony_ci OpMemberName %32 0 "c" 713fd4e5da5Sopenharmony_ci OpMemberName %32 1 "d" 714fd4e5da5Sopenharmony_ci OpName %34 "o1" 715fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 716fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 717fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 718fd4e5da5Sopenharmony_ci %7 = OpTypeFloat 32 719fd4e5da5Sopenharmony_ci %8 = OpTypeVector %7 2 720fd4e5da5Sopenharmony_ci %9 = OpTypeStruct %6 %8 721fd4e5da5Sopenharmony_ci %10 = OpTypePointer Function %9 722fd4e5da5Sopenharmony_ci %12 = OpConstant %6 1 723fd4e5da5Sopenharmony_ci %13 = OpConstant %7 2 724fd4e5da5Sopenharmony_ci %14 = OpConstant %7 3 725fd4e5da5Sopenharmony_ci %15 = OpConstantComposite %8 %13 %14 726fd4e5da5Sopenharmony_ci %16 = OpConstantComposite %9 %12 %15 727fd4e5da5Sopenharmony_ci %18 = OpConstant %6 0 728fd4e5da5Sopenharmony_ci %19 = OpTypePointer Function %6 729fd4e5da5Sopenharmony_ci %24 = OpTypePointer Function %8 730fd4e5da5Sopenharmony_ci %27 = OpConstant %7 4 731fd4e5da5Sopenharmony_ci %31 = OpTypeStruct %7 %7 %7 732fd4e5da5Sopenharmony_ci %32 = OpTypeStruct %9 %31 733fd4e5da5Sopenharmony_ci %33 = OpTypePointer Function %32 734fd4e5da5Sopenharmony_ci %36 = OpConstant %7 10 735fd4e5da5Sopenharmony_ci %37 = OpTypeInt 32 0 736fd4e5da5Sopenharmony_ci %38 = OpConstant %37 0 737fd4e5da5Sopenharmony_ci %39 = OpTypePointer Function %7 738fd4e5da5Sopenharmony_ci %42 = OpConstant %37 1 739fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 740fd4e5da5Sopenharmony_ci %5 = OpLabel 741fd4e5da5Sopenharmony_ci %11 = OpVariable %10 Function 742fd4e5da5Sopenharmony_ci %17 = OpVariable %10 Function 743fd4e5da5Sopenharmony_ci %34 = OpVariable %33 Function 744fd4e5da5Sopenharmony_ci %101 = OpCompositeConstruct %31 %27 %36 %27 745fd4e5da5Sopenharmony_ci OpStore %11 %16 746fd4e5da5Sopenharmony_ci %20 = OpAccessChain %19 %11 %18 747fd4e5da5Sopenharmony_ci %21 = OpLoad %6 %20 748fd4e5da5Sopenharmony_ci %22 = OpIAdd %6 %21 %12 749fd4e5da5Sopenharmony_ci %102 = OpCompositeConstruct %9 %22 %15 750fd4e5da5Sopenharmony_ci %23 = OpAccessChain %19 %17 %18 751fd4e5da5Sopenharmony_ci %205 = OpCompositeExtract %6 %102 0 752fd4e5da5Sopenharmony_ci OpStore %23 %205 753fd4e5da5Sopenharmony_ci %25 = OpAccessChain %24 %17 %12 754fd4e5da5Sopenharmony_ci %26 = OpLoad %8 %25 755fd4e5da5Sopenharmony_ci %202 = OpCompositeExtract %7 %101 0 756fd4e5da5Sopenharmony_ci %204 = OpCompositeExtract %7 %101 2 757fd4e5da5Sopenharmony_ci %28 = OpCompositeConstruct %8 %204 %202 758fd4e5da5Sopenharmony_ci %29 = OpFAdd %8 %26 %28 759fd4e5da5Sopenharmony_ci %30 = OpAccessChain %24 %17 %12 760fd4e5da5Sopenharmony_ci OpStore %30 %29 761fd4e5da5Sopenharmony_ci %35 = OpLoad %9 %11 762fd4e5da5Sopenharmony_ci %40 = OpAccessChain %39 %11 %12 %38 763fd4e5da5Sopenharmony_ci %41 = OpLoad %7 %40 764fd4e5da5Sopenharmony_ci %43 = OpAccessChain %39 %11 %12 %42 765fd4e5da5Sopenharmony_ci %44 = OpLoad %7 %43 766fd4e5da5Sopenharmony_ci %203 = OpCompositeExtract %7 %101 1 767fd4e5da5Sopenharmony_ci %45 = OpCompositeConstruct %31 %203 %41 %44 768fd4e5da5Sopenharmony_ci %100 = OpCompositeConstruct %32 %16 %45 769fd4e5da5Sopenharmony_ci %201 = OpCompositeExtract %31 %100 1 770fd4e5da5Sopenharmony_ci %46 = OpCompositeConstruct %32 %35 %201 771fd4e5da5Sopenharmony_ci OpStore %34 %46 772fd4e5da5Sopenharmony_ci OpReturn 773fd4e5da5Sopenharmony_ci OpFunctionEnd 774fd4e5da5Sopenharmony_ci )"; 775fd4e5da5Sopenharmony_ci 776fd4e5da5Sopenharmony_ci ASSERT_TRUE(IsEqual(env, after_transformation, context.get())); 777fd4e5da5Sopenharmony_ci} 778fd4e5da5Sopenharmony_ci 779fd4e5da5Sopenharmony_ciTEST(DataSynonymTransformationTest, VectorCompositeSynonyms) { 780fd4e5da5Sopenharmony_ci std::string shader = R"( 781fd4e5da5Sopenharmony_ci OpCapability Shader 782fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 783fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 784fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 785fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 786fd4e5da5Sopenharmony_ci OpSource ESSL 310 787fd4e5da5Sopenharmony_ci OpName %4 "main" 788fd4e5da5Sopenharmony_ci OpName %8 "f" 789fd4e5da5Sopenharmony_ci OpName %12 "v2" 790fd4e5da5Sopenharmony_ci OpName %18 "v3" 791fd4e5da5Sopenharmony_ci OpName %23 "v4" 792fd4e5da5Sopenharmony_ci OpName %32 "b" 793fd4e5da5Sopenharmony_ci OpName %36 "bv2" 794fd4e5da5Sopenharmony_ci OpName %41 "bv3" 795fd4e5da5Sopenharmony_ci OpName %50 "bv4" 796fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 797fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 798fd4e5da5Sopenharmony_ci %6 = OpTypeFloat 32 799fd4e5da5Sopenharmony_ci %7 = OpTypePointer Function %6 800fd4e5da5Sopenharmony_ci %9 = OpConstant %6 42 801fd4e5da5Sopenharmony_ci %10 = OpTypeVector %6 2 802fd4e5da5Sopenharmony_ci %11 = OpTypePointer Function %10 803fd4e5da5Sopenharmony_ci %16 = OpTypeVector %6 3 804fd4e5da5Sopenharmony_ci %17 = OpTypePointer Function %16 805fd4e5da5Sopenharmony_ci %21 = OpTypeVector %6 4 806fd4e5da5Sopenharmony_ci %22 = OpTypePointer Function %21 807fd4e5da5Sopenharmony_ci %30 = OpTypeBool 808fd4e5da5Sopenharmony_ci %31 = OpTypePointer Function %30 809fd4e5da5Sopenharmony_ci %33 = OpConstantFalse %30 810fd4e5da5Sopenharmony_ci %34 = OpTypeVector %30 2 811fd4e5da5Sopenharmony_ci %35 = OpTypePointer Function %34 812fd4e5da5Sopenharmony_ci %37 = OpConstantTrue %30 813fd4e5da5Sopenharmony_ci %38 = OpConstantComposite %34 %37 %37 814fd4e5da5Sopenharmony_ci %39 = OpTypeVector %30 3 815fd4e5da5Sopenharmony_ci %40 = OpTypePointer Function %39 816fd4e5da5Sopenharmony_ci %48 = OpTypeVector %30 4 817fd4e5da5Sopenharmony_ci %49 = OpTypePointer Function %48 818fd4e5da5Sopenharmony_ci %51 = OpTypeInt 32 0 819fd4e5da5Sopenharmony_ci %52 = OpConstant %51 2 820fd4e5da5Sopenharmony_ci %55 = OpConstant %6 0 821fd4e5da5Sopenharmony_ci %57 = OpConstant %51 1 822fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 823fd4e5da5Sopenharmony_ci %5 = OpLabel 824fd4e5da5Sopenharmony_ci %8 = OpVariable %7 Function 825fd4e5da5Sopenharmony_ci %12 = OpVariable %11 Function 826fd4e5da5Sopenharmony_ci %18 = OpVariable %17 Function 827fd4e5da5Sopenharmony_ci %23 = OpVariable %22 Function 828fd4e5da5Sopenharmony_ci %32 = OpVariable %31 Function 829fd4e5da5Sopenharmony_ci %36 = OpVariable %35 Function 830fd4e5da5Sopenharmony_ci %41 = OpVariable %40 Function 831fd4e5da5Sopenharmony_ci %50 = OpVariable %49 Function 832fd4e5da5Sopenharmony_ci OpStore %8 %9 833fd4e5da5Sopenharmony_ci %13 = OpLoad %6 %8 834fd4e5da5Sopenharmony_ci %14 = OpLoad %6 %8 835fd4e5da5Sopenharmony_ci %15 = OpCompositeConstruct %10 %13 %14 836fd4e5da5Sopenharmony_ci OpStore %12 %15 837fd4e5da5Sopenharmony_ci %19 = OpLoad %10 %12 838fd4e5da5Sopenharmony_ci %20 = OpVectorShuffle %16 %19 %19 0 0 1 839fd4e5da5Sopenharmony_ci OpStore %18 %20 840fd4e5da5Sopenharmony_ci %24 = OpLoad %16 %18 841fd4e5da5Sopenharmony_ci %25 = OpLoad %6 %8 842fd4e5da5Sopenharmony_ci %26 = OpCompositeExtract %6 %24 0 843fd4e5da5Sopenharmony_ci %27 = OpCompositeExtract %6 %24 1 844fd4e5da5Sopenharmony_ci %28 = OpCompositeExtract %6 %24 2 845fd4e5da5Sopenharmony_ci %29 = OpCompositeConstruct %21 %26 %27 %28 %25 846fd4e5da5Sopenharmony_ci OpStore %23 %29 847fd4e5da5Sopenharmony_ci OpStore %32 %33 848fd4e5da5Sopenharmony_ci OpStore %36 %38 849fd4e5da5Sopenharmony_ci %42 = OpLoad %30 %32 850fd4e5da5Sopenharmony_ci %43 = OpLoad %34 %36 851fd4e5da5Sopenharmony_ci %44 = OpVectorShuffle %34 %43 %43 0 0 852fd4e5da5Sopenharmony_ci %45 = OpCompositeExtract %30 %44 0 853fd4e5da5Sopenharmony_ci %46 = OpCompositeExtract %30 %44 1 854fd4e5da5Sopenharmony_ci %47 = OpCompositeConstruct %39 %42 %45 %46 855fd4e5da5Sopenharmony_ci OpStore %41 %47 856fd4e5da5Sopenharmony_ci %53 = OpAccessChain %7 %23 %52 857fd4e5da5Sopenharmony_ci %54 = OpLoad %6 %53 858fd4e5da5Sopenharmony_ci 859fd4e5da5Sopenharmony_ci %100 = OpCompositeConstruct %21 %20 %54 860fd4e5da5Sopenharmony_ci %101 = OpCompositeConstruct %21 %15 %19 861fd4e5da5Sopenharmony_ci %102 = OpCompositeConstruct %16 %27 %15 862fd4e5da5Sopenharmony_ci %103 = OpCompositeConstruct %48 %33 %47 863fd4e5da5Sopenharmony_ci %104 = OpCompositeConstruct %34 %42 %45 864fd4e5da5Sopenharmony_ci %105 = OpCompositeConstruct %39 %38 %46 865fd4e5da5Sopenharmony_ci 866fd4e5da5Sopenharmony_ci %86 = OpCopyObject %30 %33 867fd4e5da5Sopenharmony_ci %56 = OpFOrdNotEqual %30 %54 %55 868fd4e5da5Sopenharmony_ci %80 = OpCopyObject %16 %20 869fd4e5da5Sopenharmony_ci %58 = OpAccessChain %7 %18 %57 870fd4e5da5Sopenharmony_ci %59 = OpLoad %6 %58 871fd4e5da5Sopenharmony_ci %60 = OpFOrdNotEqual %30 %59 %55 872fd4e5da5Sopenharmony_ci %61 = OpLoad %34 %36 873fd4e5da5Sopenharmony_ci %62 = OpLogicalAnd %30 %45 %46 874fd4e5da5Sopenharmony_ci %63 = OpLogicalOr %30 %45 %46 875fd4e5da5Sopenharmony_ci %64 = OpCompositeConstruct %48 %56 %60 %62 %63 876fd4e5da5Sopenharmony_ci OpStore %12 %15 877fd4e5da5Sopenharmony_ci %81 = OpVectorShuffle %16 %19 %19 0 0 1 878fd4e5da5Sopenharmony_ci %82 = OpCompositeConstruct %21 %26 %27 %28 %25 879fd4e5da5Sopenharmony_ci %83 = OpCopyObject %10 %15 880fd4e5da5Sopenharmony_ci %84 = OpCopyObject %39 %47 881fd4e5da5Sopenharmony_ci OpStore %50 %64 882fd4e5da5Sopenharmony_ci %85 = OpCopyObject %30 %42 883fd4e5da5Sopenharmony_ci OpStore %36 %38 884fd4e5da5Sopenharmony_ci OpReturn 885fd4e5da5Sopenharmony_ci OpFunctionEnd 886fd4e5da5Sopenharmony_ci )"; 887fd4e5da5Sopenharmony_ci 888fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 889fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 890fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); 891fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 892fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 893fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 894fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 895fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(context.get()), validator_options); 896fd4e5da5Sopenharmony_ci 897fd4e5da5Sopenharmony_ci transformation_context.GetFactManager()->MaybeAddFact( 898fd4e5da5Sopenharmony_ci MakeSynonymFact(20, {0}, 100, {0})); 899fd4e5da5Sopenharmony_ci transformation_context.GetFactManager()->MaybeAddFact( 900fd4e5da5Sopenharmony_ci MakeSynonymFact(20, {1}, 100, {1})); 901fd4e5da5Sopenharmony_ci transformation_context.GetFactManager()->MaybeAddFact( 902fd4e5da5Sopenharmony_ci MakeSynonymFact(20, {2}, 100, {2})); 903fd4e5da5Sopenharmony_ci transformation_context.GetFactManager()->MaybeAddFact( 904fd4e5da5Sopenharmony_ci MakeSynonymFact(54, {}, 100, {3})); 905fd4e5da5Sopenharmony_ci transformation_context.GetFactManager()->MaybeAddFact( 906fd4e5da5Sopenharmony_ci MakeSynonymFact(15, {0}, 101, {0})); 907fd4e5da5Sopenharmony_ci transformation_context.GetFactManager()->MaybeAddFact( 908fd4e5da5Sopenharmony_ci MakeSynonymFact(15, {1}, 101, {1})); 909fd4e5da5Sopenharmony_ci transformation_context.GetFactManager()->MaybeAddFact( 910fd4e5da5Sopenharmony_ci MakeSynonymFact(19, {0}, 101, {2})); 911fd4e5da5Sopenharmony_ci transformation_context.GetFactManager()->MaybeAddFact( 912fd4e5da5Sopenharmony_ci MakeSynonymFact(19, {1}, 101, {3})); 913fd4e5da5Sopenharmony_ci transformation_context.GetFactManager()->MaybeAddFact( 914fd4e5da5Sopenharmony_ci MakeSynonymFact(27, {}, 102, {0})); 915fd4e5da5Sopenharmony_ci transformation_context.GetFactManager()->MaybeAddFact( 916fd4e5da5Sopenharmony_ci MakeSynonymFact(15, {0}, 102, {1})); 917fd4e5da5Sopenharmony_ci transformation_context.GetFactManager()->MaybeAddFact( 918fd4e5da5Sopenharmony_ci MakeSynonymFact(15, {1}, 102, {2})); 919fd4e5da5Sopenharmony_ci transformation_context.GetFactManager()->MaybeAddFact( 920fd4e5da5Sopenharmony_ci MakeSynonymFact(33, {}, 103, {0})); 921fd4e5da5Sopenharmony_ci transformation_context.GetFactManager()->MaybeAddFact( 922fd4e5da5Sopenharmony_ci MakeSynonymFact(47, {0}, 103, {1})); 923fd4e5da5Sopenharmony_ci transformation_context.GetFactManager()->MaybeAddFact( 924fd4e5da5Sopenharmony_ci MakeSynonymFact(47, {1}, 103, {2})); 925fd4e5da5Sopenharmony_ci transformation_context.GetFactManager()->MaybeAddFact( 926fd4e5da5Sopenharmony_ci MakeSynonymFact(47, {2}, 103, {3})); 927fd4e5da5Sopenharmony_ci transformation_context.GetFactManager()->MaybeAddFact( 928fd4e5da5Sopenharmony_ci MakeSynonymFact(42, {}, 104, {0})); 929fd4e5da5Sopenharmony_ci transformation_context.GetFactManager()->MaybeAddFact( 930fd4e5da5Sopenharmony_ci MakeSynonymFact(45, {}, 104, {1})); 931fd4e5da5Sopenharmony_ci transformation_context.GetFactManager()->MaybeAddFact( 932fd4e5da5Sopenharmony_ci MakeSynonymFact(38, {0}, 105, {0})); 933fd4e5da5Sopenharmony_ci transformation_context.GetFactManager()->MaybeAddFact( 934fd4e5da5Sopenharmony_ci MakeSynonymFact(38, {1}, 105, {1})); 935fd4e5da5Sopenharmony_ci transformation_context.GetFactManager()->MaybeAddFact( 936fd4e5da5Sopenharmony_ci MakeSynonymFact(46, {}, 105, {2})); 937fd4e5da5Sopenharmony_ci 938fd4e5da5Sopenharmony_ci // Replace %20 with %100[0:2] in '%80 = OpCopyObject %16 %20' 939fd4e5da5Sopenharmony_ci auto instruction_descriptor_1 = 940fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(80, spv::Op::OpCopyObject, 0); 941fd4e5da5Sopenharmony_ci auto shuffle_1 = TransformationVectorShuffle(instruction_descriptor_1, 200, 942fd4e5da5Sopenharmony_ci 100, 100, {0, 1, 2}); 943fd4e5da5Sopenharmony_ci ASSERT_TRUE(shuffle_1.IsApplicable(context.get(), transformation_context)); 944fd4e5da5Sopenharmony_ci shuffle_1.Apply(context.get(), &transformation_context); 945fd4e5da5Sopenharmony_ci transformation_context.GetFactManager()->ComputeClosureOfFacts(100); 946fd4e5da5Sopenharmony_ci 947fd4e5da5Sopenharmony_ci auto replacement_1 = TransformationReplaceIdWithSynonym( 948fd4e5da5Sopenharmony_ci MakeIdUseDescriptor(20, instruction_descriptor_1, 0), 200); 949fd4e5da5Sopenharmony_ci ASSERT_TRUE( 950fd4e5da5Sopenharmony_ci replacement_1.IsApplicable(context.get(), transformation_context)); 951fd4e5da5Sopenharmony_ci replacement_1.Apply(context.get(), &transformation_context); 952fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 953fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 954fd4e5da5Sopenharmony_ci 955fd4e5da5Sopenharmony_ci // Replace %54 with %100[3] in '%56 = OpFOrdNotEqual %30 %54 %55' 956fd4e5da5Sopenharmony_ci auto instruction_descriptor_2 = 957fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(56, spv::Op::OpFOrdNotEqual, 0); 958fd4e5da5Sopenharmony_ci auto extract_2 = 959fd4e5da5Sopenharmony_ci TransformationCompositeExtract(instruction_descriptor_2, 201, 100, {3}); 960fd4e5da5Sopenharmony_ci 961fd4e5da5Sopenharmony_ci ASSERT_TRUE(extract_2.IsApplicable(context.get(), transformation_context)); 962fd4e5da5Sopenharmony_ci extract_2.Apply(context.get(), &transformation_context); 963fd4e5da5Sopenharmony_ci auto replacement_2 = TransformationReplaceIdWithSynonym( 964fd4e5da5Sopenharmony_ci MakeIdUseDescriptor(54, instruction_descriptor_2, 0), 201); 965fd4e5da5Sopenharmony_ci ASSERT_TRUE( 966fd4e5da5Sopenharmony_ci replacement_2.IsApplicable(context.get(), transformation_context)); 967fd4e5da5Sopenharmony_ci replacement_2.Apply(context.get(), &transformation_context); 968fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 969fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 970fd4e5da5Sopenharmony_ci 971fd4e5da5Sopenharmony_ci // Replace %15 with %101[0:1] in 'OpStore %12 %15' 972fd4e5da5Sopenharmony_ci auto instruction_descriptor_3 = 973fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(64, spv::Op::OpStore, 0); 974fd4e5da5Sopenharmony_ci auto shuffle_3 = TransformationVectorShuffle(instruction_descriptor_3, 202, 975fd4e5da5Sopenharmony_ci 101, 101, {0, 1}); 976fd4e5da5Sopenharmony_ci ASSERT_TRUE(shuffle_3.IsApplicable(context.get(), transformation_context)); 977fd4e5da5Sopenharmony_ci shuffle_3.Apply(context.get(), &transformation_context); 978fd4e5da5Sopenharmony_ci transformation_context.GetFactManager()->ComputeClosureOfFacts(100); 979fd4e5da5Sopenharmony_ci 980fd4e5da5Sopenharmony_ci auto replacement_3 = TransformationReplaceIdWithSynonym( 981fd4e5da5Sopenharmony_ci MakeIdUseDescriptor(15, instruction_descriptor_3, 1), 202); 982fd4e5da5Sopenharmony_ci ASSERT_TRUE( 983fd4e5da5Sopenharmony_ci replacement_3.IsApplicable(context.get(), transformation_context)); 984fd4e5da5Sopenharmony_ci replacement_3.Apply(context.get(), &transformation_context); 985fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 986fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 987fd4e5da5Sopenharmony_ci 988fd4e5da5Sopenharmony_ci // Replace %19 with %101[2:3] in '%81 = OpVectorShuffle %16 %19 %19 0 0 1' 989fd4e5da5Sopenharmony_ci auto instruction_descriptor_4 = 990fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(81, spv::Op::OpVectorShuffle, 0); 991fd4e5da5Sopenharmony_ci auto shuffle_4 = TransformationVectorShuffle(instruction_descriptor_4, 203, 992fd4e5da5Sopenharmony_ci 101, 101, {2, 3}); 993fd4e5da5Sopenharmony_ci ASSERT_TRUE(shuffle_4.IsApplicable(context.get(), transformation_context)); 994fd4e5da5Sopenharmony_ci shuffle_4.Apply(context.get(), &transformation_context); 995fd4e5da5Sopenharmony_ci transformation_context.GetFactManager()->ComputeClosureOfFacts(100); 996fd4e5da5Sopenharmony_ci 997fd4e5da5Sopenharmony_ci auto replacement_4 = TransformationReplaceIdWithSynonym( 998fd4e5da5Sopenharmony_ci MakeIdUseDescriptor(19, instruction_descriptor_4, 0), 203); 999fd4e5da5Sopenharmony_ci ASSERT_TRUE( 1000fd4e5da5Sopenharmony_ci replacement_4.IsApplicable(context.get(), transformation_context)); 1001fd4e5da5Sopenharmony_ci replacement_4.Apply(context.get(), &transformation_context); 1002fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 1003fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 1004fd4e5da5Sopenharmony_ci 1005fd4e5da5Sopenharmony_ci // Replace %27 with %102[0] in '%82 = OpCompositeConstruct %21 %26 %27 %28 1006fd4e5da5Sopenharmony_ci // %25' 1007fd4e5da5Sopenharmony_ci auto instruction_descriptor_5 = 1008fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(82, spv::Op::OpCompositeConstruct, 0); 1009fd4e5da5Sopenharmony_ci auto extract_5 = 1010fd4e5da5Sopenharmony_ci TransformationCompositeExtract(instruction_descriptor_5, 204, 102, {0}); 1011fd4e5da5Sopenharmony_ci 1012fd4e5da5Sopenharmony_ci ASSERT_TRUE(extract_5.IsApplicable(context.get(), transformation_context)); 1013fd4e5da5Sopenharmony_ci extract_5.Apply(context.get(), &transformation_context); 1014fd4e5da5Sopenharmony_ci auto replacement_5 = TransformationReplaceIdWithSynonym( 1015fd4e5da5Sopenharmony_ci MakeIdUseDescriptor(27, instruction_descriptor_5, 1), 204); 1016fd4e5da5Sopenharmony_ci ASSERT_TRUE( 1017fd4e5da5Sopenharmony_ci replacement_5.IsApplicable(context.get(), transformation_context)); 1018fd4e5da5Sopenharmony_ci replacement_5.Apply(context.get(), &transformation_context); 1019fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 1020fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 1021fd4e5da5Sopenharmony_ci 1022fd4e5da5Sopenharmony_ci // Replace %15 with %102[1:2] in '%83 = OpCopyObject %10 %15' 1023fd4e5da5Sopenharmony_ci auto instruction_descriptor_6 = 1024fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(83, spv::Op::OpCopyObject, 0); 1025fd4e5da5Sopenharmony_ci auto shuffle_6 = TransformationVectorShuffle(instruction_descriptor_6, 205, 1026fd4e5da5Sopenharmony_ci 102, 102, {1, 2}); 1027fd4e5da5Sopenharmony_ci ASSERT_TRUE(shuffle_6.IsApplicable(context.get(), transformation_context)); 1028fd4e5da5Sopenharmony_ci shuffle_6.Apply(context.get(), &transformation_context); 1029fd4e5da5Sopenharmony_ci transformation_context.GetFactManager()->ComputeClosureOfFacts(100); 1030fd4e5da5Sopenharmony_ci 1031fd4e5da5Sopenharmony_ci auto replacement_6 = TransformationReplaceIdWithSynonym( 1032fd4e5da5Sopenharmony_ci MakeIdUseDescriptor(15, instruction_descriptor_6, 0), 205); 1033fd4e5da5Sopenharmony_ci ASSERT_TRUE( 1034fd4e5da5Sopenharmony_ci replacement_6.IsApplicable(context.get(), transformation_context)); 1035fd4e5da5Sopenharmony_ci replacement_6.Apply(context.get(), &transformation_context); 1036fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 1037fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 1038fd4e5da5Sopenharmony_ci 1039fd4e5da5Sopenharmony_ci // Replace %33 with %103[0] in '%86 = OpCopyObject %30 %33' 1040fd4e5da5Sopenharmony_ci auto instruction_descriptor_7 = 1041fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(86, spv::Op::OpCopyObject, 0); 1042fd4e5da5Sopenharmony_ci auto extract_7 = 1043fd4e5da5Sopenharmony_ci TransformationCompositeExtract(instruction_descriptor_7, 206, 103, {0}); 1044fd4e5da5Sopenharmony_ci ASSERT_TRUE(extract_7.IsApplicable(context.get(), transformation_context)); 1045fd4e5da5Sopenharmony_ci extract_7.Apply(context.get(), &transformation_context); 1046fd4e5da5Sopenharmony_ci auto replacement_7 = TransformationReplaceIdWithSynonym( 1047fd4e5da5Sopenharmony_ci MakeIdUseDescriptor(33, instruction_descriptor_7, 0), 206); 1048fd4e5da5Sopenharmony_ci ASSERT_TRUE( 1049fd4e5da5Sopenharmony_ci replacement_7.IsApplicable(context.get(), transformation_context)); 1050fd4e5da5Sopenharmony_ci replacement_7.Apply(context.get(), &transformation_context); 1051fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 1052fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 1053fd4e5da5Sopenharmony_ci 1054fd4e5da5Sopenharmony_ci // Replace %47 with %103[1:3] in '%84 = OpCopyObject %39 %47' 1055fd4e5da5Sopenharmony_ci auto instruction_descriptor_8 = 1056fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(84, spv::Op::OpCopyObject, 0); 1057fd4e5da5Sopenharmony_ci auto shuffle_8 = TransformationVectorShuffle(instruction_descriptor_8, 207, 1058fd4e5da5Sopenharmony_ci 103, 103, {1, 2, 3}); 1059fd4e5da5Sopenharmony_ci ASSERT_TRUE(shuffle_8.IsApplicable(context.get(), transformation_context)); 1060fd4e5da5Sopenharmony_ci shuffle_8.Apply(context.get(), &transformation_context); 1061fd4e5da5Sopenharmony_ci transformation_context.GetFactManager()->ComputeClosureOfFacts(100); 1062fd4e5da5Sopenharmony_ci 1063fd4e5da5Sopenharmony_ci auto replacement_8 = TransformationReplaceIdWithSynonym( 1064fd4e5da5Sopenharmony_ci MakeIdUseDescriptor(47, instruction_descriptor_8, 0), 207); 1065fd4e5da5Sopenharmony_ci ASSERT_TRUE( 1066fd4e5da5Sopenharmony_ci replacement_8.IsApplicable(context.get(), transformation_context)); 1067fd4e5da5Sopenharmony_ci replacement_8.Apply(context.get(), &transformation_context); 1068fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 1069fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 1070fd4e5da5Sopenharmony_ci 1071fd4e5da5Sopenharmony_ci // Replace %42 with %104[0] in '%85 = OpCopyObject %30 %42' 1072fd4e5da5Sopenharmony_ci auto instruction_descriptor_9 = 1073fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(85, spv::Op::OpCopyObject, 0); 1074fd4e5da5Sopenharmony_ci auto extract_9 = 1075fd4e5da5Sopenharmony_ci TransformationCompositeExtract(instruction_descriptor_9, 208, 104, {0}); 1076fd4e5da5Sopenharmony_ci ASSERT_TRUE(extract_9.IsApplicable(context.get(), transformation_context)); 1077fd4e5da5Sopenharmony_ci extract_9.Apply(context.get(), &transformation_context); 1078fd4e5da5Sopenharmony_ci auto replacement_9 = TransformationReplaceIdWithSynonym( 1079fd4e5da5Sopenharmony_ci MakeIdUseDescriptor(42, instruction_descriptor_9, 0), 208); 1080fd4e5da5Sopenharmony_ci ASSERT_TRUE( 1081fd4e5da5Sopenharmony_ci replacement_9.IsApplicable(context.get(), transformation_context)); 1082fd4e5da5Sopenharmony_ci replacement_9.Apply(context.get(), &transformation_context); 1083fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 1084fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 1085fd4e5da5Sopenharmony_ci 1086fd4e5da5Sopenharmony_ci // Replace %45 with %104[1] in '%63 = OpLogicalOr %30 %45 %46' 1087fd4e5da5Sopenharmony_ci auto instruction_descriptor_10 = 1088fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(63, spv::Op::OpLogicalOr, 0); 1089fd4e5da5Sopenharmony_ci auto extract_10 = 1090fd4e5da5Sopenharmony_ci TransformationCompositeExtract(instruction_descriptor_10, 209, 104, {1}); 1091fd4e5da5Sopenharmony_ci ASSERT_TRUE(extract_10.IsApplicable(context.get(), transformation_context)); 1092fd4e5da5Sopenharmony_ci extract_10.Apply(context.get(), &transformation_context); 1093fd4e5da5Sopenharmony_ci auto replacement_10 = TransformationReplaceIdWithSynonym( 1094fd4e5da5Sopenharmony_ci MakeIdUseDescriptor(45, instruction_descriptor_10, 0), 209); 1095fd4e5da5Sopenharmony_ci ASSERT_TRUE( 1096fd4e5da5Sopenharmony_ci replacement_10.IsApplicable(context.get(), transformation_context)); 1097fd4e5da5Sopenharmony_ci replacement_10.Apply(context.get(), &transformation_context); 1098fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 1099fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 1100fd4e5da5Sopenharmony_ci 1101fd4e5da5Sopenharmony_ci // Replace %38 with %105[0:1] in 'OpStore %36 %38' 1102fd4e5da5Sopenharmony_ci auto instruction_descriptor_11 = 1103fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(85, spv::Op::OpStore, 0); 1104fd4e5da5Sopenharmony_ci auto shuffle_11 = TransformationVectorShuffle(instruction_descriptor_11, 210, 1105fd4e5da5Sopenharmony_ci 105, 105, {0, 1}); 1106fd4e5da5Sopenharmony_ci ASSERT_TRUE(shuffle_11.IsApplicable(context.get(), transformation_context)); 1107fd4e5da5Sopenharmony_ci shuffle_11.Apply(context.get(), &transformation_context); 1108fd4e5da5Sopenharmony_ci transformation_context.GetFactManager()->ComputeClosureOfFacts(100); 1109fd4e5da5Sopenharmony_ci 1110fd4e5da5Sopenharmony_ci auto replacement_11 = TransformationReplaceIdWithSynonym( 1111fd4e5da5Sopenharmony_ci MakeIdUseDescriptor(38, instruction_descriptor_11, 1), 210); 1112fd4e5da5Sopenharmony_ci ASSERT_TRUE( 1113fd4e5da5Sopenharmony_ci replacement_11.IsApplicable(context.get(), transformation_context)); 1114fd4e5da5Sopenharmony_ci replacement_11.Apply(context.get(), &transformation_context); 1115fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 1116fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 1117fd4e5da5Sopenharmony_ci 1118fd4e5da5Sopenharmony_ci // Replace %46 with %105[2] in '%62 = OpLogicalAnd %30 %45 %46' 1119fd4e5da5Sopenharmony_ci auto instruction_descriptor_12 = 1120fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(62, spv::Op::OpLogicalAnd, 0); 1121fd4e5da5Sopenharmony_ci auto extract_12 = 1122fd4e5da5Sopenharmony_ci TransformationCompositeExtract(instruction_descriptor_12, 211, 105, {2}); 1123fd4e5da5Sopenharmony_ci ASSERT_TRUE(extract_12.IsApplicable(context.get(), transformation_context)); 1124fd4e5da5Sopenharmony_ci extract_12.Apply(context.get(), &transformation_context); 1125fd4e5da5Sopenharmony_ci auto replacement_12 = TransformationReplaceIdWithSynonym( 1126fd4e5da5Sopenharmony_ci MakeIdUseDescriptor(46, instruction_descriptor_12, 1), 211); 1127fd4e5da5Sopenharmony_ci ASSERT_TRUE( 1128fd4e5da5Sopenharmony_ci replacement_12.IsApplicable(context.get(), transformation_context)); 1129fd4e5da5Sopenharmony_ci replacement_12.Apply(context.get(), &transformation_context); 1130fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 1131fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 1132fd4e5da5Sopenharmony_ci 1133fd4e5da5Sopenharmony_ci const std::string after_transformation = R"( 1134fd4e5da5Sopenharmony_ci OpCapability Shader 1135fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 1136fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1137fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 1138fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 1139fd4e5da5Sopenharmony_ci OpSource ESSL 310 1140fd4e5da5Sopenharmony_ci OpName %4 "main" 1141fd4e5da5Sopenharmony_ci OpName %8 "f" 1142fd4e5da5Sopenharmony_ci OpName %12 "v2" 1143fd4e5da5Sopenharmony_ci OpName %18 "v3" 1144fd4e5da5Sopenharmony_ci OpName %23 "v4" 1145fd4e5da5Sopenharmony_ci OpName %32 "b" 1146fd4e5da5Sopenharmony_ci OpName %36 "bv2" 1147fd4e5da5Sopenharmony_ci OpName %41 "bv3" 1148fd4e5da5Sopenharmony_ci OpName %50 "bv4" 1149fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 1150fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 1151fd4e5da5Sopenharmony_ci %6 = OpTypeFloat 32 1152fd4e5da5Sopenharmony_ci %7 = OpTypePointer Function %6 1153fd4e5da5Sopenharmony_ci %9 = OpConstant %6 42 1154fd4e5da5Sopenharmony_ci %10 = OpTypeVector %6 2 1155fd4e5da5Sopenharmony_ci %11 = OpTypePointer Function %10 1156fd4e5da5Sopenharmony_ci %16 = OpTypeVector %6 3 1157fd4e5da5Sopenharmony_ci %17 = OpTypePointer Function %16 1158fd4e5da5Sopenharmony_ci %21 = OpTypeVector %6 4 1159fd4e5da5Sopenharmony_ci %22 = OpTypePointer Function %21 1160fd4e5da5Sopenharmony_ci %30 = OpTypeBool 1161fd4e5da5Sopenharmony_ci %31 = OpTypePointer Function %30 1162fd4e5da5Sopenharmony_ci %33 = OpConstantFalse %30 1163fd4e5da5Sopenharmony_ci %34 = OpTypeVector %30 2 1164fd4e5da5Sopenharmony_ci %35 = OpTypePointer Function %34 1165fd4e5da5Sopenharmony_ci %37 = OpConstantTrue %30 1166fd4e5da5Sopenharmony_ci %38 = OpConstantComposite %34 %37 %37 1167fd4e5da5Sopenharmony_ci %39 = OpTypeVector %30 3 1168fd4e5da5Sopenharmony_ci %40 = OpTypePointer Function %39 1169fd4e5da5Sopenharmony_ci %48 = OpTypeVector %30 4 1170fd4e5da5Sopenharmony_ci %49 = OpTypePointer Function %48 1171fd4e5da5Sopenharmony_ci %51 = OpTypeInt 32 0 1172fd4e5da5Sopenharmony_ci %52 = OpConstant %51 2 1173fd4e5da5Sopenharmony_ci %55 = OpConstant %6 0 1174fd4e5da5Sopenharmony_ci %57 = OpConstant %51 1 1175fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 1176fd4e5da5Sopenharmony_ci %5 = OpLabel 1177fd4e5da5Sopenharmony_ci %8 = OpVariable %7 Function 1178fd4e5da5Sopenharmony_ci %12 = OpVariable %11 Function 1179fd4e5da5Sopenharmony_ci %18 = OpVariable %17 Function 1180fd4e5da5Sopenharmony_ci %23 = OpVariable %22 Function 1181fd4e5da5Sopenharmony_ci %32 = OpVariable %31 Function 1182fd4e5da5Sopenharmony_ci %36 = OpVariable %35 Function 1183fd4e5da5Sopenharmony_ci %41 = OpVariable %40 Function 1184fd4e5da5Sopenharmony_ci %50 = OpVariable %49 Function 1185fd4e5da5Sopenharmony_ci OpStore %8 %9 1186fd4e5da5Sopenharmony_ci %13 = OpLoad %6 %8 1187fd4e5da5Sopenharmony_ci %14 = OpLoad %6 %8 1188fd4e5da5Sopenharmony_ci %15 = OpCompositeConstruct %10 %13 %14 1189fd4e5da5Sopenharmony_ci OpStore %12 %15 1190fd4e5da5Sopenharmony_ci %19 = OpLoad %10 %12 1191fd4e5da5Sopenharmony_ci %20 = OpVectorShuffle %16 %19 %19 0 0 1 1192fd4e5da5Sopenharmony_ci OpStore %18 %20 1193fd4e5da5Sopenharmony_ci %24 = OpLoad %16 %18 1194fd4e5da5Sopenharmony_ci %25 = OpLoad %6 %8 1195fd4e5da5Sopenharmony_ci %26 = OpCompositeExtract %6 %24 0 1196fd4e5da5Sopenharmony_ci %27 = OpCompositeExtract %6 %24 1 1197fd4e5da5Sopenharmony_ci %28 = OpCompositeExtract %6 %24 2 1198fd4e5da5Sopenharmony_ci %29 = OpCompositeConstruct %21 %26 %27 %28 %25 1199fd4e5da5Sopenharmony_ci OpStore %23 %29 1200fd4e5da5Sopenharmony_ci OpStore %32 %33 1201fd4e5da5Sopenharmony_ci OpStore %36 %38 1202fd4e5da5Sopenharmony_ci %42 = OpLoad %30 %32 1203fd4e5da5Sopenharmony_ci %43 = OpLoad %34 %36 1204fd4e5da5Sopenharmony_ci %44 = OpVectorShuffle %34 %43 %43 0 0 1205fd4e5da5Sopenharmony_ci %45 = OpCompositeExtract %30 %44 0 1206fd4e5da5Sopenharmony_ci %46 = OpCompositeExtract %30 %44 1 1207fd4e5da5Sopenharmony_ci %47 = OpCompositeConstruct %39 %42 %45 %46 1208fd4e5da5Sopenharmony_ci OpStore %41 %47 1209fd4e5da5Sopenharmony_ci %53 = OpAccessChain %7 %23 %52 1210fd4e5da5Sopenharmony_ci %54 = OpLoad %6 %53 1211fd4e5da5Sopenharmony_ci 1212fd4e5da5Sopenharmony_ci %100 = OpCompositeConstruct %21 %20 %54 1213fd4e5da5Sopenharmony_ci %101 = OpCompositeConstruct %21 %15 %19 1214fd4e5da5Sopenharmony_ci %102 = OpCompositeConstruct %16 %27 %15 1215fd4e5da5Sopenharmony_ci %103 = OpCompositeConstruct %48 %33 %47 1216fd4e5da5Sopenharmony_ci %104 = OpCompositeConstruct %34 %42 %45 1217fd4e5da5Sopenharmony_ci %105 = OpCompositeConstruct %39 %38 %46 1218fd4e5da5Sopenharmony_ci 1219fd4e5da5Sopenharmony_ci %206 = OpCompositeExtract %30 %103 0 1220fd4e5da5Sopenharmony_ci %86 = OpCopyObject %30 %206 1221fd4e5da5Sopenharmony_ci %201 = OpCompositeExtract %6 %100 3 1222fd4e5da5Sopenharmony_ci %56 = OpFOrdNotEqual %30 %201 %55 1223fd4e5da5Sopenharmony_ci %200 = OpVectorShuffle %16 %100 %100 0 1 2 1224fd4e5da5Sopenharmony_ci %80 = OpCopyObject %16 %200 1225fd4e5da5Sopenharmony_ci %58 = OpAccessChain %7 %18 %57 1226fd4e5da5Sopenharmony_ci %59 = OpLoad %6 %58 1227fd4e5da5Sopenharmony_ci %60 = OpFOrdNotEqual %30 %59 %55 1228fd4e5da5Sopenharmony_ci %61 = OpLoad %34 %36 1229fd4e5da5Sopenharmony_ci %211 = OpCompositeExtract %30 %105 2 1230fd4e5da5Sopenharmony_ci %62 = OpLogicalAnd %30 %45 %211 1231fd4e5da5Sopenharmony_ci %209 = OpCompositeExtract %30 %104 1 1232fd4e5da5Sopenharmony_ci %63 = OpLogicalOr %30 %209 %46 1233fd4e5da5Sopenharmony_ci %64 = OpCompositeConstruct %48 %56 %60 %62 %63 1234fd4e5da5Sopenharmony_ci %202 = OpVectorShuffle %10 %101 %101 0 1 1235fd4e5da5Sopenharmony_ci OpStore %12 %202 1236fd4e5da5Sopenharmony_ci %203 = OpVectorShuffle %10 %101 %101 2 3 1237fd4e5da5Sopenharmony_ci %81 = OpVectorShuffle %16 %203 %19 0 0 1 1238fd4e5da5Sopenharmony_ci %204 = OpCompositeExtract %6 %102 0 1239fd4e5da5Sopenharmony_ci %82 = OpCompositeConstruct %21 %26 %204 %28 %25 1240fd4e5da5Sopenharmony_ci %205 = OpVectorShuffle %10 %102 %102 1 2 1241fd4e5da5Sopenharmony_ci %83 = OpCopyObject %10 %205 1242fd4e5da5Sopenharmony_ci %207 = OpVectorShuffle %39 %103 %103 1 2 3 1243fd4e5da5Sopenharmony_ci %84 = OpCopyObject %39 %207 1244fd4e5da5Sopenharmony_ci OpStore %50 %64 1245fd4e5da5Sopenharmony_ci %208 = OpCompositeExtract %30 %104 0 1246fd4e5da5Sopenharmony_ci %85 = OpCopyObject %30 %208 1247fd4e5da5Sopenharmony_ci %210 = OpVectorShuffle %34 %105 %105 0 1 1248fd4e5da5Sopenharmony_ci OpStore %36 %210 1249fd4e5da5Sopenharmony_ci OpReturn 1250fd4e5da5Sopenharmony_ci OpFunctionEnd 1251fd4e5da5Sopenharmony_ci )"; 1252fd4e5da5Sopenharmony_ci 1253fd4e5da5Sopenharmony_ci ASSERT_TRUE(IsEqual(env, after_transformation, context.get())); 1254fd4e5da5Sopenharmony_ci} 1255fd4e5da5Sopenharmony_ci 1256fd4e5da5Sopenharmony_ci} // namespace 1257fd4e5da5Sopenharmony_ci} // namespace fuzz 1258fd4e5da5Sopenharmony_ci} // namespace spvtools 1259