1fd4e5da5Sopenharmony_ci// Copyright (c) 2020 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/transformation_equation_instruction.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(TransformationEquationInstructionTest, SignedNegate) { 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 %12 "main" 32fd4e5da5Sopenharmony_ci OpExecutionMode %12 OriginUpperLeft 33fd4e5da5Sopenharmony_ci OpSource ESSL 310 34fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 35fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 36fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 37fd4e5da5Sopenharmony_ci %7 = OpConstant %6 24 38fd4e5da5Sopenharmony_ci %40 = OpTypeBool 39fd4e5da5Sopenharmony_ci %41 = OpConstantTrue %40 40fd4e5da5Sopenharmony_ci %20 = OpUndef %6 41fd4e5da5Sopenharmony_ci %12 = OpFunction %2 None %3 42fd4e5da5Sopenharmony_ci %13 = OpLabel 43fd4e5da5Sopenharmony_ci %30 = OpCopyObject %6 %7 44fd4e5da5Sopenharmony_ci OpReturn 45fd4e5da5Sopenharmony_ci OpFunctionEnd 46fd4e5da5Sopenharmony_ci )"; 47fd4e5da5Sopenharmony_ci 48fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 49fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 50fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); 51fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 52fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 53fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 54fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 55fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(context.get()), validator_options); 56fd4e5da5Sopenharmony_ci protobufs::InstructionDescriptor return_instruction = 57fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(13, spv::Op::OpReturn, 0); 58fd4e5da5Sopenharmony_ci 59fd4e5da5Sopenharmony_ci // Bad: id already in use. 60fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationEquationInstruction(7, spv::Op::OpSNegate, {7}, 61fd4e5da5Sopenharmony_ci return_instruction) 62fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 63fd4e5da5Sopenharmony_ci 64fd4e5da5Sopenharmony_ci // Bad: identified instruction does not exist. 65fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationEquationInstruction( 66fd4e5da5Sopenharmony_ci 14, spv::Op::OpSNegate, {7}, 67fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(13, spv::Op::OpLoad, 0)) 68fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 69fd4e5da5Sopenharmony_ci 70fd4e5da5Sopenharmony_ci // Bad: id 100 does not exist 71fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationEquationInstruction(14, spv::Op::OpSNegate, {100}, 72fd4e5da5Sopenharmony_ci return_instruction) 73fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 74fd4e5da5Sopenharmony_ci 75fd4e5da5Sopenharmony_ci // Bad: id 20 is an OpUndef 76fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationEquationInstruction(14, spv::Op::OpSNegate, {20}, 77fd4e5da5Sopenharmony_ci return_instruction) 78fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 79fd4e5da5Sopenharmony_ci 80fd4e5da5Sopenharmony_ci // Bad: id 30 is not available right before its definition 81fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationEquationInstruction( 82fd4e5da5Sopenharmony_ci 14, spv::Op::OpSNegate, {30}, 83fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(30, spv::Op::OpCopyObject, 0)) 84fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 85fd4e5da5Sopenharmony_ci 86fd4e5da5Sopenharmony_ci // Bad: too many arguments to OpSNegate. 87fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationEquationInstruction(14, spv::Op::OpSNegate, {7, 7}, 88fd4e5da5Sopenharmony_ci return_instruction) 89fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 90fd4e5da5Sopenharmony_ci 91fd4e5da5Sopenharmony_ci // Bad: 40 is a type id. 92fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationEquationInstruction(14, spv::Op::OpSNegate, {40}, 93fd4e5da5Sopenharmony_ci return_instruction) 94fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 95fd4e5da5Sopenharmony_ci 96fd4e5da5Sopenharmony_ci // Bad: wrong type of argument to OpSNegate. 97fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationEquationInstruction(14, spv::Op::OpSNegate, {41}, 98fd4e5da5Sopenharmony_ci return_instruction) 99fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 100fd4e5da5Sopenharmony_ci 101fd4e5da5Sopenharmony_ci auto transformation1 = TransformationEquationInstruction( 102fd4e5da5Sopenharmony_ci 14, spv::Op::OpSNegate, {7}, return_instruction); 103fd4e5da5Sopenharmony_ci ASSERT_TRUE( 104fd4e5da5Sopenharmony_ci transformation1.IsApplicable(context.get(), transformation_context)); 105fd4e5da5Sopenharmony_ci ASSERT_EQ(nullptr, context->get_def_use_mgr()->GetDef(14)); 106fd4e5da5Sopenharmony_ci ASSERT_EQ(nullptr, context->get_instr_block(14)); 107fd4e5da5Sopenharmony_ci ApplyAndCheckFreshIds(transformation1, context.get(), 108fd4e5da5Sopenharmony_ci &transformation_context); 109fd4e5da5Sopenharmony_ci ASSERT_EQ(spv::Op::OpSNegate, 110fd4e5da5Sopenharmony_ci context->get_def_use_mgr()->GetDef(14)->opcode()); 111fd4e5da5Sopenharmony_ci ASSERT_EQ(13, context->get_instr_block(14)->id()); 112fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 113fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 114fd4e5da5Sopenharmony_ci 115fd4e5da5Sopenharmony_ci auto transformation2 = TransformationEquationInstruction( 116fd4e5da5Sopenharmony_ci 15, spv::Op::OpSNegate, {14}, return_instruction); 117fd4e5da5Sopenharmony_ci ASSERT_TRUE( 118fd4e5da5Sopenharmony_ci transformation2.IsApplicable(context.get(), transformation_context)); 119fd4e5da5Sopenharmony_ci ApplyAndCheckFreshIds(transformation2, context.get(), 120fd4e5da5Sopenharmony_ci &transformation_context); 121fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 122fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 123fd4e5da5Sopenharmony_ci 124fd4e5da5Sopenharmony_ci ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( 125fd4e5da5Sopenharmony_ci MakeDataDescriptor(15, {}), MakeDataDescriptor(7, {}))); 126fd4e5da5Sopenharmony_ci 127fd4e5da5Sopenharmony_ci std::string after_transformation = R"( 128fd4e5da5Sopenharmony_ci OpCapability Shader 129fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 130fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 131fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %12 "main" 132fd4e5da5Sopenharmony_ci OpExecutionMode %12 OriginUpperLeft 133fd4e5da5Sopenharmony_ci OpSource ESSL 310 134fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 135fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 136fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 137fd4e5da5Sopenharmony_ci %7 = OpConstant %6 24 138fd4e5da5Sopenharmony_ci %40 = OpTypeBool 139fd4e5da5Sopenharmony_ci %41 = OpConstantTrue %40 140fd4e5da5Sopenharmony_ci %20 = OpUndef %6 141fd4e5da5Sopenharmony_ci %12 = OpFunction %2 None %3 142fd4e5da5Sopenharmony_ci %13 = OpLabel 143fd4e5da5Sopenharmony_ci %30 = OpCopyObject %6 %7 144fd4e5da5Sopenharmony_ci %14 = OpSNegate %6 %7 145fd4e5da5Sopenharmony_ci %15 = OpSNegate %6 %14 146fd4e5da5Sopenharmony_ci OpReturn 147fd4e5da5Sopenharmony_ci OpFunctionEnd 148fd4e5da5Sopenharmony_ci )"; 149fd4e5da5Sopenharmony_ci 150fd4e5da5Sopenharmony_ci ASSERT_TRUE(IsEqual(env, after_transformation, context.get())); 151fd4e5da5Sopenharmony_ci} 152fd4e5da5Sopenharmony_ci 153fd4e5da5Sopenharmony_ciTEST(TransformationEquationInstructionTest, LogicalNot) { 154fd4e5da5Sopenharmony_ci std::string shader = R"( 155fd4e5da5Sopenharmony_ci OpCapability Shader 156fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 157fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 158fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %12 "main" 159fd4e5da5Sopenharmony_ci OpExecutionMode %12 OriginUpperLeft 160fd4e5da5Sopenharmony_ci OpSource ESSL 310 161fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 162fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 163fd4e5da5Sopenharmony_ci %6 = OpTypeBool 164fd4e5da5Sopenharmony_ci %7 = OpConstantTrue %6 165fd4e5da5Sopenharmony_ci %20 = OpTypeInt 32 0 166fd4e5da5Sopenharmony_ci %21 = OpConstant %20 5 167fd4e5da5Sopenharmony_ci %12 = OpFunction %2 None %3 168fd4e5da5Sopenharmony_ci %13 = OpLabel 169fd4e5da5Sopenharmony_ci OpReturn 170fd4e5da5Sopenharmony_ci OpFunctionEnd 171fd4e5da5Sopenharmony_ci )"; 172fd4e5da5Sopenharmony_ci 173fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 174fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 175fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); 176fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 177fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 178fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 179fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 180fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(context.get()), validator_options); 181fd4e5da5Sopenharmony_ci protobufs::InstructionDescriptor return_instruction = 182fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(13, spv::Op::OpReturn, 0); 183fd4e5da5Sopenharmony_ci 184fd4e5da5Sopenharmony_ci // Bad: too few arguments to OpLogicalNot. 185fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationEquationInstruction(14, spv::Op::OpLogicalNot, {}, 186fd4e5da5Sopenharmony_ci return_instruction) 187fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 188fd4e5da5Sopenharmony_ci 189fd4e5da5Sopenharmony_ci // Bad: 6 is a type id. 190fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationEquationInstruction(14, spv::Op::OpLogicalNot, {6}, 191fd4e5da5Sopenharmony_ci return_instruction) 192fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 193fd4e5da5Sopenharmony_ci 194fd4e5da5Sopenharmony_ci // Bad: wrong type of argument to OpLogicalNot. 195fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationEquationInstruction(14, spv::Op::OpLogicalNot, 196fd4e5da5Sopenharmony_ci {21}, return_instruction) 197fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 198fd4e5da5Sopenharmony_ci 199fd4e5da5Sopenharmony_ci auto transformation1 = TransformationEquationInstruction( 200fd4e5da5Sopenharmony_ci 14, spv::Op::OpLogicalNot, {7}, return_instruction); 201fd4e5da5Sopenharmony_ci ASSERT_TRUE( 202fd4e5da5Sopenharmony_ci transformation1.IsApplicable(context.get(), transformation_context)); 203fd4e5da5Sopenharmony_ci ApplyAndCheckFreshIds(transformation1, context.get(), 204fd4e5da5Sopenharmony_ci &transformation_context); 205fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 206fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 207fd4e5da5Sopenharmony_ci 208fd4e5da5Sopenharmony_ci auto transformation2 = TransformationEquationInstruction( 209fd4e5da5Sopenharmony_ci 15, spv::Op::OpLogicalNot, {14}, return_instruction); 210fd4e5da5Sopenharmony_ci ASSERT_TRUE( 211fd4e5da5Sopenharmony_ci transformation2.IsApplicable(context.get(), transformation_context)); 212fd4e5da5Sopenharmony_ci ApplyAndCheckFreshIds(transformation2, context.get(), 213fd4e5da5Sopenharmony_ci &transformation_context); 214fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 215fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 216fd4e5da5Sopenharmony_ci 217fd4e5da5Sopenharmony_ci ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( 218fd4e5da5Sopenharmony_ci MakeDataDescriptor(15, {}), MakeDataDescriptor(7, {}))); 219fd4e5da5Sopenharmony_ci 220fd4e5da5Sopenharmony_ci std::string after_transformation = R"( 221fd4e5da5Sopenharmony_ci OpCapability Shader 222fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 223fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 224fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %12 "main" 225fd4e5da5Sopenharmony_ci OpExecutionMode %12 OriginUpperLeft 226fd4e5da5Sopenharmony_ci OpSource ESSL 310 227fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 228fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 229fd4e5da5Sopenharmony_ci %6 = OpTypeBool 230fd4e5da5Sopenharmony_ci %7 = OpConstantTrue %6 231fd4e5da5Sopenharmony_ci %20 = OpTypeInt 32 0 232fd4e5da5Sopenharmony_ci %21 = OpConstant %20 5 233fd4e5da5Sopenharmony_ci %12 = OpFunction %2 None %3 234fd4e5da5Sopenharmony_ci %13 = OpLabel 235fd4e5da5Sopenharmony_ci %14 = OpLogicalNot %6 %7 236fd4e5da5Sopenharmony_ci %15 = OpLogicalNot %6 %14 237fd4e5da5Sopenharmony_ci OpReturn 238fd4e5da5Sopenharmony_ci OpFunctionEnd 239fd4e5da5Sopenharmony_ci )"; 240fd4e5da5Sopenharmony_ci 241fd4e5da5Sopenharmony_ci ASSERT_TRUE(IsEqual(env, after_transformation, context.get())); 242fd4e5da5Sopenharmony_ci} 243fd4e5da5Sopenharmony_ci 244fd4e5da5Sopenharmony_ciTEST(TransformationEquationInstructionTest, AddSubNegate1) { 245fd4e5da5Sopenharmony_ci std::string shader = R"( 246fd4e5da5Sopenharmony_ci OpCapability Shader 247fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 248fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 249fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %12 "main" 250fd4e5da5Sopenharmony_ci OpExecutionMode %12 OriginUpperLeft 251fd4e5da5Sopenharmony_ci OpSource ESSL 310 252fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 253fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 254fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 255fd4e5da5Sopenharmony_ci %30 = OpTypeVector %6 3 256fd4e5da5Sopenharmony_ci %15 = OpConstant %6 24 257fd4e5da5Sopenharmony_ci %16 = OpConstant %6 37 258fd4e5da5Sopenharmony_ci %31 = OpConstantComposite %30 %15 %16 %15 259fd4e5da5Sopenharmony_ci %33 = OpTypeBool 260fd4e5da5Sopenharmony_ci %32 = OpConstantTrue %33 261fd4e5da5Sopenharmony_ci %12 = OpFunction %2 None %3 262fd4e5da5Sopenharmony_ci %13 = OpLabel 263fd4e5da5Sopenharmony_ci OpReturn 264fd4e5da5Sopenharmony_ci OpFunctionEnd 265fd4e5da5Sopenharmony_ci )"; 266fd4e5da5Sopenharmony_ci 267fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 268fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 269fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); 270fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 271fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 272fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 273fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 274fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(context.get()), validator_options); 275fd4e5da5Sopenharmony_ci protobufs::InstructionDescriptor return_instruction = 276fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(13, spv::Op::OpReturn, 0); 277fd4e5da5Sopenharmony_ci 278fd4e5da5Sopenharmony_ci // Bad: too many arguments to OpIAdd. 279fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationEquationInstruction( 280fd4e5da5Sopenharmony_ci 14, spv::Op::OpIAdd, {15, 16, 16}, return_instruction) 281fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 282fd4e5da5Sopenharmony_ci // Bad: boolean argument to OpIAdd. 283fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationEquationInstruction(14, spv::Op::OpIAdd, {15, 32}, 284fd4e5da5Sopenharmony_ci return_instruction) 285fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 286fd4e5da5Sopenharmony_ci // Bad: type as argument to OpIAdd. 287fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationEquationInstruction(14, spv::Op::OpIAdd, {33, 16}, 288fd4e5da5Sopenharmony_ci return_instruction) 289fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 290fd4e5da5Sopenharmony_ci // Bad: arguments of mismatched widths 291fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationEquationInstruction(14, spv::Op::OpIAdd, {15, 31}, 292fd4e5da5Sopenharmony_ci return_instruction) 293fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 294fd4e5da5Sopenharmony_ci // Bad: arguments of mismatched widths 295fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationEquationInstruction(14, spv::Op::OpIAdd, {31, 15}, 296fd4e5da5Sopenharmony_ci return_instruction) 297fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 298fd4e5da5Sopenharmony_ci 299fd4e5da5Sopenharmony_ci auto transformation1 = TransformationEquationInstruction( 300fd4e5da5Sopenharmony_ci 14, spv::Op::OpIAdd, {15, 16}, return_instruction); 301fd4e5da5Sopenharmony_ci ASSERT_TRUE( 302fd4e5da5Sopenharmony_ci transformation1.IsApplicable(context.get(), transformation_context)); 303fd4e5da5Sopenharmony_ci ApplyAndCheckFreshIds(transformation1, context.get(), 304fd4e5da5Sopenharmony_ci &transformation_context); 305fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 306fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 307fd4e5da5Sopenharmony_ci 308fd4e5da5Sopenharmony_ci auto transformation2 = TransformationEquationInstruction( 309fd4e5da5Sopenharmony_ci 19, spv::Op::OpISub, {14, 16}, return_instruction); 310fd4e5da5Sopenharmony_ci ASSERT_TRUE( 311fd4e5da5Sopenharmony_ci transformation2.IsApplicable(context.get(), transformation_context)); 312fd4e5da5Sopenharmony_ci ApplyAndCheckFreshIds(transformation2, context.get(), 313fd4e5da5Sopenharmony_ci &transformation_context); 314fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 315fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 316fd4e5da5Sopenharmony_ci ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( 317fd4e5da5Sopenharmony_ci MakeDataDescriptor(15, {}), MakeDataDescriptor(19, {}))); 318fd4e5da5Sopenharmony_ci 319fd4e5da5Sopenharmony_ci auto transformation3 = TransformationEquationInstruction( 320fd4e5da5Sopenharmony_ci 20, spv::Op::OpISub, {14, 15}, return_instruction); 321fd4e5da5Sopenharmony_ci ASSERT_TRUE( 322fd4e5da5Sopenharmony_ci transformation3.IsApplicable(context.get(), transformation_context)); 323fd4e5da5Sopenharmony_ci ApplyAndCheckFreshIds(transformation3, context.get(), 324fd4e5da5Sopenharmony_ci &transformation_context); 325fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 326fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 327fd4e5da5Sopenharmony_ci ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( 328fd4e5da5Sopenharmony_ci MakeDataDescriptor(20, {}), MakeDataDescriptor(16, {}))); 329fd4e5da5Sopenharmony_ci 330fd4e5da5Sopenharmony_ci auto transformation4 = TransformationEquationInstruction( 331fd4e5da5Sopenharmony_ci 22, spv::Op::OpISub, {16, 14}, return_instruction); 332fd4e5da5Sopenharmony_ci ASSERT_TRUE( 333fd4e5da5Sopenharmony_ci transformation4.IsApplicable(context.get(), transformation_context)); 334fd4e5da5Sopenharmony_ci ApplyAndCheckFreshIds(transformation4, context.get(), 335fd4e5da5Sopenharmony_ci &transformation_context); 336fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 337fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 338fd4e5da5Sopenharmony_ci 339fd4e5da5Sopenharmony_ci auto transformation5 = TransformationEquationInstruction( 340fd4e5da5Sopenharmony_ci 24, spv::Op::OpSNegate, {22}, return_instruction); 341fd4e5da5Sopenharmony_ci ASSERT_TRUE( 342fd4e5da5Sopenharmony_ci transformation5.IsApplicable(context.get(), transformation_context)); 343fd4e5da5Sopenharmony_ci ApplyAndCheckFreshIds(transformation5, context.get(), 344fd4e5da5Sopenharmony_ci &transformation_context); 345fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 346fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 347fd4e5da5Sopenharmony_ci ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( 348fd4e5da5Sopenharmony_ci MakeDataDescriptor(24, {}), MakeDataDescriptor(15, {}))); 349fd4e5da5Sopenharmony_ci 350fd4e5da5Sopenharmony_ci std::string after_transformation = R"( 351fd4e5da5Sopenharmony_ci OpCapability Shader 352fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 353fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 354fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %12 "main" 355fd4e5da5Sopenharmony_ci OpExecutionMode %12 OriginUpperLeft 356fd4e5da5Sopenharmony_ci OpSource ESSL 310 357fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 358fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 359fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 360fd4e5da5Sopenharmony_ci %30 = OpTypeVector %6 3 361fd4e5da5Sopenharmony_ci %15 = OpConstant %6 24 362fd4e5da5Sopenharmony_ci %16 = OpConstant %6 37 363fd4e5da5Sopenharmony_ci %31 = OpConstantComposite %30 %15 %16 %15 364fd4e5da5Sopenharmony_ci %33 = OpTypeBool 365fd4e5da5Sopenharmony_ci %32 = OpConstantTrue %33 366fd4e5da5Sopenharmony_ci %12 = OpFunction %2 None %3 367fd4e5da5Sopenharmony_ci %13 = OpLabel 368fd4e5da5Sopenharmony_ci %14 = OpIAdd %6 %15 %16 369fd4e5da5Sopenharmony_ci %19 = OpISub %6 %14 %16 ; ==> synonymous(%19, %15) 370fd4e5da5Sopenharmony_ci %20 = OpISub %6 %14 %15 ; ==> synonymous(%20, %16) 371fd4e5da5Sopenharmony_ci %22 = OpISub %6 %16 %14 372fd4e5da5Sopenharmony_ci %24 = OpSNegate %6 %22 ; ==> synonymous(%24, %15) 373fd4e5da5Sopenharmony_ci OpReturn 374fd4e5da5Sopenharmony_ci OpFunctionEnd 375fd4e5da5Sopenharmony_ci )"; 376fd4e5da5Sopenharmony_ci 377fd4e5da5Sopenharmony_ci ASSERT_TRUE(IsEqual(env, after_transformation, context.get())); 378fd4e5da5Sopenharmony_ci} 379fd4e5da5Sopenharmony_ci 380fd4e5da5Sopenharmony_ciTEST(TransformationEquationInstructionTest, AddSubNegate2) { 381fd4e5da5Sopenharmony_ci std::string shader = R"( 382fd4e5da5Sopenharmony_ci OpCapability Shader 383fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 384fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 385fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %12 "main" 386fd4e5da5Sopenharmony_ci OpExecutionMode %12 OriginUpperLeft 387fd4e5da5Sopenharmony_ci OpSource ESSL 310 388fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 389fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 390fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 391fd4e5da5Sopenharmony_ci %15 = OpConstant %6 24 392fd4e5da5Sopenharmony_ci %16 = OpConstant %6 37 393fd4e5da5Sopenharmony_ci %12 = OpFunction %2 None %3 394fd4e5da5Sopenharmony_ci %13 = OpLabel 395fd4e5da5Sopenharmony_ci OpReturn 396fd4e5da5Sopenharmony_ci OpFunctionEnd 397fd4e5da5Sopenharmony_ci )"; 398fd4e5da5Sopenharmony_ci 399fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 400fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 401fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); 402fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 403fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 404fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 405fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 406fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(context.get()), validator_options); 407fd4e5da5Sopenharmony_ci protobufs::InstructionDescriptor return_instruction = 408fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(13, spv::Op::OpReturn, 0); 409fd4e5da5Sopenharmony_ci 410fd4e5da5Sopenharmony_ci auto transformation1 = TransformationEquationInstruction( 411fd4e5da5Sopenharmony_ci 14, spv::Op::OpISub, {15, 16}, return_instruction); 412fd4e5da5Sopenharmony_ci ASSERT_TRUE( 413fd4e5da5Sopenharmony_ci transformation1.IsApplicable(context.get(), transformation_context)); 414fd4e5da5Sopenharmony_ci ApplyAndCheckFreshIds(transformation1, context.get(), 415fd4e5da5Sopenharmony_ci &transformation_context); 416fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 417fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 418fd4e5da5Sopenharmony_ci 419fd4e5da5Sopenharmony_ci auto transformation2 = TransformationEquationInstruction( 420fd4e5da5Sopenharmony_ci 17, spv::Op::OpIAdd, {14, 16}, return_instruction); 421fd4e5da5Sopenharmony_ci ASSERT_TRUE( 422fd4e5da5Sopenharmony_ci transformation2.IsApplicable(context.get(), transformation_context)); 423fd4e5da5Sopenharmony_ci ApplyAndCheckFreshIds(transformation2, context.get(), 424fd4e5da5Sopenharmony_ci &transformation_context); 425fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 426fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 427fd4e5da5Sopenharmony_ci ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( 428fd4e5da5Sopenharmony_ci MakeDataDescriptor(17, {}), MakeDataDescriptor(15, {}))); 429fd4e5da5Sopenharmony_ci 430fd4e5da5Sopenharmony_ci auto transformation3 = TransformationEquationInstruction( 431fd4e5da5Sopenharmony_ci 18, spv::Op::OpIAdd, {16, 14}, return_instruction); 432fd4e5da5Sopenharmony_ci ASSERT_TRUE( 433fd4e5da5Sopenharmony_ci transformation3.IsApplicable(context.get(), transformation_context)); 434fd4e5da5Sopenharmony_ci ApplyAndCheckFreshIds(transformation3, context.get(), 435fd4e5da5Sopenharmony_ci &transformation_context); 436fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 437fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 438fd4e5da5Sopenharmony_ci ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( 439fd4e5da5Sopenharmony_ci MakeDataDescriptor(17, {}), MakeDataDescriptor(18, {}))); 440fd4e5da5Sopenharmony_ci ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( 441fd4e5da5Sopenharmony_ci MakeDataDescriptor(18, {}), MakeDataDescriptor(15, {}))); 442fd4e5da5Sopenharmony_ci 443fd4e5da5Sopenharmony_ci auto transformation4 = TransformationEquationInstruction( 444fd4e5da5Sopenharmony_ci 19, spv::Op::OpISub, {14, 15}, return_instruction); 445fd4e5da5Sopenharmony_ci ASSERT_TRUE( 446fd4e5da5Sopenharmony_ci transformation4.IsApplicable(context.get(), transformation_context)); 447fd4e5da5Sopenharmony_ci ApplyAndCheckFreshIds(transformation4, context.get(), 448fd4e5da5Sopenharmony_ci &transformation_context); 449fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 450fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 451fd4e5da5Sopenharmony_ci 452fd4e5da5Sopenharmony_ci auto transformation5 = TransformationEquationInstruction( 453fd4e5da5Sopenharmony_ci 20, spv::Op::OpSNegate, {19}, return_instruction); 454fd4e5da5Sopenharmony_ci ASSERT_TRUE( 455fd4e5da5Sopenharmony_ci transformation5.IsApplicable(context.get(), transformation_context)); 456fd4e5da5Sopenharmony_ci ApplyAndCheckFreshIds(transformation5, context.get(), 457fd4e5da5Sopenharmony_ci &transformation_context); 458fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 459fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 460fd4e5da5Sopenharmony_ci ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( 461fd4e5da5Sopenharmony_ci MakeDataDescriptor(20, {}), MakeDataDescriptor(16, {}))); 462fd4e5da5Sopenharmony_ci 463fd4e5da5Sopenharmony_ci auto transformation6 = TransformationEquationInstruction( 464fd4e5da5Sopenharmony_ci 21, spv::Op::OpISub, {14, 19}, return_instruction); 465fd4e5da5Sopenharmony_ci ASSERT_TRUE( 466fd4e5da5Sopenharmony_ci transformation6.IsApplicable(context.get(), transformation_context)); 467fd4e5da5Sopenharmony_ci ApplyAndCheckFreshIds(transformation6, context.get(), 468fd4e5da5Sopenharmony_ci &transformation_context); 469fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 470fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 471fd4e5da5Sopenharmony_ci ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( 472fd4e5da5Sopenharmony_ci MakeDataDescriptor(21, {}), MakeDataDescriptor(15, {}))); 473fd4e5da5Sopenharmony_ci 474fd4e5da5Sopenharmony_ci auto transformation7 = TransformationEquationInstruction( 475fd4e5da5Sopenharmony_ci 22, spv::Op::OpISub, {14, 18}, return_instruction); 476fd4e5da5Sopenharmony_ci ASSERT_TRUE( 477fd4e5da5Sopenharmony_ci transformation7.IsApplicable(context.get(), transformation_context)); 478fd4e5da5Sopenharmony_ci ApplyAndCheckFreshIds(transformation7, context.get(), 479fd4e5da5Sopenharmony_ci &transformation_context); 480fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 481fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 482fd4e5da5Sopenharmony_ci 483fd4e5da5Sopenharmony_ci auto transformation8 = TransformationEquationInstruction( 484fd4e5da5Sopenharmony_ci 23, spv::Op::OpSNegate, {22}, return_instruction); 485fd4e5da5Sopenharmony_ci ASSERT_TRUE( 486fd4e5da5Sopenharmony_ci transformation8.IsApplicable(context.get(), transformation_context)); 487fd4e5da5Sopenharmony_ci ApplyAndCheckFreshIds(transformation8, context.get(), 488fd4e5da5Sopenharmony_ci &transformation_context); 489fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 490fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 491fd4e5da5Sopenharmony_ci ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( 492fd4e5da5Sopenharmony_ci MakeDataDescriptor(23, {}), MakeDataDescriptor(16, {}))); 493fd4e5da5Sopenharmony_ci 494fd4e5da5Sopenharmony_ci std::string after_transformation = R"( 495fd4e5da5Sopenharmony_ci OpCapability Shader 496fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 497fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 498fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %12 "main" 499fd4e5da5Sopenharmony_ci OpExecutionMode %12 OriginUpperLeft 500fd4e5da5Sopenharmony_ci OpSource ESSL 310 501fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 502fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 503fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 504fd4e5da5Sopenharmony_ci %15 = OpConstant %6 24 505fd4e5da5Sopenharmony_ci %16 = OpConstant %6 37 506fd4e5da5Sopenharmony_ci %12 = OpFunction %2 None %3 507fd4e5da5Sopenharmony_ci %13 = OpLabel 508fd4e5da5Sopenharmony_ci %14 = OpISub %6 %15 %16 509fd4e5da5Sopenharmony_ci %17 = OpIAdd %6 %14 %16 ; ==> synonymous(%17, %15) 510fd4e5da5Sopenharmony_ci %18 = OpIAdd %6 %16 %14 ; ==> synonymous(%17, %18, %15) 511fd4e5da5Sopenharmony_ci %19 = OpISub %6 %14 %15 512fd4e5da5Sopenharmony_ci %20 = OpSNegate %6 %19 ; ==> synonymous(%20, %16) 513fd4e5da5Sopenharmony_ci %21 = OpISub %6 %14 %19 ; ==> synonymous(%21, %15) 514fd4e5da5Sopenharmony_ci %22 = OpISub %6 %14 %18 515fd4e5da5Sopenharmony_ci %23 = OpSNegate %6 %22 ; ==> synonymous(%23, %16) 516fd4e5da5Sopenharmony_ci OpReturn 517fd4e5da5Sopenharmony_ci OpFunctionEnd 518fd4e5da5Sopenharmony_ci )"; 519fd4e5da5Sopenharmony_ci 520fd4e5da5Sopenharmony_ci ASSERT_TRUE(IsEqual(env, after_transformation, context.get())); 521fd4e5da5Sopenharmony_ci} 522fd4e5da5Sopenharmony_ci 523fd4e5da5Sopenharmony_ciTEST(TransformationEquationInstructionTest, Bitcast) { 524fd4e5da5Sopenharmony_ci std::string shader = R"( 525fd4e5da5Sopenharmony_ci OpCapability Shader 526fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 527fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 528fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %12 "main" 529fd4e5da5Sopenharmony_ci OpExecutionMode %12 OriginUpperLeft 530fd4e5da5Sopenharmony_ci OpSource ESSL 310 531fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 532fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 533fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 534fd4e5da5Sopenharmony_ci %7 = OpTypeInt 32 0 535fd4e5da5Sopenharmony_ci %8 = OpTypeFloat 32 536fd4e5da5Sopenharmony_ci %9 = OpTypeVector %6 2 537fd4e5da5Sopenharmony_ci %10 = OpTypeVector %7 2 538fd4e5da5Sopenharmony_ci %11 = OpTypeVector %8 2 539fd4e5da5Sopenharmony_ci %21 = OpTypeBool 540fd4e5da5Sopenharmony_ci %22 = OpTypeVector %21 2 541fd4e5da5Sopenharmony_ci %15 = OpConstant %6 24 542fd4e5da5Sopenharmony_ci %16 = OpConstant %7 24 543fd4e5da5Sopenharmony_ci %17 = OpConstant %8 24 544fd4e5da5Sopenharmony_ci %18 = OpConstantComposite %9 %15 %15 545fd4e5da5Sopenharmony_ci %19 = OpConstantComposite %10 %16 %16 546fd4e5da5Sopenharmony_ci %20 = OpConstantComposite %11 %17 %17 547fd4e5da5Sopenharmony_ci %23 = OpConstantTrue %21 548fd4e5da5Sopenharmony_ci %24 = OpConstantComposite %22 %23 %23 549fd4e5da5Sopenharmony_ci %12 = OpFunction %2 None %3 550fd4e5da5Sopenharmony_ci %13 = OpLabel 551fd4e5da5Sopenharmony_ci OpReturn 552fd4e5da5Sopenharmony_ci OpFunctionEnd 553fd4e5da5Sopenharmony_ci )"; 554fd4e5da5Sopenharmony_ci 555fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 556fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 557fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); 558fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 559fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 560fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 561fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 562fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(context.get()), validator_options); 563fd4e5da5Sopenharmony_ci auto insert_before = MakeInstructionDescriptor(13, spv::Op::OpReturn, 0); 564fd4e5da5Sopenharmony_ci 565fd4e5da5Sopenharmony_ci // Too many operands. 566fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationEquationInstruction(50, spv::Op::OpBitcast, 567fd4e5da5Sopenharmony_ci {15, 16}, insert_before) 568fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 569fd4e5da5Sopenharmony_ci 570fd4e5da5Sopenharmony_ci // Too few operands. 571fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationEquationInstruction(50, spv::Op::OpBitcast, {}, 572fd4e5da5Sopenharmony_ci insert_before) 573fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 574fd4e5da5Sopenharmony_ci 575fd4e5da5Sopenharmony_ci // Operand's id is invalid. 576fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationEquationInstruction(50, spv::Op::OpBitcast, {50}, 577fd4e5da5Sopenharmony_ci insert_before) 578fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 579fd4e5da5Sopenharmony_ci 580fd4e5da5Sopenharmony_ci // Operand's type is invalid 581fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationEquationInstruction(50, spv::Op::OpBitcast, {13}, 582fd4e5da5Sopenharmony_ci insert_before) 583fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 584fd4e5da5Sopenharmony_ci 585fd4e5da5Sopenharmony_ci // Operand must be a scalar or a vector of numerical type. 586fd4e5da5Sopenharmony_ci#ifndef NDEBUG 587fd4e5da5Sopenharmony_ci ASSERT_DEATH(TransformationEquationInstruction(50, spv::Op::OpBitcast, {23}, 588fd4e5da5Sopenharmony_ci insert_before) 589fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context), 590fd4e5da5Sopenharmony_ci "Operand is not a scalar or a vector of numerical type"); 591fd4e5da5Sopenharmony_ci ASSERT_DEATH(TransformationEquationInstruction(50, spv::Op::OpBitcast, {24}, 592fd4e5da5Sopenharmony_ci insert_before) 593fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context), 594fd4e5da5Sopenharmony_ci "Only vectors of numerical components are supported"); 595fd4e5da5Sopenharmony_ci#else 596fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationEquationInstruction(50, spv::Op::OpBitcast, {23}, 597fd4e5da5Sopenharmony_ci insert_before) 598fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 599fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationEquationInstruction(50, spv::Op::OpBitcast, {24}, 600fd4e5da5Sopenharmony_ci insert_before) 601fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 602fd4e5da5Sopenharmony_ci#endif 603fd4e5da5Sopenharmony_ci 604fd4e5da5Sopenharmony_ci for (uint32_t operand_id = 15, fresh_id = 50; operand_id <= 20; 605fd4e5da5Sopenharmony_ci ++operand_id, ++fresh_id) { 606fd4e5da5Sopenharmony_ci TransformationEquationInstruction transformation( 607fd4e5da5Sopenharmony_ci fresh_id, spv::Op::OpBitcast, {operand_id}, insert_before); 608fd4e5da5Sopenharmony_ci ASSERT_TRUE( 609fd4e5da5Sopenharmony_ci transformation.IsApplicable(context.get(), transformation_context)); 610fd4e5da5Sopenharmony_ci ApplyAndCheckFreshIds(transformation, context.get(), 611fd4e5da5Sopenharmony_ci &transformation_context); 612fd4e5da5Sopenharmony_ci } 613fd4e5da5Sopenharmony_ci 614fd4e5da5Sopenharmony_ci std::string expected_shader = R"( 615fd4e5da5Sopenharmony_ci OpCapability Shader 616fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 617fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 618fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %12 "main" 619fd4e5da5Sopenharmony_ci OpExecutionMode %12 OriginUpperLeft 620fd4e5da5Sopenharmony_ci OpSource ESSL 310 621fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 622fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 623fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 624fd4e5da5Sopenharmony_ci %7 = OpTypeInt 32 0 625fd4e5da5Sopenharmony_ci %8 = OpTypeFloat 32 626fd4e5da5Sopenharmony_ci %9 = OpTypeVector %6 2 627fd4e5da5Sopenharmony_ci %10 = OpTypeVector %7 2 628fd4e5da5Sopenharmony_ci %11 = OpTypeVector %8 2 629fd4e5da5Sopenharmony_ci %21 = OpTypeBool 630fd4e5da5Sopenharmony_ci %22 = OpTypeVector %21 2 631fd4e5da5Sopenharmony_ci %15 = OpConstant %6 24 632fd4e5da5Sopenharmony_ci %16 = OpConstant %7 24 633fd4e5da5Sopenharmony_ci %17 = OpConstant %8 24 634fd4e5da5Sopenharmony_ci %18 = OpConstantComposite %9 %15 %15 635fd4e5da5Sopenharmony_ci %19 = OpConstantComposite %10 %16 %16 636fd4e5da5Sopenharmony_ci %20 = OpConstantComposite %11 %17 %17 637fd4e5da5Sopenharmony_ci %23 = OpConstantTrue %21 638fd4e5da5Sopenharmony_ci %24 = OpConstantComposite %22 %23 %23 639fd4e5da5Sopenharmony_ci %12 = OpFunction %2 None %3 640fd4e5da5Sopenharmony_ci %13 = OpLabel 641fd4e5da5Sopenharmony_ci %50 = OpBitcast %8 %15 642fd4e5da5Sopenharmony_ci %51 = OpBitcast %8 %16 643fd4e5da5Sopenharmony_ci %52 = OpBitcast %6 %17 644fd4e5da5Sopenharmony_ci %53 = OpBitcast %11 %18 645fd4e5da5Sopenharmony_ci %54 = OpBitcast %11 %19 646fd4e5da5Sopenharmony_ci %55 = OpBitcast %9 %20 647fd4e5da5Sopenharmony_ci OpReturn 648fd4e5da5Sopenharmony_ci OpFunctionEnd 649fd4e5da5Sopenharmony_ci )"; 650fd4e5da5Sopenharmony_ci 651fd4e5da5Sopenharmony_ci ASSERT_TRUE(IsEqual(env, expected_shader, context.get())); 652fd4e5da5Sopenharmony_ci} 653fd4e5da5Sopenharmony_ci 654fd4e5da5Sopenharmony_ciTEST(TransformationEquationInstructionTest, 655fd4e5da5Sopenharmony_ci BitcastResultTypeFloatDoesNotExist) { 656fd4e5da5Sopenharmony_ci std::string shader = R"( 657fd4e5da5Sopenharmony_ci OpCapability Shader 658fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 659fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 660fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %12 "main" 661fd4e5da5Sopenharmony_ci OpExecutionMode %12 OriginUpperLeft 662fd4e5da5Sopenharmony_ci OpSource ESSL 310 663fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 664fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 665fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 666fd4e5da5Sopenharmony_ci %7 = OpTypeInt 32 0 667fd4e5da5Sopenharmony_ci %9 = OpTypeVector %6 2 668fd4e5da5Sopenharmony_ci %10 = OpTypeVector %7 2 669fd4e5da5Sopenharmony_ci %15 = OpConstant %6 24 670fd4e5da5Sopenharmony_ci %16 = OpConstant %7 24 671fd4e5da5Sopenharmony_ci %18 = OpConstantComposite %9 %15 %15 672fd4e5da5Sopenharmony_ci %19 = OpConstantComposite %10 %16 %16 673fd4e5da5Sopenharmony_ci %12 = OpFunction %2 None %3 674fd4e5da5Sopenharmony_ci %13 = OpLabel 675fd4e5da5Sopenharmony_ci OpReturn 676fd4e5da5Sopenharmony_ci OpFunctionEnd 677fd4e5da5Sopenharmony_ci )"; 678fd4e5da5Sopenharmony_ci 679fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 680fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 681fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); 682fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 683fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 684fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 685fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 686fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(context.get()), validator_options); 687fd4e5da5Sopenharmony_ci auto insert_before = MakeInstructionDescriptor(13, spv::Op::OpReturn, 0); 688fd4e5da5Sopenharmony_ci 689fd4e5da5Sopenharmony_ci // Scalar floating-point type does not exist. 690fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationEquationInstruction(50, spv::Op::OpBitcast, {15}, 691fd4e5da5Sopenharmony_ci insert_before) 692fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 693fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationEquationInstruction(50, spv::Op::OpBitcast, {16}, 694fd4e5da5Sopenharmony_ci insert_before) 695fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 696fd4e5da5Sopenharmony_ci 697fd4e5da5Sopenharmony_ci // Vector of floating-point components does not exist. 698fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationEquationInstruction(50, spv::Op::OpBitcast, {18}, 699fd4e5da5Sopenharmony_ci insert_before) 700fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 701fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationEquationInstruction(50, spv::Op::OpBitcast, {19}, 702fd4e5da5Sopenharmony_ci insert_before) 703fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 704fd4e5da5Sopenharmony_ci} 705fd4e5da5Sopenharmony_ci 706fd4e5da5Sopenharmony_ciTEST(TransformationEquationInstructionTest, BitcastResultTypeIntDoesNotExist1) { 707fd4e5da5Sopenharmony_ci std::string shader = R"( 708fd4e5da5Sopenharmony_ci OpCapability Shader 709fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 710fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 711fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %12 "main" 712fd4e5da5Sopenharmony_ci OpExecutionMode %12 OriginUpperLeft 713fd4e5da5Sopenharmony_ci OpSource ESSL 310 714fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 715fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 716fd4e5da5Sopenharmony_ci %8 = OpTypeFloat 32 717fd4e5da5Sopenharmony_ci %11 = OpTypeVector %8 2 718fd4e5da5Sopenharmony_ci %17 = OpConstant %8 24 719fd4e5da5Sopenharmony_ci %20 = OpConstantComposite %11 %17 %17 720fd4e5da5Sopenharmony_ci %12 = OpFunction %2 None %3 721fd4e5da5Sopenharmony_ci %13 = OpLabel 722fd4e5da5Sopenharmony_ci OpReturn 723fd4e5da5Sopenharmony_ci OpFunctionEnd 724fd4e5da5Sopenharmony_ci )"; 725fd4e5da5Sopenharmony_ci 726fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 727fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 728fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); 729fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 730fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 731fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 732fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 733fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(context.get()), validator_options); 734fd4e5da5Sopenharmony_ci auto insert_before = MakeInstructionDescriptor(13, spv::Op::OpReturn, 0); 735fd4e5da5Sopenharmony_ci 736fd4e5da5Sopenharmony_ci // Scalar integral type does not exist. 737fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationEquationInstruction(50, spv::Op::OpBitcast, {17}, 738fd4e5da5Sopenharmony_ci insert_before) 739fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 740fd4e5da5Sopenharmony_ci 741fd4e5da5Sopenharmony_ci // Vector of integral components does not exist. 742fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationEquationInstruction(50, spv::Op::OpBitcast, {20}, 743fd4e5da5Sopenharmony_ci insert_before) 744fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 745fd4e5da5Sopenharmony_ci} 746fd4e5da5Sopenharmony_ci 747fd4e5da5Sopenharmony_ciTEST(TransformationEquationInstructionTest, BitcastResultTypeIntDoesNotExist2) { 748fd4e5da5Sopenharmony_ci std::string shader = R"( 749fd4e5da5Sopenharmony_ci OpCapability Shader 750fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 751fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 752fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %12 "main" 753fd4e5da5Sopenharmony_ci OpExecutionMode %12 OriginUpperLeft 754fd4e5da5Sopenharmony_ci OpSource ESSL 310 755fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 756fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 757fd4e5da5Sopenharmony_ci %4 = OpTypeInt 32 0 758fd4e5da5Sopenharmony_ci %8 = OpTypeFloat 32 759fd4e5da5Sopenharmony_ci %9 = OpTypeVector %4 2 760fd4e5da5Sopenharmony_ci %11 = OpTypeVector %8 2 761fd4e5da5Sopenharmony_ci %17 = OpConstant %8 24 762fd4e5da5Sopenharmony_ci %20 = OpConstantComposite %11 %17 %17 763fd4e5da5Sopenharmony_ci %12 = OpFunction %2 None %3 764fd4e5da5Sopenharmony_ci %13 = OpLabel 765fd4e5da5Sopenharmony_ci OpReturn 766fd4e5da5Sopenharmony_ci OpFunctionEnd 767fd4e5da5Sopenharmony_ci )"; 768fd4e5da5Sopenharmony_ci 769fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 770fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 771fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); 772fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 773fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 774fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 775fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 776fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(context.get()), validator_options); 777fd4e5da5Sopenharmony_ci auto insert_before = MakeInstructionDescriptor(13, spv::Op::OpReturn, 0); 778fd4e5da5Sopenharmony_ci 779fd4e5da5Sopenharmony_ci { 780fd4e5da5Sopenharmony_ci TransformationEquationInstruction transformation(50, spv::Op::OpBitcast, 781fd4e5da5Sopenharmony_ci {17}, insert_before); 782fd4e5da5Sopenharmony_ci ASSERT_TRUE( 783fd4e5da5Sopenharmony_ci transformation.IsApplicable(context.get(), transformation_context)); 784fd4e5da5Sopenharmony_ci ApplyAndCheckFreshIds(transformation, context.get(), 785fd4e5da5Sopenharmony_ci &transformation_context); 786fd4e5da5Sopenharmony_ci } 787fd4e5da5Sopenharmony_ci { 788fd4e5da5Sopenharmony_ci TransformationEquationInstruction transformation(51, spv::Op::OpBitcast, 789fd4e5da5Sopenharmony_ci {20}, insert_before); 790fd4e5da5Sopenharmony_ci ASSERT_TRUE( 791fd4e5da5Sopenharmony_ci transformation.IsApplicable(context.get(), transformation_context)); 792fd4e5da5Sopenharmony_ci ApplyAndCheckFreshIds(transformation, context.get(), 793fd4e5da5Sopenharmony_ci &transformation_context); 794fd4e5da5Sopenharmony_ci } 795fd4e5da5Sopenharmony_ci 796fd4e5da5Sopenharmony_ci std::string expected_shader = R"( 797fd4e5da5Sopenharmony_ci OpCapability Shader 798fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 799fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 800fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %12 "main" 801fd4e5da5Sopenharmony_ci OpExecutionMode %12 OriginUpperLeft 802fd4e5da5Sopenharmony_ci OpSource ESSL 310 803fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 804fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 805fd4e5da5Sopenharmony_ci %4 = OpTypeInt 32 0 806fd4e5da5Sopenharmony_ci %8 = OpTypeFloat 32 807fd4e5da5Sopenharmony_ci %9 = OpTypeVector %4 2 808fd4e5da5Sopenharmony_ci %11 = OpTypeVector %8 2 809fd4e5da5Sopenharmony_ci %17 = OpConstant %8 24 810fd4e5da5Sopenharmony_ci %20 = OpConstantComposite %11 %17 %17 811fd4e5da5Sopenharmony_ci %12 = OpFunction %2 None %3 812fd4e5da5Sopenharmony_ci %13 = OpLabel 813fd4e5da5Sopenharmony_ci %50 = OpBitcast %4 %17 814fd4e5da5Sopenharmony_ci %51 = OpBitcast %9 %20 815fd4e5da5Sopenharmony_ci OpReturn 816fd4e5da5Sopenharmony_ci OpFunctionEnd 817fd4e5da5Sopenharmony_ci )"; 818fd4e5da5Sopenharmony_ci 819fd4e5da5Sopenharmony_ci ASSERT_TRUE(IsEqual(env, expected_shader, context.get())); 820fd4e5da5Sopenharmony_ci} 821fd4e5da5Sopenharmony_ci 822fd4e5da5Sopenharmony_ciTEST(TransformationEquationInstructionTest, BitcastResultTypeIntDoesNotExist3) { 823fd4e5da5Sopenharmony_ci std::string shader = R"( 824fd4e5da5Sopenharmony_ci OpCapability Shader 825fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 826fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 827fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %12 "main" 828fd4e5da5Sopenharmony_ci OpExecutionMode %12 OriginUpperLeft 829fd4e5da5Sopenharmony_ci OpSource ESSL 310 830fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 831fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 832fd4e5da5Sopenharmony_ci %4 = OpTypeInt 32 1 833fd4e5da5Sopenharmony_ci %8 = OpTypeFloat 32 834fd4e5da5Sopenharmony_ci %9 = OpTypeVector %4 2 835fd4e5da5Sopenharmony_ci %11 = OpTypeVector %8 2 836fd4e5da5Sopenharmony_ci %17 = OpConstant %8 24 837fd4e5da5Sopenharmony_ci %20 = OpConstantComposite %11 %17 %17 838fd4e5da5Sopenharmony_ci %12 = OpFunction %2 None %3 839fd4e5da5Sopenharmony_ci %13 = OpLabel 840fd4e5da5Sopenharmony_ci OpReturn 841fd4e5da5Sopenharmony_ci OpFunctionEnd 842fd4e5da5Sopenharmony_ci )"; 843fd4e5da5Sopenharmony_ci 844fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 845fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 846fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); 847fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 848fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 849fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 850fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 851fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(context.get()), validator_options); 852fd4e5da5Sopenharmony_ci auto insert_before = MakeInstructionDescriptor(13, spv::Op::OpReturn, 0); 853fd4e5da5Sopenharmony_ci 854fd4e5da5Sopenharmony_ci { 855fd4e5da5Sopenharmony_ci TransformationEquationInstruction transformation(50, spv::Op::OpBitcast, 856fd4e5da5Sopenharmony_ci {17}, insert_before); 857fd4e5da5Sopenharmony_ci ASSERT_TRUE( 858fd4e5da5Sopenharmony_ci transformation.IsApplicable(context.get(), transformation_context)); 859fd4e5da5Sopenharmony_ci ApplyAndCheckFreshIds(transformation, context.get(), 860fd4e5da5Sopenharmony_ci &transformation_context); 861fd4e5da5Sopenharmony_ci } 862fd4e5da5Sopenharmony_ci { 863fd4e5da5Sopenharmony_ci TransformationEquationInstruction transformation(51, spv::Op::OpBitcast, 864fd4e5da5Sopenharmony_ci {20}, insert_before); 865fd4e5da5Sopenharmony_ci ASSERT_TRUE( 866fd4e5da5Sopenharmony_ci transformation.IsApplicable(context.get(), transformation_context)); 867fd4e5da5Sopenharmony_ci ApplyAndCheckFreshIds(transformation, context.get(), 868fd4e5da5Sopenharmony_ci &transformation_context); 869fd4e5da5Sopenharmony_ci } 870fd4e5da5Sopenharmony_ci 871fd4e5da5Sopenharmony_ci std::string expected_shader = R"( 872fd4e5da5Sopenharmony_ci OpCapability Shader 873fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 874fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 875fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %12 "main" 876fd4e5da5Sopenharmony_ci OpExecutionMode %12 OriginUpperLeft 877fd4e5da5Sopenharmony_ci OpSource ESSL 310 878fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 879fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 880fd4e5da5Sopenharmony_ci %4 = OpTypeInt 32 1 881fd4e5da5Sopenharmony_ci %8 = OpTypeFloat 32 882fd4e5da5Sopenharmony_ci %9 = OpTypeVector %4 2 883fd4e5da5Sopenharmony_ci %11 = OpTypeVector %8 2 884fd4e5da5Sopenharmony_ci %17 = OpConstant %8 24 885fd4e5da5Sopenharmony_ci %20 = OpConstantComposite %11 %17 %17 886fd4e5da5Sopenharmony_ci %12 = OpFunction %2 None %3 887fd4e5da5Sopenharmony_ci %13 = OpLabel 888fd4e5da5Sopenharmony_ci %50 = OpBitcast %4 %17 889fd4e5da5Sopenharmony_ci %51 = OpBitcast %9 %20 890fd4e5da5Sopenharmony_ci OpReturn 891fd4e5da5Sopenharmony_ci OpFunctionEnd 892fd4e5da5Sopenharmony_ci )"; 893fd4e5da5Sopenharmony_ci 894fd4e5da5Sopenharmony_ci ASSERT_TRUE(IsEqual(env, expected_shader, context.get())); 895fd4e5da5Sopenharmony_ci} 896fd4e5da5Sopenharmony_ci 897fd4e5da5Sopenharmony_ciTEST(TransformationEquationInstructionTest, BitcastResultTypeIntDoesNotExist4) { 898fd4e5da5Sopenharmony_ci std::string shader = R"( 899fd4e5da5Sopenharmony_ci OpCapability Shader 900fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 901fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 902fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %12 "main" 903fd4e5da5Sopenharmony_ci OpExecutionMode %12 OriginUpperLeft 904fd4e5da5Sopenharmony_ci OpSource ESSL 310 905fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 906fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 907fd4e5da5Sopenharmony_ci %4 = OpTypeInt 32 1 908fd4e5da5Sopenharmony_ci %8 = OpTypeFloat 32 909fd4e5da5Sopenharmony_ci %11 = OpTypeVector %8 2 910fd4e5da5Sopenharmony_ci %17 = OpConstant %8 24 911fd4e5da5Sopenharmony_ci %20 = OpConstantComposite %11 %17 %17 912fd4e5da5Sopenharmony_ci %12 = OpFunction %2 None %3 913fd4e5da5Sopenharmony_ci %13 = OpLabel 914fd4e5da5Sopenharmony_ci OpReturn 915fd4e5da5Sopenharmony_ci OpFunctionEnd 916fd4e5da5Sopenharmony_ci )"; 917fd4e5da5Sopenharmony_ci 918fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 919fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 920fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); 921fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 922fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 923fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 924fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 925fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(context.get()), validator_options); 926fd4e5da5Sopenharmony_ci auto insert_before = MakeInstructionDescriptor(13, spv::Op::OpReturn, 0); 927fd4e5da5Sopenharmony_ci 928fd4e5da5Sopenharmony_ci { 929fd4e5da5Sopenharmony_ci TransformationEquationInstruction transformation(50, spv::Op::OpBitcast, 930fd4e5da5Sopenharmony_ci {17}, insert_before); 931fd4e5da5Sopenharmony_ci ASSERT_TRUE( 932fd4e5da5Sopenharmony_ci transformation.IsApplicable(context.get(), transformation_context)); 933fd4e5da5Sopenharmony_ci ApplyAndCheckFreshIds(transformation, context.get(), 934fd4e5da5Sopenharmony_ci &transformation_context); 935fd4e5da5Sopenharmony_ci } 936fd4e5da5Sopenharmony_ci 937fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationEquationInstruction(51, spv::Op::OpBitcast, {20}, 938fd4e5da5Sopenharmony_ci insert_before) 939fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 940fd4e5da5Sopenharmony_ci 941fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 942fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 943fd4e5da5Sopenharmony_ci 944fd4e5da5Sopenharmony_ci std::string expected_shader = R"( 945fd4e5da5Sopenharmony_ci OpCapability Shader 946fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 947fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 948fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %12 "main" 949fd4e5da5Sopenharmony_ci OpExecutionMode %12 OriginUpperLeft 950fd4e5da5Sopenharmony_ci OpSource ESSL 310 951fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 952fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 953fd4e5da5Sopenharmony_ci %4 = OpTypeInt 32 1 954fd4e5da5Sopenharmony_ci %8 = OpTypeFloat 32 955fd4e5da5Sopenharmony_ci %11 = OpTypeVector %8 2 956fd4e5da5Sopenharmony_ci %17 = OpConstant %8 24 957fd4e5da5Sopenharmony_ci %20 = OpConstantComposite %11 %17 %17 958fd4e5da5Sopenharmony_ci %12 = OpFunction %2 None %3 959fd4e5da5Sopenharmony_ci %13 = OpLabel 960fd4e5da5Sopenharmony_ci %50 = OpBitcast %4 %17 961fd4e5da5Sopenharmony_ci OpReturn 962fd4e5da5Sopenharmony_ci OpFunctionEnd 963fd4e5da5Sopenharmony_ci )"; 964fd4e5da5Sopenharmony_ci 965fd4e5da5Sopenharmony_ci ASSERT_TRUE(IsEqual(env, expected_shader, context.get())); 966fd4e5da5Sopenharmony_ci} 967fd4e5da5Sopenharmony_ci 968fd4e5da5Sopenharmony_ciTEST(TransformationEquationInstructionTest, BitcastResultTypeIntDoesNotExist5) { 969fd4e5da5Sopenharmony_ci std::string shader = R"( 970fd4e5da5Sopenharmony_ci OpCapability Shader 971fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 972fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 973fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %12 "main" 974fd4e5da5Sopenharmony_ci OpExecutionMode %12 OriginUpperLeft 975fd4e5da5Sopenharmony_ci OpSource ESSL 310 976fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 977fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 978fd4e5da5Sopenharmony_ci %4 = OpTypeInt 32 0 979fd4e5da5Sopenharmony_ci %8 = OpTypeFloat 32 980fd4e5da5Sopenharmony_ci %11 = OpTypeVector %8 2 981fd4e5da5Sopenharmony_ci %17 = OpConstant %8 24 982fd4e5da5Sopenharmony_ci %20 = OpConstantComposite %11 %17 %17 983fd4e5da5Sopenharmony_ci %12 = OpFunction %2 None %3 984fd4e5da5Sopenharmony_ci %13 = OpLabel 985fd4e5da5Sopenharmony_ci OpReturn 986fd4e5da5Sopenharmony_ci OpFunctionEnd 987fd4e5da5Sopenharmony_ci )"; 988fd4e5da5Sopenharmony_ci 989fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 990fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 991fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); 992fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 993fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 994fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 995fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 996fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(context.get()), validator_options); 997fd4e5da5Sopenharmony_ci auto insert_before = MakeInstructionDescriptor(13, spv::Op::OpReturn, 0); 998fd4e5da5Sopenharmony_ci 999fd4e5da5Sopenharmony_ci { 1000fd4e5da5Sopenharmony_ci TransformationEquationInstruction transformation(50, spv::Op::OpBitcast, 1001fd4e5da5Sopenharmony_ci {17}, insert_before); 1002fd4e5da5Sopenharmony_ci ASSERT_TRUE( 1003fd4e5da5Sopenharmony_ci transformation.IsApplicable(context.get(), transformation_context)); 1004fd4e5da5Sopenharmony_ci ApplyAndCheckFreshIds(transformation, context.get(), 1005fd4e5da5Sopenharmony_ci &transformation_context); 1006fd4e5da5Sopenharmony_ci } 1007fd4e5da5Sopenharmony_ci 1008fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationEquationInstruction(51, spv::Op::OpBitcast, {20}, 1009fd4e5da5Sopenharmony_ci insert_before) 1010fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 1011fd4e5da5Sopenharmony_ci 1012fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 1013fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 1014fd4e5da5Sopenharmony_ci 1015fd4e5da5Sopenharmony_ci std::string expected_shader = R"( 1016fd4e5da5Sopenharmony_ci OpCapability Shader 1017fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 1018fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1019fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %12 "main" 1020fd4e5da5Sopenharmony_ci OpExecutionMode %12 OriginUpperLeft 1021fd4e5da5Sopenharmony_ci OpSource ESSL 310 1022fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 1023fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 1024fd4e5da5Sopenharmony_ci %4 = OpTypeInt 32 0 1025fd4e5da5Sopenharmony_ci %8 = OpTypeFloat 32 1026fd4e5da5Sopenharmony_ci %11 = OpTypeVector %8 2 1027fd4e5da5Sopenharmony_ci %17 = OpConstant %8 24 1028fd4e5da5Sopenharmony_ci %20 = OpConstantComposite %11 %17 %17 1029fd4e5da5Sopenharmony_ci %12 = OpFunction %2 None %3 1030fd4e5da5Sopenharmony_ci %13 = OpLabel 1031fd4e5da5Sopenharmony_ci %50 = OpBitcast %4 %17 1032fd4e5da5Sopenharmony_ci OpReturn 1033fd4e5da5Sopenharmony_ci OpFunctionEnd 1034fd4e5da5Sopenharmony_ci )"; 1035fd4e5da5Sopenharmony_ci 1036fd4e5da5Sopenharmony_ci ASSERT_TRUE(IsEqual(env, expected_shader, context.get())); 1037fd4e5da5Sopenharmony_ci} 1038fd4e5da5Sopenharmony_ci 1039fd4e5da5Sopenharmony_ciTEST(TransformationEquationInstructionTest, BitcastResultTypeIntDoesNotExist6) { 1040fd4e5da5Sopenharmony_ci std::string shader = R"( 1041fd4e5da5Sopenharmony_ci OpCapability Shader 1042fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 1043fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1044fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %12 "main" 1045fd4e5da5Sopenharmony_ci OpExecutionMode %12 OriginUpperLeft 1046fd4e5da5Sopenharmony_ci OpSource ESSL 310 1047fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 1048fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 1049fd4e5da5Sopenharmony_ci %4 = OpTypeInt 32 1 1050fd4e5da5Sopenharmony_ci %5 = OpTypeInt 32 0 1051fd4e5da5Sopenharmony_ci %8 = OpTypeFloat 32 1052fd4e5da5Sopenharmony_ci %9 = OpTypeVector %5 2 1053fd4e5da5Sopenharmony_ci %11 = OpTypeVector %8 2 1054fd4e5da5Sopenharmony_ci %17 = OpConstant %8 24 1055fd4e5da5Sopenharmony_ci %20 = OpConstantComposite %11 %17 %17 1056fd4e5da5Sopenharmony_ci %12 = OpFunction %2 None %3 1057fd4e5da5Sopenharmony_ci %13 = OpLabel 1058fd4e5da5Sopenharmony_ci OpReturn 1059fd4e5da5Sopenharmony_ci OpFunctionEnd 1060fd4e5da5Sopenharmony_ci )"; 1061fd4e5da5Sopenharmony_ci 1062fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 1063fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 1064fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); 1065fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 1066fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 1067fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 1068fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 1069fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(context.get()), validator_options); 1070fd4e5da5Sopenharmony_ci auto insert_before = MakeInstructionDescriptor(13, spv::Op::OpReturn, 0); 1071fd4e5da5Sopenharmony_ci 1072fd4e5da5Sopenharmony_ci { 1073fd4e5da5Sopenharmony_ci TransformationEquationInstruction transformation(50, spv::Op::OpBitcast, 1074fd4e5da5Sopenharmony_ci {17}, insert_before); 1075fd4e5da5Sopenharmony_ci ASSERT_TRUE( 1076fd4e5da5Sopenharmony_ci transformation.IsApplicable(context.get(), transformation_context)); 1077fd4e5da5Sopenharmony_ci ApplyAndCheckFreshIds(transformation, context.get(), 1078fd4e5da5Sopenharmony_ci &transformation_context); 1079fd4e5da5Sopenharmony_ci } 1080fd4e5da5Sopenharmony_ci { 1081fd4e5da5Sopenharmony_ci TransformationEquationInstruction transformation(51, spv::Op::OpBitcast, 1082fd4e5da5Sopenharmony_ci {20}, insert_before); 1083fd4e5da5Sopenharmony_ci ASSERT_TRUE( 1084fd4e5da5Sopenharmony_ci transformation.IsApplicable(context.get(), transformation_context)); 1085fd4e5da5Sopenharmony_ci ApplyAndCheckFreshIds(transformation, context.get(), 1086fd4e5da5Sopenharmony_ci &transformation_context); 1087fd4e5da5Sopenharmony_ci } 1088fd4e5da5Sopenharmony_ci 1089fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 1090fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 1091fd4e5da5Sopenharmony_ci 1092fd4e5da5Sopenharmony_ci std::string expected_shader = R"( 1093fd4e5da5Sopenharmony_ci OpCapability Shader 1094fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 1095fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1096fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %12 "main" 1097fd4e5da5Sopenharmony_ci OpExecutionMode %12 OriginUpperLeft 1098fd4e5da5Sopenharmony_ci OpSource ESSL 310 1099fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 1100fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 1101fd4e5da5Sopenharmony_ci %4 = OpTypeInt 32 1 1102fd4e5da5Sopenharmony_ci %5 = OpTypeInt 32 0 1103fd4e5da5Sopenharmony_ci %8 = OpTypeFloat 32 1104fd4e5da5Sopenharmony_ci %9 = OpTypeVector %5 2 1105fd4e5da5Sopenharmony_ci %11 = OpTypeVector %8 2 1106fd4e5da5Sopenharmony_ci %17 = OpConstant %8 24 1107fd4e5da5Sopenharmony_ci %20 = OpConstantComposite %11 %17 %17 1108fd4e5da5Sopenharmony_ci %12 = OpFunction %2 None %3 1109fd4e5da5Sopenharmony_ci %13 = OpLabel 1110fd4e5da5Sopenharmony_ci %50 = OpBitcast %4 %17 1111fd4e5da5Sopenharmony_ci %51 = OpBitcast %9 %20 1112fd4e5da5Sopenharmony_ci OpReturn 1113fd4e5da5Sopenharmony_ci OpFunctionEnd 1114fd4e5da5Sopenharmony_ci )"; 1115fd4e5da5Sopenharmony_ci 1116fd4e5da5Sopenharmony_ci ASSERT_TRUE(IsEqual(env, expected_shader, context.get())); 1117fd4e5da5Sopenharmony_ci} 1118fd4e5da5Sopenharmony_ci 1119fd4e5da5Sopenharmony_ciTEST(TransformationEquationInstructionTest, BitcastResultTypeIntDoesNotExist7) { 1120fd4e5da5Sopenharmony_ci std::string shader = R"( 1121fd4e5da5Sopenharmony_ci OpCapability Shader 1122fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 1123fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1124fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %12 "main" 1125fd4e5da5Sopenharmony_ci OpExecutionMode %12 OriginUpperLeft 1126fd4e5da5Sopenharmony_ci OpSource ESSL 310 1127fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 1128fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 1129fd4e5da5Sopenharmony_ci %4 = OpTypeInt 32 1 1130fd4e5da5Sopenharmony_ci %5 = OpTypeInt 32 0 1131fd4e5da5Sopenharmony_ci %8 = OpTypeFloat 32 1132fd4e5da5Sopenharmony_ci %9 = OpTypeVector %4 2 1133fd4e5da5Sopenharmony_ci %11 = OpTypeVector %8 2 1134fd4e5da5Sopenharmony_ci %17 = OpConstant %8 24 1135fd4e5da5Sopenharmony_ci %20 = OpConstantComposite %11 %17 %17 1136fd4e5da5Sopenharmony_ci %12 = OpFunction %2 None %3 1137fd4e5da5Sopenharmony_ci %13 = OpLabel 1138fd4e5da5Sopenharmony_ci OpReturn 1139fd4e5da5Sopenharmony_ci OpFunctionEnd 1140fd4e5da5Sopenharmony_ci )"; 1141fd4e5da5Sopenharmony_ci 1142fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 1143fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 1144fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); 1145fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 1146fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 1147fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 1148fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 1149fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(context.get()), validator_options); 1150fd4e5da5Sopenharmony_ci auto insert_before = MakeInstructionDescriptor(13, spv::Op::OpReturn, 0); 1151fd4e5da5Sopenharmony_ci 1152fd4e5da5Sopenharmony_ci { 1153fd4e5da5Sopenharmony_ci TransformationEquationInstruction transformation(50, spv::Op::OpBitcast, 1154fd4e5da5Sopenharmony_ci {17}, insert_before); 1155fd4e5da5Sopenharmony_ci ASSERT_TRUE( 1156fd4e5da5Sopenharmony_ci transformation.IsApplicable(context.get(), transformation_context)); 1157fd4e5da5Sopenharmony_ci ApplyAndCheckFreshIds(transformation, context.get(), 1158fd4e5da5Sopenharmony_ci &transformation_context); 1159fd4e5da5Sopenharmony_ci } 1160fd4e5da5Sopenharmony_ci { 1161fd4e5da5Sopenharmony_ci TransformationEquationInstruction transformation(51, spv::Op::OpBitcast, 1162fd4e5da5Sopenharmony_ci {20}, insert_before); 1163fd4e5da5Sopenharmony_ci ASSERT_TRUE( 1164fd4e5da5Sopenharmony_ci transformation.IsApplicable(context.get(), transformation_context)); 1165fd4e5da5Sopenharmony_ci ApplyAndCheckFreshIds(transformation, context.get(), 1166fd4e5da5Sopenharmony_ci &transformation_context); 1167fd4e5da5Sopenharmony_ci } 1168fd4e5da5Sopenharmony_ci 1169fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 1170fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 1171fd4e5da5Sopenharmony_ci 1172fd4e5da5Sopenharmony_ci std::string expected_shader = R"( 1173fd4e5da5Sopenharmony_ci OpCapability Shader 1174fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 1175fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1176fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %12 "main" 1177fd4e5da5Sopenharmony_ci OpExecutionMode %12 OriginUpperLeft 1178fd4e5da5Sopenharmony_ci OpSource ESSL 310 1179fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 1180fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 1181fd4e5da5Sopenharmony_ci %4 = OpTypeInt 32 1 1182fd4e5da5Sopenharmony_ci %5 = OpTypeInt 32 0 1183fd4e5da5Sopenharmony_ci %8 = OpTypeFloat 32 1184fd4e5da5Sopenharmony_ci %9 = OpTypeVector %4 2 1185fd4e5da5Sopenharmony_ci %11 = OpTypeVector %8 2 1186fd4e5da5Sopenharmony_ci %17 = OpConstant %8 24 1187fd4e5da5Sopenharmony_ci %20 = OpConstantComposite %11 %17 %17 1188fd4e5da5Sopenharmony_ci %12 = OpFunction %2 None %3 1189fd4e5da5Sopenharmony_ci %13 = OpLabel 1190fd4e5da5Sopenharmony_ci %50 = OpBitcast %4 %17 1191fd4e5da5Sopenharmony_ci %51 = OpBitcast %9 %20 1192fd4e5da5Sopenharmony_ci OpReturn 1193fd4e5da5Sopenharmony_ci OpFunctionEnd 1194fd4e5da5Sopenharmony_ci )"; 1195fd4e5da5Sopenharmony_ci 1196fd4e5da5Sopenharmony_ci ASSERT_TRUE(IsEqual(env, expected_shader, context.get())); 1197fd4e5da5Sopenharmony_ci} 1198fd4e5da5Sopenharmony_ci 1199fd4e5da5Sopenharmony_ciTEST(TransformationEquationInstructionTest, Miscellaneous1) { 1200fd4e5da5Sopenharmony_ci std::string shader = R"( 1201fd4e5da5Sopenharmony_ci OpCapability Shader 1202fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 1203fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1204fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %12 "main" 1205fd4e5da5Sopenharmony_ci OpExecutionMode %12 OriginUpperLeft 1206fd4e5da5Sopenharmony_ci OpSource ESSL 310 1207fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 1208fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 1209fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 1210fd4e5da5Sopenharmony_ci %113 = OpConstant %6 24 1211fd4e5da5Sopenharmony_ci %12 = OpFunction %2 None %3 1212fd4e5da5Sopenharmony_ci %13 = OpLabel 1213fd4e5da5Sopenharmony_ci OpReturn 1214fd4e5da5Sopenharmony_ci OpFunctionEnd 1215fd4e5da5Sopenharmony_ci )"; 1216fd4e5da5Sopenharmony_ci 1217fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 1218fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 1219fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); 1220fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 1221fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 1222fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 1223fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 1224fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(context.get()), validator_options); 1225fd4e5da5Sopenharmony_ci protobufs::InstructionDescriptor return_instruction = 1226fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(13, spv::Op::OpReturn, 0); 1227fd4e5da5Sopenharmony_ci 1228fd4e5da5Sopenharmony_ci auto transformation1 = TransformationEquationInstruction( 1229fd4e5da5Sopenharmony_ci 522, spv::Op::OpISub, {113, 113}, return_instruction); 1230fd4e5da5Sopenharmony_ci ASSERT_TRUE( 1231fd4e5da5Sopenharmony_ci transformation1.IsApplicable(context.get(), transformation_context)); 1232fd4e5da5Sopenharmony_ci ApplyAndCheckFreshIds(transformation1, context.get(), 1233fd4e5da5Sopenharmony_ci &transformation_context); 1234fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 1235fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 1236fd4e5da5Sopenharmony_ci 1237fd4e5da5Sopenharmony_ci auto transformation2 = TransformationEquationInstruction( 1238fd4e5da5Sopenharmony_ci 570, spv::Op::OpIAdd, {522, 113}, return_instruction); 1239fd4e5da5Sopenharmony_ci ASSERT_TRUE( 1240fd4e5da5Sopenharmony_ci transformation2.IsApplicable(context.get(), transformation_context)); 1241fd4e5da5Sopenharmony_ci ApplyAndCheckFreshIds(transformation2, context.get(), 1242fd4e5da5Sopenharmony_ci &transformation_context); 1243fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 1244fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 1245fd4e5da5Sopenharmony_ci 1246fd4e5da5Sopenharmony_ci std::string after_transformation = R"( 1247fd4e5da5Sopenharmony_ci OpCapability Shader 1248fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 1249fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1250fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %12 "main" 1251fd4e5da5Sopenharmony_ci OpExecutionMode %12 OriginUpperLeft 1252fd4e5da5Sopenharmony_ci OpSource ESSL 310 1253fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 1254fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 1255fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 1256fd4e5da5Sopenharmony_ci %113 = OpConstant %6 24 1257fd4e5da5Sopenharmony_ci %12 = OpFunction %2 None %3 1258fd4e5da5Sopenharmony_ci %13 = OpLabel 1259fd4e5da5Sopenharmony_ci %522 = OpISub %6 %113 %113 1260fd4e5da5Sopenharmony_ci %570 = OpIAdd %6 %522 %113 1261fd4e5da5Sopenharmony_ci OpReturn 1262fd4e5da5Sopenharmony_ci OpFunctionEnd 1263fd4e5da5Sopenharmony_ci )"; 1264fd4e5da5Sopenharmony_ci 1265fd4e5da5Sopenharmony_ci ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( 1266fd4e5da5Sopenharmony_ci MakeDataDescriptor(570, {}), MakeDataDescriptor(113, {}))); 1267fd4e5da5Sopenharmony_ci 1268fd4e5da5Sopenharmony_ci ASSERT_TRUE(IsEqual(env, after_transformation, context.get())); 1269fd4e5da5Sopenharmony_ci} 1270fd4e5da5Sopenharmony_ci 1271fd4e5da5Sopenharmony_ciTEST(TransformationEquationInstructionTest, Miscellaneous2) { 1272fd4e5da5Sopenharmony_ci std::string shader = R"( 1273fd4e5da5Sopenharmony_ci OpCapability Shader 1274fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 1275fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1276fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %12 "main" 1277fd4e5da5Sopenharmony_ci OpExecutionMode %12 OriginUpperLeft 1278fd4e5da5Sopenharmony_ci OpSource ESSL 310 1279fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 1280fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 1281fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 1282fd4e5da5Sopenharmony_ci %113 = OpConstant %6 24 1283fd4e5da5Sopenharmony_ci %12 = OpFunction %2 None %3 1284fd4e5da5Sopenharmony_ci %13 = OpLabel 1285fd4e5da5Sopenharmony_ci OpReturn 1286fd4e5da5Sopenharmony_ci OpFunctionEnd 1287fd4e5da5Sopenharmony_ci )"; 1288fd4e5da5Sopenharmony_ci 1289fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 1290fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 1291fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); 1292fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 1293fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 1294fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 1295fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 1296fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(context.get()), validator_options); 1297fd4e5da5Sopenharmony_ci protobufs::InstructionDescriptor return_instruction = 1298fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(13, spv::Op::OpReturn, 0); 1299fd4e5da5Sopenharmony_ci 1300fd4e5da5Sopenharmony_ci auto transformation1 = TransformationEquationInstruction( 1301fd4e5da5Sopenharmony_ci 522, spv::Op::OpISub, {113, 113}, return_instruction); 1302fd4e5da5Sopenharmony_ci ASSERT_TRUE( 1303fd4e5da5Sopenharmony_ci transformation1.IsApplicable(context.get(), transformation_context)); 1304fd4e5da5Sopenharmony_ci ApplyAndCheckFreshIds(transformation1, context.get(), 1305fd4e5da5Sopenharmony_ci &transformation_context); 1306fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 1307fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 1308fd4e5da5Sopenharmony_ci 1309fd4e5da5Sopenharmony_ci auto transformation2 = TransformationEquationInstruction( 1310fd4e5da5Sopenharmony_ci 570, spv::Op::OpIAdd, {522, 113}, return_instruction); 1311fd4e5da5Sopenharmony_ci ASSERT_TRUE( 1312fd4e5da5Sopenharmony_ci transformation2.IsApplicable(context.get(), transformation_context)); 1313fd4e5da5Sopenharmony_ci ApplyAndCheckFreshIds(transformation2, context.get(), 1314fd4e5da5Sopenharmony_ci &transformation_context); 1315fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 1316fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 1317fd4e5da5Sopenharmony_ci 1318fd4e5da5Sopenharmony_ci std::string after_transformation = R"( 1319fd4e5da5Sopenharmony_ci OpCapability Shader 1320fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 1321fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1322fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %12 "main" 1323fd4e5da5Sopenharmony_ci OpExecutionMode %12 OriginUpperLeft 1324fd4e5da5Sopenharmony_ci OpSource ESSL 310 1325fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 1326fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 1327fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 1328fd4e5da5Sopenharmony_ci %113 = OpConstant %6 24 1329fd4e5da5Sopenharmony_ci %12 = OpFunction %2 None %3 1330fd4e5da5Sopenharmony_ci %13 = OpLabel 1331fd4e5da5Sopenharmony_ci %522 = OpISub %6 %113 %113 1332fd4e5da5Sopenharmony_ci %570 = OpIAdd %6 %522 %113 1333fd4e5da5Sopenharmony_ci OpReturn 1334fd4e5da5Sopenharmony_ci OpFunctionEnd 1335fd4e5da5Sopenharmony_ci )"; 1336fd4e5da5Sopenharmony_ci 1337fd4e5da5Sopenharmony_ci ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous( 1338fd4e5da5Sopenharmony_ci MakeDataDescriptor(570, {}), MakeDataDescriptor(113, {}))); 1339fd4e5da5Sopenharmony_ci 1340fd4e5da5Sopenharmony_ci ASSERT_TRUE(IsEqual(env, after_transformation, context.get())); 1341fd4e5da5Sopenharmony_ci} 1342fd4e5da5Sopenharmony_ci 1343fd4e5da5Sopenharmony_ciTEST(TransformationEquationInstructionTest, ConversionInstructions) { 1344fd4e5da5Sopenharmony_ci std::string shader = R"( 1345fd4e5da5Sopenharmony_ci OpCapability Shader 1346fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 1347fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1348fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %12 "main" 1349fd4e5da5Sopenharmony_ci OpExecutionMode %12 OriginUpperLeft 1350fd4e5da5Sopenharmony_ci OpSource ESSL 310 1351fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 1352fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 1353fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 1354fd4e5da5Sopenharmony_ci %4 = OpTypeInt 32 0 1355fd4e5da5Sopenharmony_ci %5 = OpTypeFloat 32 1356fd4e5da5Sopenharmony_ci %7 = OpTypeVector %6 3 1357fd4e5da5Sopenharmony_ci %8 = OpTypeVector %4 3 1358fd4e5da5Sopenharmony_ci %9 = OpTypeVector %5 3 1359fd4e5da5Sopenharmony_ci %10 = OpConstant %6 12 1360fd4e5da5Sopenharmony_ci %20 = OpConstant %6 12 1361fd4e5da5Sopenharmony_ci %11 = OpConstant %4 12 1362fd4e5da5Sopenharmony_ci %21 = OpConstant %4 12 1363fd4e5da5Sopenharmony_ci %14 = OpConstant %5 12 1364fd4e5da5Sopenharmony_ci %15 = OpConstantComposite %7 %10 %10 %10 1365fd4e5da5Sopenharmony_ci %18 = OpConstantComposite %7 %10 %10 %10 1366fd4e5da5Sopenharmony_ci %16 = OpConstantComposite %8 %11 %11 %11 1367fd4e5da5Sopenharmony_ci %19 = OpConstantComposite %8 %11 %11 %11 1368fd4e5da5Sopenharmony_ci %17 = OpConstantComposite %9 %14 %14 %14 1369fd4e5da5Sopenharmony_ci %12 = OpFunction %2 None %3 1370fd4e5da5Sopenharmony_ci %13 = OpLabel 1371fd4e5da5Sopenharmony_ci OpReturn 1372fd4e5da5Sopenharmony_ci OpFunctionEnd 1373fd4e5da5Sopenharmony_ci )"; 1374fd4e5da5Sopenharmony_ci 1375fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 1376fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 1377fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); 1378fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 1379fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 1380fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 1381fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 1382fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(context.get()), validator_options); 1383fd4e5da5Sopenharmony_ci protobufs::InstructionDescriptor return_instruction = 1384fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(13, spv::Op::OpReturn, 0); 1385fd4e5da5Sopenharmony_ci 1386fd4e5da5Sopenharmony_ci // Too few instruction operands. 1387fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationEquationInstruction(50, spv::Op::OpConvertSToF, {}, 1388fd4e5da5Sopenharmony_ci return_instruction) 1389fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 1390fd4e5da5Sopenharmony_ci 1391fd4e5da5Sopenharmony_ci // Too many instruction operands. 1392fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationEquationInstruction(50, spv::Op::OpConvertSToF, 1393fd4e5da5Sopenharmony_ci {15, 16}, return_instruction) 1394fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 1395fd4e5da5Sopenharmony_ci 1396fd4e5da5Sopenharmony_ci // Operand has no type id. 1397fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationEquationInstruction(50, spv::Op::OpConvertSToF, 1398fd4e5da5Sopenharmony_ci {7}, return_instruction) 1399fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 1400fd4e5da5Sopenharmony_ci 1401fd4e5da5Sopenharmony_ci // OpConvertSToF and OpConvertUToF require an operand to have scalar or vector 1402fd4e5da5Sopenharmony_ci // of integral components type. 1403fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationEquationInstruction(50, spv::Op::OpConvertSToF, 1404fd4e5da5Sopenharmony_ci {17}, return_instruction) 1405fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 1406fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationEquationInstruction(50, spv::Op::OpConvertSToF, 1407fd4e5da5Sopenharmony_ci {14}, return_instruction) 1408fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 1409fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationEquationInstruction(50, spv::Op::OpConvertUToF, 1410fd4e5da5Sopenharmony_ci {17}, return_instruction) 1411fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 1412fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationEquationInstruction(50, spv::Op::OpConvertUToF, 1413fd4e5da5Sopenharmony_ci {14}, return_instruction) 1414fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 1415fd4e5da5Sopenharmony_ci 1416fd4e5da5Sopenharmony_ci { 1417fd4e5da5Sopenharmony_ci TransformationEquationInstruction transformation(50, spv::Op::OpConvertSToF, 1418fd4e5da5Sopenharmony_ci {15}, return_instruction); 1419fd4e5da5Sopenharmony_ci ASSERT_TRUE( 1420fd4e5da5Sopenharmony_ci transformation.IsApplicable(context.get(), transformation_context)); 1421fd4e5da5Sopenharmony_ci ApplyAndCheckFreshIds(transformation, context.get(), 1422fd4e5da5Sopenharmony_ci &transformation_context); 1423fd4e5da5Sopenharmony_ci } 1424fd4e5da5Sopenharmony_ci { 1425fd4e5da5Sopenharmony_ci TransformationEquationInstruction transformation(51, spv::Op::OpConvertSToF, 1426fd4e5da5Sopenharmony_ci {10}, return_instruction); 1427fd4e5da5Sopenharmony_ci ASSERT_TRUE( 1428fd4e5da5Sopenharmony_ci transformation.IsApplicable(context.get(), transformation_context)); 1429fd4e5da5Sopenharmony_ci ApplyAndCheckFreshIds(transformation, context.get(), 1430fd4e5da5Sopenharmony_ci &transformation_context); 1431fd4e5da5Sopenharmony_ci } 1432fd4e5da5Sopenharmony_ci { 1433fd4e5da5Sopenharmony_ci TransformationEquationInstruction transformation(52, spv::Op::OpConvertUToF, 1434fd4e5da5Sopenharmony_ci {16}, return_instruction); 1435fd4e5da5Sopenharmony_ci ASSERT_TRUE( 1436fd4e5da5Sopenharmony_ci transformation.IsApplicable(context.get(), transformation_context)); 1437fd4e5da5Sopenharmony_ci ApplyAndCheckFreshIds(transformation, context.get(), 1438fd4e5da5Sopenharmony_ci &transformation_context); 1439fd4e5da5Sopenharmony_ci } 1440fd4e5da5Sopenharmony_ci { 1441fd4e5da5Sopenharmony_ci TransformationEquationInstruction transformation(53, spv::Op::OpConvertUToF, 1442fd4e5da5Sopenharmony_ci {11}, return_instruction); 1443fd4e5da5Sopenharmony_ci ASSERT_TRUE( 1444fd4e5da5Sopenharmony_ci transformation.IsApplicable(context.get(), transformation_context)); 1445fd4e5da5Sopenharmony_ci ApplyAndCheckFreshIds(transformation, context.get(), 1446fd4e5da5Sopenharmony_ci &transformation_context); 1447fd4e5da5Sopenharmony_ci } 1448fd4e5da5Sopenharmony_ci { 1449fd4e5da5Sopenharmony_ci TransformationEquationInstruction transformation(58, spv::Op::OpConvertSToF, 1450fd4e5da5Sopenharmony_ci {18}, return_instruction); 1451fd4e5da5Sopenharmony_ci ASSERT_TRUE( 1452fd4e5da5Sopenharmony_ci transformation.IsApplicable(context.get(), transformation_context)); 1453fd4e5da5Sopenharmony_ci ApplyAndCheckFreshIds(transformation, context.get(), 1454fd4e5da5Sopenharmony_ci &transformation_context); 1455fd4e5da5Sopenharmony_ci } 1456fd4e5da5Sopenharmony_ci { 1457fd4e5da5Sopenharmony_ci TransformationEquationInstruction transformation(59, spv::Op::OpConvertUToF, 1458fd4e5da5Sopenharmony_ci {19}, return_instruction); 1459fd4e5da5Sopenharmony_ci ASSERT_TRUE( 1460fd4e5da5Sopenharmony_ci transformation.IsApplicable(context.get(), transformation_context)); 1461fd4e5da5Sopenharmony_ci ApplyAndCheckFreshIds(transformation, context.get(), 1462fd4e5da5Sopenharmony_ci &transformation_context); 1463fd4e5da5Sopenharmony_ci } 1464fd4e5da5Sopenharmony_ci { 1465fd4e5da5Sopenharmony_ci TransformationEquationInstruction transformation(60, spv::Op::OpConvertSToF, 1466fd4e5da5Sopenharmony_ci {20}, return_instruction); 1467fd4e5da5Sopenharmony_ci ASSERT_TRUE( 1468fd4e5da5Sopenharmony_ci transformation.IsApplicable(context.get(), transformation_context)); 1469fd4e5da5Sopenharmony_ci ApplyAndCheckFreshIds(transformation, context.get(), 1470fd4e5da5Sopenharmony_ci &transformation_context); 1471fd4e5da5Sopenharmony_ci } 1472fd4e5da5Sopenharmony_ci { 1473fd4e5da5Sopenharmony_ci TransformationEquationInstruction transformation(61, spv::Op::OpConvertUToF, 1474fd4e5da5Sopenharmony_ci {21}, return_instruction); 1475fd4e5da5Sopenharmony_ci ASSERT_TRUE( 1476fd4e5da5Sopenharmony_ci transformation.IsApplicable(context.get(), transformation_context)); 1477fd4e5da5Sopenharmony_ci ApplyAndCheckFreshIds(transformation, context.get(), 1478fd4e5da5Sopenharmony_ci &transformation_context); 1479fd4e5da5Sopenharmony_ci } 1480fd4e5da5Sopenharmony_ci 1481fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 1482fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 1483fd4e5da5Sopenharmony_ci 1484fd4e5da5Sopenharmony_ci std::string after_transformations = R"( 1485fd4e5da5Sopenharmony_ci OpCapability Shader 1486fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 1487fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1488fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %12 "main" 1489fd4e5da5Sopenharmony_ci OpExecutionMode %12 OriginUpperLeft 1490fd4e5da5Sopenharmony_ci OpSource ESSL 310 1491fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 1492fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 1493fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 1494fd4e5da5Sopenharmony_ci %4 = OpTypeInt 32 0 1495fd4e5da5Sopenharmony_ci %5 = OpTypeFloat 32 1496fd4e5da5Sopenharmony_ci %7 = OpTypeVector %6 3 1497fd4e5da5Sopenharmony_ci %8 = OpTypeVector %4 3 1498fd4e5da5Sopenharmony_ci %9 = OpTypeVector %5 3 1499fd4e5da5Sopenharmony_ci %10 = OpConstant %6 12 1500fd4e5da5Sopenharmony_ci %20 = OpConstant %6 12 1501fd4e5da5Sopenharmony_ci %11 = OpConstant %4 12 1502fd4e5da5Sopenharmony_ci %21 = OpConstant %4 12 1503fd4e5da5Sopenharmony_ci %14 = OpConstant %5 12 1504fd4e5da5Sopenharmony_ci %15 = OpConstantComposite %7 %10 %10 %10 1505fd4e5da5Sopenharmony_ci %18 = OpConstantComposite %7 %10 %10 %10 1506fd4e5da5Sopenharmony_ci %16 = OpConstantComposite %8 %11 %11 %11 1507fd4e5da5Sopenharmony_ci %19 = OpConstantComposite %8 %11 %11 %11 1508fd4e5da5Sopenharmony_ci %17 = OpConstantComposite %9 %14 %14 %14 1509fd4e5da5Sopenharmony_ci %12 = OpFunction %2 None %3 1510fd4e5da5Sopenharmony_ci %13 = OpLabel 1511fd4e5da5Sopenharmony_ci %50 = OpConvertSToF %9 %15 1512fd4e5da5Sopenharmony_ci %51 = OpConvertSToF %5 %10 1513fd4e5da5Sopenharmony_ci %52 = OpConvertUToF %9 %16 1514fd4e5da5Sopenharmony_ci %53 = OpConvertUToF %5 %11 1515fd4e5da5Sopenharmony_ci %58 = OpConvertSToF %9 %18 1516fd4e5da5Sopenharmony_ci %59 = OpConvertUToF %9 %19 1517fd4e5da5Sopenharmony_ci %60 = OpConvertSToF %5 %20 1518fd4e5da5Sopenharmony_ci %61 = OpConvertUToF %5 %21 1519fd4e5da5Sopenharmony_ci OpReturn 1520fd4e5da5Sopenharmony_ci OpFunctionEnd 1521fd4e5da5Sopenharmony_ci )"; 1522fd4e5da5Sopenharmony_ci 1523fd4e5da5Sopenharmony_ci ASSERT_TRUE(IsEqual(env, after_transformations, context.get())); 1524fd4e5da5Sopenharmony_ci} 1525fd4e5da5Sopenharmony_ci 1526fd4e5da5Sopenharmony_ciTEST(TransformationEquationInstructionTest, FloatResultTypeDoesNotExist) { 1527fd4e5da5Sopenharmony_ci std::string shader = R"( 1528fd4e5da5Sopenharmony_ci OpCapability Shader 1529fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 1530fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1531fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %12 "main" 1532fd4e5da5Sopenharmony_ci OpExecutionMode %12 OriginUpperLeft 1533fd4e5da5Sopenharmony_ci OpSource ESSL 310 1534fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 1535fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 1536fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 0 1537fd4e5da5Sopenharmony_ci %7 = OpTypeInt 32 1 1538fd4e5da5Sopenharmony_ci %8 = OpTypeVector %6 3 1539fd4e5da5Sopenharmony_ci %9 = OpTypeVector %7 3 1540fd4e5da5Sopenharmony_ci %10 = OpConstant %6 24 1541fd4e5da5Sopenharmony_ci %11 = OpConstant %7 25 1542fd4e5da5Sopenharmony_ci %14 = OpConstantComposite %8 %10 %10 %10 1543fd4e5da5Sopenharmony_ci %15 = OpConstantComposite %9 %11 %11 %11 1544fd4e5da5Sopenharmony_ci %12 = OpFunction %2 None %3 1545fd4e5da5Sopenharmony_ci %13 = OpLabel 1546fd4e5da5Sopenharmony_ci OpReturn 1547fd4e5da5Sopenharmony_ci OpFunctionEnd 1548fd4e5da5Sopenharmony_ci )"; 1549fd4e5da5Sopenharmony_ci 1550fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 1551fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 1552fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); 1553fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 1554fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 1555fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 1556fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 1557fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(context.get()), validator_options); 1558fd4e5da5Sopenharmony_ci protobufs::InstructionDescriptor return_instruction = 1559fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(13, spv::Op::OpReturn, 0); 1560fd4e5da5Sopenharmony_ci 1561fd4e5da5Sopenharmony_ci // Scalar float type doesn't exist. 1562fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationEquationInstruction(16, spv::Op::OpConvertUToF, 1563fd4e5da5Sopenharmony_ci {10}, return_instruction) 1564fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 1565fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationEquationInstruction(16, spv::Op::OpConvertSToF, 1566fd4e5da5Sopenharmony_ci {11}, return_instruction) 1567fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 1568fd4e5da5Sopenharmony_ci 1569fd4e5da5Sopenharmony_ci // Vector float type doesn't exist. 1570fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationEquationInstruction(16, spv::Op::OpConvertUToF, 1571fd4e5da5Sopenharmony_ci {14}, return_instruction) 1572fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 1573fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationEquationInstruction(16, spv::Op::OpConvertSToF, 1574fd4e5da5Sopenharmony_ci {15}, return_instruction) 1575fd4e5da5Sopenharmony_ci .IsApplicable(context.get(), transformation_context)); 1576fd4e5da5Sopenharmony_ci} 1577fd4e5da5Sopenharmony_ci 1578fd4e5da5Sopenharmony_ciTEST(TransformationEquationInstructionTest, HandlesIrrelevantIds) { 1579fd4e5da5Sopenharmony_ci std::string shader = R"( 1580fd4e5da5Sopenharmony_ci OpCapability Shader 1581fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 1582fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1583fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %12 "main" 1584fd4e5da5Sopenharmony_ci OpExecutionMode %12 OriginUpperLeft 1585fd4e5da5Sopenharmony_ci OpSource ESSL 310 1586fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 1587fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 1588fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 1589fd4e5da5Sopenharmony_ci %30 = OpTypeVector %6 3 1590fd4e5da5Sopenharmony_ci %15 = OpConstant %6 24 1591fd4e5da5Sopenharmony_ci %16 = OpConstant %6 37 1592fd4e5da5Sopenharmony_ci %31 = OpConstantComposite %30 %15 %16 %15 1593fd4e5da5Sopenharmony_ci %33 = OpTypeBool 1594fd4e5da5Sopenharmony_ci %32 = OpConstantTrue %33 1595fd4e5da5Sopenharmony_ci %12 = OpFunction %2 None %3 1596fd4e5da5Sopenharmony_ci %13 = OpLabel 1597fd4e5da5Sopenharmony_ci OpReturn 1598fd4e5da5Sopenharmony_ci OpFunctionEnd 1599fd4e5da5Sopenharmony_ci )"; 1600fd4e5da5Sopenharmony_ci 1601fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 1602fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 1603fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); 1604fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 1605fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 1606fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 1607fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 1608fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(context.get()), validator_options); 1609fd4e5da5Sopenharmony_ci auto return_instruction = MakeInstructionDescriptor(13, spv::Op::OpReturn, 0); 1610fd4e5da5Sopenharmony_ci 1611fd4e5da5Sopenharmony_ci // Applicable. 1612fd4e5da5Sopenharmony_ci TransformationEquationInstruction transformation( 1613fd4e5da5Sopenharmony_ci 14, spv::Op::OpIAdd, {15, 16}, return_instruction); 1614fd4e5da5Sopenharmony_ci ASSERT_TRUE( 1615fd4e5da5Sopenharmony_ci transformation.IsApplicable(context.get(), transformation_context)); 1616fd4e5da5Sopenharmony_ci 1617fd4e5da5Sopenharmony_ci // Handles irrelevant ids. 1618fd4e5da5Sopenharmony_ci transformation_context.GetFactManager()->AddFactIdIsIrrelevant(16); 1619fd4e5da5Sopenharmony_ci ASSERT_FALSE( 1620fd4e5da5Sopenharmony_ci transformation.IsApplicable(context.get(), transformation_context)); 1621fd4e5da5Sopenharmony_ci transformation_context.GetFactManager()->AddFactIdIsIrrelevant(15); 1622fd4e5da5Sopenharmony_ci ASSERT_FALSE( 1623fd4e5da5Sopenharmony_ci transformation.IsApplicable(context.get(), transformation_context)); 1624fd4e5da5Sopenharmony_ci} 1625fd4e5da5Sopenharmony_ci 1626fd4e5da5Sopenharmony_ciTEST(TransformationEquationInstructionTest, HandlesDeadBlock) { 1627fd4e5da5Sopenharmony_ci std::string shader = R"( 1628fd4e5da5Sopenharmony_ci OpCapability Shader 1629fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 1630fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1631fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %12 "main" 1632fd4e5da5Sopenharmony_ci OpExecutionMode %12 OriginUpperLeft 1633fd4e5da5Sopenharmony_ci OpSource ESSL 310 1634fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 1635fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 1636fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 1637fd4e5da5Sopenharmony_ci %30 = OpTypeVector %6 3 1638fd4e5da5Sopenharmony_ci %15 = OpConstant %6 24 1639fd4e5da5Sopenharmony_ci %16 = OpConstant %6 37 1640fd4e5da5Sopenharmony_ci %31 = OpConstantComposite %30 %15 %16 %15 1641fd4e5da5Sopenharmony_ci %33 = OpTypeBool 1642fd4e5da5Sopenharmony_ci %32 = OpConstantTrue %33 1643fd4e5da5Sopenharmony_ci %12 = OpFunction %2 None %3 1644fd4e5da5Sopenharmony_ci %13 = OpLabel 1645fd4e5da5Sopenharmony_ci OpSelectionMerge %40 None 1646fd4e5da5Sopenharmony_ci OpBranchConditional %32 %40 %41 1647fd4e5da5Sopenharmony_ci %41 = OpLabel 1648fd4e5da5Sopenharmony_ci OpBranch %40 1649fd4e5da5Sopenharmony_ci %40 = OpLabel 1650fd4e5da5Sopenharmony_ci OpReturn 1651fd4e5da5Sopenharmony_ci OpFunctionEnd 1652fd4e5da5Sopenharmony_ci )"; 1653fd4e5da5Sopenharmony_ci 1654fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 1655fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 1656fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); 1657fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 1658fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 1659fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 1660fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 1661fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(context.get()), validator_options); 1662fd4e5da5Sopenharmony_ci 1663fd4e5da5Sopenharmony_ci transformation_context.GetFactManager()->AddFactBlockIsDead(41); 1664fd4e5da5Sopenharmony_ci 1665fd4e5da5Sopenharmony_ci TransformationEquationInstruction transformation1( 1666fd4e5da5Sopenharmony_ci 14, spv::Op::OpIAdd, {15, 16}, 1667fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(13, spv::Op::OpSelectionMerge, 0)); 1668fd4e5da5Sopenharmony_ci // No synonym is created since block is dead. 1669fd4e5da5Sopenharmony_ci TransformationEquationInstruction transformation2( 1670fd4e5da5Sopenharmony_ci 100, spv::Op::OpISub, {14, 16}, 1671fd4e5da5Sopenharmony_ci MakeInstructionDescriptor(41, spv::Op::OpBranch, 0)); 1672fd4e5da5Sopenharmony_ci ASSERT_TRUE( 1673fd4e5da5Sopenharmony_ci transformation1.IsApplicable(context.get(), transformation_context)); 1674fd4e5da5Sopenharmony_ci ApplyAndCheckFreshIds(transformation1, context.get(), 1675fd4e5da5Sopenharmony_ci &transformation_context); 1676fd4e5da5Sopenharmony_ci ASSERT_TRUE( 1677fd4e5da5Sopenharmony_ci transformation2.IsApplicable(context.get(), transformation_context)); 1678fd4e5da5Sopenharmony_ci ApplyAndCheckFreshIds(transformation2, context.get(), 1679fd4e5da5Sopenharmony_ci &transformation_context); 1680fd4e5da5Sopenharmony_ci ASSERT_FALSE(transformation_context.GetFactManager()->IsSynonymous( 1681fd4e5da5Sopenharmony_ci MakeDataDescriptor(100, {}), MakeDataDescriptor(15, {}))); 1682fd4e5da5Sopenharmony_ci} 1683fd4e5da5Sopenharmony_ci 1684fd4e5da5Sopenharmony_ci} // namespace 1685fd4e5da5Sopenharmony_ci} // namespace fuzz 1686fd4e5da5Sopenharmony_ci} // namespace spvtools 1687