1fd4e5da5Sopenharmony_ci// Copyright (c) 2019 Google LLC 2fd4e5da5Sopenharmony_ci// 3fd4e5da5Sopenharmony_ci// Licensed under the Apache License, Version 2.0 (the "License"); 4fd4e5da5Sopenharmony_ci// you may not use this file except in compliance with the License. 5fd4e5da5Sopenharmony_ci// You may obtain a copy of the License at 6fd4e5da5Sopenharmony_ci// 7fd4e5da5Sopenharmony_ci// http://www.apache.org/licenses/LICENSE-2.0 8fd4e5da5Sopenharmony_ci// 9fd4e5da5Sopenharmony_ci// Unless required by applicable law or agreed to in writing, software 10fd4e5da5Sopenharmony_ci// distributed under the License is distributed on an "AS IS" BASIS, 11fd4e5da5Sopenharmony_ci// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12fd4e5da5Sopenharmony_ci// See the License for the specific language governing permissions and 13fd4e5da5Sopenharmony_ci// limitations under the License. 14fd4e5da5Sopenharmony_ci 15fd4e5da5Sopenharmony_ci#include "source/fuzz/transformation_merge_blocks.h" 16fd4e5da5Sopenharmony_ci 17fd4e5da5Sopenharmony_ci#include "gtest/gtest.h" 18fd4e5da5Sopenharmony_ci#include "source/fuzz/fuzzer_util.h" 19fd4e5da5Sopenharmony_ci#include "test/fuzz/fuzz_test_util.h" 20fd4e5da5Sopenharmony_ci 21fd4e5da5Sopenharmony_cinamespace spvtools { 22fd4e5da5Sopenharmony_cinamespace fuzz { 23fd4e5da5Sopenharmony_cinamespace { 24fd4e5da5Sopenharmony_ci 25fd4e5da5Sopenharmony_ciTEST(TransformationMergeBlocksTest, BlockDoesNotExist) { 26fd4e5da5Sopenharmony_ci std::string shader = R"( 27fd4e5da5Sopenharmony_ci OpCapability Shader 28fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 29fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 30fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 31fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 32fd4e5da5Sopenharmony_ci OpSource ESSL 310 33fd4e5da5Sopenharmony_ci OpName %4 "main" 34fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 35fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 36fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 37fd4e5da5Sopenharmony_ci %5 = OpLabel 38fd4e5da5Sopenharmony_ci OpBranch %6 39fd4e5da5Sopenharmony_ci %6 = OpLabel 40fd4e5da5Sopenharmony_ci OpReturn 41fd4e5da5Sopenharmony_ci OpFunctionEnd 42fd4e5da5Sopenharmony_ci )"; 43fd4e5da5Sopenharmony_ci 44fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_4; 45fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 46fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); 47fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 48fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 49fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 50fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 51fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(context.get()), validator_options); 52fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationMergeBlocks(3).IsApplicable( 53fd4e5da5Sopenharmony_ci context.get(), transformation_context)); 54fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationMergeBlocks(7).IsApplicable( 55fd4e5da5Sopenharmony_ci context.get(), transformation_context)); 56fd4e5da5Sopenharmony_ci} 57fd4e5da5Sopenharmony_ci 58fd4e5da5Sopenharmony_ciTEST(TransformationMergeBlocksTest, DoNotMergeFirstBlockHasMultipleSuccessors) { 59fd4e5da5Sopenharmony_ci std::string shader = R"( 60fd4e5da5Sopenharmony_ci OpCapability Shader 61fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 62fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 63fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 64fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 65fd4e5da5Sopenharmony_ci OpSource ESSL 310 66fd4e5da5Sopenharmony_ci OpName %4 "main" 67fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 68fd4e5da5Sopenharmony_ci %7 = OpTypeBool 69fd4e5da5Sopenharmony_ci %8 = OpConstantTrue %7 70fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 71fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 72fd4e5da5Sopenharmony_ci %5 = OpLabel 73fd4e5da5Sopenharmony_ci OpSelectionMerge %10 None 74fd4e5da5Sopenharmony_ci OpBranchConditional %8 %6 %9 75fd4e5da5Sopenharmony_ci %6 = OpLabel 76fd4e5da5Sopenharmony_ci OpBranch %10 77fd4e5da5Sopenharmony_ci %9 = OpLabel 78fd4e5da5Sopenharmony_ci OpBranch %10 79fd4e5da5Sopenharmony_ci %10 = OpLabel 80fd4e5da5Sopenharmony_ci OpReturn 81fd4e5da5Sopenharmony_ci OpFunctionEnd 82fd4e5da5Sopenharmony_ci )"; 83fd4e5da5Sopenharmony_ci 84fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_4; 85fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 86fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); 87fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 88fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 89fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 90fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 91fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(context.get()), validator_options); 92fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationMergeBlocks(6).IsApplicable( 93fd4e5da5Sopenharmony_ci context.get(), transformation_context)); 94fd4e5da5Sopenharmony_ci} 95fd4e5da5Sopenharmony_ci 96fd4e5da5Sopenharmony_ciTEST(TransformationMergeBlocksTest, 97fd4e5da5Sopenharmony_ci DoNotMergeSecondBlockHasMultiplePredecessors) { 98fd4e5da5Sopenharmony_ci std::string shader = R"( 99fd4e5da5Sopenharmony_ci OpCapability Shader 100fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 101fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 102fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 103fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 104fd4e5da5Sopenharmony_ci OpSource ESSL 310 105fd4e5da5Sopenharmony_ci OpName %4 "main" 106fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 107fd4e5da5Sopenharmony_ci %7 = OpTypeBool 108fd4e5da5Sopenharmony_ci %8 = OpConstantTrue %7 109fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 110fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 111fd4e5da5Sopenharmony_ci %5 = OpLabel 112fd4e5da5Sopenharmony_ci OpSelectionMerge %10 None 113fd4e5da5Sopenharmony_ci OpBranchConditional %8 %6 %9 114fd4e5da5Sopenharmony_ci %6 = OpLabel 115fd4e5da5Sopenharmony_ci OpBranch %10 116fd4e5da5Sopenharmony_ci %9 = OpLabel 117fd4e5da5Sopenharmony_ci OpBranch %10 118fd4e5da5Sopenharmony_ci %10 = OpLabel 119fd4e5da5Sopenharmony_ci OpReturn 120fd4e5da5Sopenharmony_ci OpFunctionEnd 121fd4e5da5Sopenharmony_ci )"; 122fd4e5da5Sopenharmony_ci 123fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_4; 124fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 125fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); 126fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 127fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 128fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 129fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 130fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(context.get()), validator_options); 131fd4e5da5Sopenharmony_ci ASSERT_FALSE(TransformationMergeBlocks(10).IsApplicable( 132fd4e5da5Sopenharmony_ci context.get(), transformation_context)); 133fd4e5da5Sopenharmony_ci} 134fd4e5da5Sopenharmony_ci 135fd4e5da5Sopenharmony_ciTEST(TransformationMergeBlocksTest, MergeWhenSecondBlockIsSelectionMerge) { 136fd4e5da5Sopenharmony_ci std::string shader = R"( 137fd4e5da5Sopenharmony_ci OpCapability Shader 138fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 139fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 140fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 141fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 142fd4e5da5Sopenharmony_ci OpSource ESSL 310 143fd4e5da5Sopenharmony_ci OpName %4 "main" 144fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 145fd4e5da5Sopenharmony_ci %7 = OpTypeBool 146fd4e5da5Sopenharmony_ci %8 = OpConstantTrue %7 147fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 148fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 149fd4e5da5Sopenharmony_ci %5 = OpLabel 150fd4e5da5Sopenharmony_ci OpSelectionMerge %10 None 151fd4e5da5Sopenharmony_ci OpBranchConditional %8 %6 %9 152fd4e5da5Sopenharmony_ci %6 = OpLabel 153fd4e5da5Sopenharmony_ci OpBranch %11 154fd4e5da5Sopenharmony_ci %9 = OpLabel 155fd4e5da5Sopenharmony_ci OpBranch %11 156fd4e5da5Sopenharmony_ci %11 = OpLabel 157fd4e5da5Sopenharmony_ci OpBranch %10 158fd4e5da5Sopenharmony_ci %10 = OpLabel 159fd4e5da5Sopenharmony_ci OpReturn 160fd4e5da5Sopenharmony_ci OpFunctionEnd 161fd4e5da5Sopenharmony_ci )"; 162fd4e5da5Sopenharmony_ci 163fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_4; 164fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 165fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); 166fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 167fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 168fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 169fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 170fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(context.get()), validator_options); 171fd4e5da5Sopenharmony_ci TransformationMergeBlocks transformation(10); 172fd4e5da5Sopenharmony_ci ASSERT_TRUE( 173fd4e5da5Sopenharmony_ci transformation.IsApplicable(context.get(), transformation_context)); 174fd4e5da5Sopenharmony_ci ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); 175fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 176fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 177fd4e5da5Sopenharmony_ci 178fd4e5da5Sopenharmony_ci std::string after_transformation = R"( 179fd4e5da5Sopenharmony_ci OpCapability Shader 180fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 181fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 182fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 183fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 184fd4e5da5Sopenharmony_ci OpSource ESSL 310 185fd4e5da5Sopenharmony_ci OpName %4 "main" 186fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 187fd4e5da5Sopenharmony_ci %7 = OpTypeBool 188fd4e5da5Sopenharmony_ci %8 = OpConstantTrue %7 189fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 190fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 191fd4e5da5Sopenharmony_ci %5 = OpLabel 192fd4e5da5Sopenharmony_ci OpSelectionMerge %11 None 193fd4e5da5Sopenharmony_ci OpBranchConditional %8 %6 %9 194fd4e5da5Sopenharmony_ci %6 = OpLabel 195fd4e5da5Sopenharmony_ci OpBranch %11 196fd4e5da5Sopenharmony_ci %9 = OpLabel 197fd4e5da5Sopenharmony_ci OpBranch %11 198fd4e5da5Sopenharmony_ci %11 = OpLabel 199fd4e5da5Sopenharmony_ci OpReturn 200fd4e5da5Sopenharmony_ci OpFunctionEnd 201fd4e5da5Sopenharmony_ci )"; 202fd4e5da5Sopenharmony_ci 203fd4e5da5Sopenharmony_ci ASSERT_TRUE(IsEqual(env, after_transformation, context.get())); 204fd4e5da5Sopenharmony_ci} 205fd4e5da5Sopenharmony_ci 206fd4e5da5Sopenharmony_ciTEST(TransformationMergeBlocksTest, MergeWhenSecondBlockIsLoopMerge) { 207fd4e5da5Sopenharmony_ci std::string shader = R"( 208fd4e5da5Sopenharmony_ci OpCapability Shader 209fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 210fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 211fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 212fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 213fd4e5da5Sopenharmony_ci OpSource ESSL 310 214fd4e5da5Sopenharmony_ci OpName %4 "main" 215fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 216fd4e5da5Sopenharmony_ci %7 = OpTypeBool 217fd4e5da5Sopenharmony_ci %8 = OpConstantTrue %7 218fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 219fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 220fd4e5da5Sopenharmony_ci %12 = OpLabel 221fd4e5da5Sopenharmony_ci OpBranch %5 222fd4e5da5Sopenharmony_ci %5 = OpLabel 223fd4e5da5Sopenharmony_ci OpLoopMerge %10 %11 None 224fd4e5da5Sopenharmony_ci OpBranch %6 225fd4e5da5Sopenharmony_ci %6 = OpLabel 226fd4e5da5Sopenharmony_ci OpBranchConditional %8 %9 %11 227fd4e5da5Sopenharmony_ci %9 = OpLabel 228fd4e5da5Sopenharmony_ci OpBranch %10 229fd4e5da5Sopenharmony_ci %11 = OpLabel 230fd4e5da5Sopenharmony_ci OpBranch %5 231fd4e5da5Sopenharmony_ci %10 = OpLabel 232fd4e5da5Sopenharmony_ci OpReturn 233fd4e5da5Sopenharmony_ci OpFunctionEnd 234fd4e5da5Sopenharmony_ci )"; 235fd4e5da5Sopenharmony_ci 236fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_4; 237fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 238fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); 239fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 240fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 241fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 242fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 243fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(context.get()), validator_options); 244fd4e5da5Sopenharmony_ci TransformationMergeBlocks transformation(10); 245fd4e5da5Sopenharmony_ci ASSERT_TRUE( 246fd4e5da5Sopenharmony_ci transformation.IsApplicable(context.get(), transformation_context)); 247fd4e5da5Sopenharmony_ci ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); 248fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 249fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 250fd4e5da5Sopenharmony_ci 251fd4e5da5Sopenharmony_ci std::string after_transformation = R"( 252fd4e5da5Sopenharmony_ci OpCapability Shader 253fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 254fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 255fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 256fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 257fd4e5da5Sopenharmony_ci OpSource ESSL 310 258fd4e5da5Sopenharmony_ci OpName %4 "main" 259fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 260fd4e5da5Sopenharmony_ci %7 = OpTypeBool 261fd4e5da5Sopenharmony_ci %8 = OpConstantTrue %7 262fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 263fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 264fd4e5da5Sopenharmony_ci %12 = OpLabel 265fd4e5da5Sopenharmony_ci OpBranch %5 266fd4e5da5Sopenharmony_ci %5 = OpLabel 267fd4e5da5Sopenharmony_ci OpLoopMerge %9 %11 None 268fd4e5da5Sopenharmony_ci OpBranch %6 269fd4e5da5Sopenharmony_ci %6 = OpLabel 270fd4e5da5Sopenharmony_ci OpBranchConditional %8 %9 %11 271fd4e5da5Sopenharmony_ci %9 = OpLabel 272fd4e5da5Sopenharmony_ci OpReturn 273fd4e5da5Sopenharmony_ci %11 = OpLabel 274fd4e5da5Sopenharmony_ci OpBranch %5 275fd4e5da5Sopenharmony_ci OpFunctionEnd 276fd4e5da5Sopenharmony_ci )"; 277fd4e5da5Sopenharmony_ci 278fd4e5da5Sopenharmony_ci ASSERT_TRUE(IsEqual(env, after_transformation, context.get())); 279fd4e5da5Sopenharmony_ci} 280fd4e5da5Sopenharmony_ci 281fd4e5da5Sopenharmony_ciTEST(TransformationMergeBlocksTest, MergeWhenSecondBlockIsLoopContinue) { 282fd4e5da5Sopenharmony_ci std::string shader = R"( 283fd4e5da5Sopenharmony_ci OpCapability Shader 284fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 285fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 286fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 287fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 288fd4e5da5Sopenharmony_ci OpSource ESSL 310 289fd4e5da5Sopenharmony_ci OpName %4 "main" 290fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 291fd4e5da5Sopenharmony_ci %7 = OpTypeBool 292fd4e5da5Sopenharmony_ci %8 = OpConstantTrue %7 293fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 294fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 295fd4e5da5Sopenharmony_ci %13 = OpLabel 296fd4e5da5Sopenharmony_ci OpBranch %5 297fd4e5da5Sopenharmony_ci %5 = OpLabel 298fd4e5da5Sopenharmony_ci OpLoopMerge %10 %11 None 299fd4e5da5Sopenharmony_ci OpBranch %6 300fd4e5da5Sopenharmony_ci %6 = OpLabel 301fd4e5da5Sopenharmony_ci OpSelectionMerge %9 None 302fd4e5da5Sopenharmony_ci OpBranchConditional %8 %9 %12 303fd4e5da5Sopenharmony_ci %12 = OpLabel 304fd4e5da5Sopenharmony_ci OpBranch %11 305fd4e5da5Sopenharmony_ci %11 = OpLabel 306fd4e5da5Sopenharmony_ci OpBranch %5 307fd4e5da5Sopenharmony_ci %9 = OpLabel 308fd4e5da5Sopenharmony_ci OpBranch %10 309fd4e5da5Sopenharmony_ci %10 = OpLabel 310fd4e5da5Sopenharmony_ci OpReturn 311fd4e5da5Sopenharmony_ci OpFunctionEnd 312fd4e5da5Sopenharmony_ci )"; 313fd4e5da5Sopenharmony_ci 314fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_4; 315fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 316fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); 317fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 318fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 319fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 320fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 321fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(context.get()), validator_options); 322fd4e5da5Sopenharmony_ci TransformationMergeBlocks transformation(11); 323fd4e5da5Sopenharmony_ci ASSERT_TRUE( 324fd4e5da5Sopenharmony_ci transformation.IsApplicable(context.get(), transformation_context)); 325fd4e5da5Sopenharmony_ci ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); 326fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 327fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 328fd4e5da5Sopenharmony_ci 329fd4e5da5Sopenharmony_ci std::string after_transformation = R"( 330fd4e5da5Sopenharmony_ci OpCapability Shader 331fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 332fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 333fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 334fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 335fd4e5da5Sopenharmony_ci OpSource ESSL 310 336fd4e5da5Sopenharmony_ci OpName %4 "main" 337fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 338fd4e5da5Sopenharmony_ci %7 = OpTypeBool 339fd4e5da5Sopenharmony_ci %8 = OpConstantTrue %7 340fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 341fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 342fd4e5da5Sopenharmony_ci %13 = OpLabel 343fd4e5da5Sopenharmony_ci OpBranch %5 344fd4e5da5Sopenharmony_ci %5 = OpLabel 345fd4e5da5Sopenharmony_ci OpLoopMerge %10 %12 None 346fd4e5da5Sopenharmony_ci OpBranch %6 347fd4e5da5Sopenharmony_ci %6 = OpLabel 348fd4e5da5Sopenharmony_ci OpSelectionMerge %9 None 349fd4e5da5Sopenharmony_ci OpBranchConditional %8 %9 %12 350fd4e5da5Sopenharmony_ci %12 = OpLabel 351fd4e5da5Sopenharmony_ci OpBranch %5 352fd4e5da5Sopenharmony_ci %9 = OpLabel 353fd4e5da5Sopenharmony_ci OpBranch %10 354fd4e5da5Sopenharmony_ci %10 = OpLabel 355fd4e5da5Sopenharmony_ci OpReturn 356fd4e5da5Sopenharmony_ci OpFunctionEnd 357fd4e5da5Sopenharmony_ci )"; 358fd4e5da5Sopenharmony_ci 359fd4e5da5Sopenharmony_ci ASSERT_TRUE(IsEqual(env, after_transformation, context.get())); 360fd4e5da5Sopenharmony_ci} 361fd4e5da5Sopenharmony_ci 362fd4e5da5Sopenharmony_ciTEST(TransformationMergeBlocksTest, MergeWhenSecondBlockStartsWithOpPhi) { 363fd4e5da5Sopenharmony_ci std::string shader = R"( 364fd4e5da5Sopenharmony_ci OpCapability Shader 365fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 366fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 367fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 368fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 369fd4e5da5Sopenharmony_ci OpSource ESSL 310 370fd4e5da5Sopenharmony_ci OpName %4 "main" 371fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 372fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 373fd4e5da5Sopenharmony_ci %7 = OpTypeBool 374fd4e5da5Sopenharmony_ci %8 = OpUndef %7 375fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 376fd4e5da5Sopenharmony_ci %5 = OpLabel 377fd4e5da5Sopenharmony_ci OpBranch %6 378fd4e5da5Sopenharmony_ci %6 = OpLabel 379fd4e5da5Sopenharmony_ci %9 = OpPhi %7 %8 %5 380fd4e5da5Sopenharmony_ci %10 = OpCopyObject %7 %9 381fd4e5da5Sopenharmony_ci OpBranch %11 382fd4e5da5Sopenharmony_ci %11 = OpLabel 383fd4e5da5Sopenharmony_ci %12 = OpCopyObject %7 %9 384fd4e5da5Sopenharmony_ci OpReturn 385fd4e5da5Sopenharmony_ci OpFunctionEnd 386fd4e5da5Sopenharmony_ci )"; 387fd4e5da5Sopenharmony_ci 388fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_4; 389fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 390fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); 391fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 392fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 393fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 394fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 395fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(context.get()), validator_options); 396fd4e5da5Sopenharmony_ci TransformationMergeBlocks transformation(6); 397fd4e5da5Sopenharmony_ci ASSERT_TRUE( 398fd4e5da5Sopenharmony_ci transformation.IsApplicable(context.get(), transformation_context)); 399fd4e5da5Sopenharmony_ci ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); 400fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 401fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 402fd4e5da5Sopenharmony_ci 403fd4e5da5Sopenharmony_ci std::string after_transformation = R"( 404fd4e5da5Sopenharmony_ci OpCapability Shader 405fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 406fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 407fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 408fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 409fd4e5da5Sopenharmony_ci OpSource ESSL 310 410fd4e5da5Sopenharmony_ci OpName %4 "main" 411fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 412fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 413fd4e5da5Sopenharmony_ci %7 = OpTypeBool 414fd4e5da5Sopenharmony_ci %8 = OpUndef %7 415fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 416fd4e5da5Sopenharmony_ci %5 = OpLabel 417fd4e5da5Sopenharmony_ci %10 = OpCopyObject %7 %8 418fd4e5da5Sopenharmony_ci OpBranch %11 419fd4e5da5Sopenharmony_ci %11 = OpLabel 420fd4e5da5Sopenharmony_ci %12 = OpCopyObject %7 %8 421fd4e5da5Sopenharmony_ci OpReturn 422fd4e5da5Sopenharmony_ci OpFunctionEnd 423fd4e5da5Sopenharmony_ci )"; 424fd4e5da5Sopenharmony_ci 425fd4e5da5Sopenharmony_ci ASSERT_TRUE(IsEqual(env, after_transformation, context.get())); 426fd4e5da5Sopenharmony_ci} 427fd4e5da5Sopenharmony_ci 428fd4e5da5Sopenharmony_ciTEST(TransformationMergeBlocksTest, BasicMerge) { 429fd4e5da5Sopenharmony_ci std::string shader = R"( 430fd4e5da5Sopenharmony_ci OpCapability Shader 431fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 432fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 433fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 434fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 435fd4e5da5Sopenharmony_ci OpSource ESSL 310 436fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 437fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 438fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 439fd4e5da5Sopenharmony_ci %7 = OpTypePointer Function %6 440fd4e5da5Sopenharmony_ci %9 = OpConstant %6 2 441fd4e5da5Sopenharmony_ci %11 = OpConstant %6 3 442fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 443fd4e5da5Sopenharmony_ci %5 = OpLabel 444fd4e5da5Sopenharmony_ci %8 = OpVariable %7 Function 445fd4e5da5Sopenharmony_ci %10 = OpVariable %7 Function 446fd4e5da5Sopenharmony_ci OpStore %8 %9 447fd4e5da5Sopenharmony_ci OpBranch %100 448fd4e5da5Sopenharmony_ci %100 = OpLabel 449fd4e5da5Sopenharmony_ci OpStore %10 %11 450fd4e5da5Sopenharmony_ci %12 = OpLoad %6 %10 451fd4e5da5Sopenharmony_ci %13 = OpLoad %6 %8 452fd4e5da5Sopenharmony_ci OpBranch %101 453fd4e5da5Sopenharmony_ci %101 = OpLabel 454fd4e5da5Sopenharmony_ci %14 = OpIAdd %6 %13 %12 455fd4e5da5Sopenharmony_ci OpStore %8 %14 456fd4e5da5Sopenharmony_ci %15 = OpLoad %6 %8 457fd4e5da5Sopenharmony_ci OpBranch %102 458fd4e5da5Sopenharmony_ci %102 = OpLabel 459fd4e5da5Sopenharmony_ci %16 = OpLoad %6 %10 460fd4e5da5Sopenharmony_ci %17 = OpIMul %6 %16 %15 461fd4e5da5Sopenharmony_ci OpBranch %103 462fd4e5da5Sopenharmony_ci %103 = OpLabel 463fd4e5da5Sopenharmony_ci OpStore %10 %17 464fd4e5da5Sopenharmony_ci OpReturn 465fd4e5da5Sopenharmony_ci OpFunctionEnd 466fd4e5da5Sopenharmony_ci )"; 467fd4e5da5Sopenharmony_ci 468fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_4; 469fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 470fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); 471fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 472fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 473fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 474fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 475fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(context.get()), validator_options); 476fd4e5da5Sopenharmony_ci for (auto& transformation : 477fd4e5da5Sopenharmony_ci {TransformationMergeBlocks(100), TransformationMergeBlocks(101), 478fd4e5da5Sopenharmony_ci TransformationMergeBlocks(102), TransformationMergeBlocks(103)}) { 479fd4e5da5Sopenharmony_ci ASSERT_TRUE( 480fd4e5da5Sopenharmony_ci transformation.IsApplicable(context.get(), transformation_context)); 481fd4e5da5Sopenharmony_ci ApplyAndCheckFreshIds(transformation, context.get(), 482fd4e5da5Sopenharmony_ci &transformation_context); 483fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed( 484fd4e5da5Sopenharmony_ci context.get(), validator_options, kConsoleMessageConsumer)); 485fd4e5da5Sopenharmony_ci } 486fd4e5da5Sopenharmony_ci 487fd4e5da5Sopenharmony_ci std::string after_transformation = R"( 488fd4e5da5Sopenharmony_ci OpCapability Shader 489fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 490fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 491fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 492fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 493fd4e5da5Sopenharmony_ci OpSource ESSL 310 494fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 495fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 496fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 497fd4e5da5Sopenharmony_ci %7 = OpTypePointer Function %6 498fd4e5da5Sopenharmony_ci %9 = OpConstant %6 2 499fd4e5da5Sopenharmony_ci %11 = OpConstant %6 3 500fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 501fd4e5da5Sopenharmony_ci %5 = OpLabel 502fd4e5da5Sopenharmony_ci %8 = OpVariable %7 Function 503fd4e5da5Sopenharmony_ci %10 = OpVariable %7 Function 504fd4e5da5Sopenharmony_ci OpStore %8 %9 505fd4e5da5Sopenharmony_ci OpStore %10 %11 506fd4e5da5Sopenharmony_ci %12 = OpLoad %6 %10 507fd4e5da5Sopenharmony_ci %13 = OpLoad %6 %8 508fd4e5da5Sopenharmony_ci %14 = OpIAdd %6 %13 %12 509fd4e5da5Sopenharmony_ci OpStore %8 %14 510fd4e5da5Sopenharmony_ci %15 = OpLoad %6 %8 511fd4e5da5Sopenharmony_ci %16 = OpLoad %6 %10 512fd4e5da5Sopenharmony_ci %17 = OpIMul %6 %16 %15 513fd4e5da5Sopenharmony_ci OpStore %10 %17 514fd4e5da5Sopenharmony_ci OpReturn 515fd4e5da5Sopenharmony_ci OpFunctionEnd 516fd4e5da5Sopenharmony_ci )"; 517fd4e5da5Sopenharmony_ci 518fd4e5da5Sopenharmony_ci ASSERT_TRUE(IsEqual(env, after_transformation, context.get())); 519fd4e5da5Sopenharmony_ci} 520fd4e5da5Sopenharmony_ci 521fd4e5da5Sopenharmony_ciTEST(TransformationMergeBlocksTest, MergeWhenSecondBlockIsSelectionHeader) { 522fd4e5da5Sopenharmony_ci std::string shader = R"( 523fd4e5da5Sopenharmony_ci OpCapability Shader 524fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 525fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 526fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 527fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 528fd4e5da5Sopenharmony_ci OpSource ESSL 310 529fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 530fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 531fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 532fd4e5da5Sopenharmony_ci %7 = OpTypePointer Function %6 533fd4e5da5Sopenharmony_ci %9 = OpConstant %6 2 534fd4e5da5Sopenharmony_ci %11 = OpConstant %6 3 535fd4e5da5Sopenharmony_ci %50 = OpTypeBool 536fd4e5da5Sopenharmony_ci %51 = OpConstantTrue %50 537fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 538fd4e5da5Sopenharmony_ci %5 = OpLabel 539fd4e5da5Sopenharmony_ci %8 = OpVariable %7 Function 540fd4e5da5Sopenharmony_ci %10 = OpVariable %7 Function 541fd4e5da5Sopenharmony_ci OpStore %8 %9 542fd4e5da5Sopenharmony_ci OpBranch %100 543fd4e5da5Sopenharmony_ci %100 = OpLabel 544fd4e5da5Sopenharmony_ci OpStore %10 %11 545fd4e5da5Sopenharmony_ci %12 = OpLoad %6 %10 546fd4e5da5Sopenharmony_ci %13 = OpLoad %6 %8 547fd4e5da5Sopenharmony_ci OpBranch %101 548fd4e5da5Sopenharmony_ci %101 = OpLabel 549fd4e5da5Sopenharmony_ci OpSelectionMerge %103 None 550fd4e5da5Sopenharmony_ci OpBranchConditional %51 %102 %103 551fd4e5da5Sopenharmony_ci %102 = OpLabel 552fd4e5da5Sopenharmony_ci %14 = OpIAdd %6 %13 %12 553fd4e5da5Sopenharmony_ci OpStore %8 %14 554fd4e5da5Sopenharmony_ci OpBranch %103 555fd4e5da5Sopenharmony_ci %103 = OpLabel 556fd4e5da5Sopenharmony_ci OpReturn 557fd4e5da5Sopenharmony_ci OpFunctionEnd 558fd4e5da5Sopenharmony_ci )"; 559fd4e5da5Sopenharmony_ci 560fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_4; 561fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 562fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); 563fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 564fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 565fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 566fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 567fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(context.get()), validator_options); 568fd4e5da5Sopenharmony_ci for (auto& transformation : 569fd4e5da5Sopenharmony_ci {TransformationMergeBlocks(101), TransformationMergeBlocks(100)}) { 570fd4e5da5Sopenharmony_ci ASSERT_TRUE( 571fd4e5da5Sopenharmony_ci transformation.IsApplicable(context.get(), transformation_context)); 572fd4e5da5Sopenharmony_ci ApplyAndCheckFreshIds(transformation, context.get(), 573fd4e5da5Sopenharmony_ci &transformation_context); 574fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed( 575fd4e5da5Sopenharmony_ci context.get(), validator_options, kConsoleMessageConsumer)); 576fd4e5da5Sopenharmony_ci } 577fd4e5da5Sopenharmony_ci 578fd4e5da5Sopenharmony_ci std::string after_transformation = R"( 579fd4e5da5Sopenharmony_ci OpCapability Shader 580fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 581fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 582fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 583fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 584fd4e5da5Sopenharmony_ci OpSource ESSL 310 585fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 586fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 587fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 588fd4e5da5Sopenharmony_ci %7 = OpTypePointer Function %6 589fd4e5da5Sopenharmony_ci %9 = OpConstant %6 2 590fd4e5da5Sopenharmony_ci %11 = OpConstant %6 3 591fd4e5da5Sopenharmony_ci %50 = OpTypeBool 592fd4e5da5Sopenharmony_ci %51 = OpConstantTrue %50 593fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 594fd4e5da5Sopenharmony_ci %5 = OpLabel 595fd4e5da5Sopenharmony_ci %8 = OpVariable %7 Function 596fd4e5da5Sopenharmony_ci %10 = OpVariable %7 Function 597fd4e5da5Sopenharmony_ci OpStore %8 %9 598fd4e5da5Sopenharmony_ci OpStore %10 %11 599fd4e5da5Sopenharmony_ci %12 = OpLoad %6 %10 600fd4e5da5Sopenharmony_ci %13 = OpLoad %6 %8 601fd4e5da5Sopenharmony_ci OpSelectionMerge %103 None 602fd4e5da5Sopenharmony_ci OpBranchConditional %51 %102 %103 603fd4e5da5Sopenharmony_ci %102 = OpLabel 604fd4e5da5Sopenharmony_ci %14 = OpIAdd %6 %13 %12 605fd4e5da5Sopenharmony_ci OpStore %8 %14 606fd4e5da5Sopenharmony_ci OpBranch %103 607fd4e5da5Sopenharmony_ci %103 = OpLabel 608fd4e5da5Sopenharmony_ci OpReturn 609fd4e5da5Sopenharmony_ci OpFunctionEnd 610fd4e5da5Sopenharmony_ci )"; 611fd4e5da5Sopenharmony_ci 612fd4e5da5Sopenharmony_ci ASSERT_TRUE(IsEqual(env, after_transformation, context.get())); 613fd4e5da5Sopenharmony_ci} 614fd4e5da5Sopenharmony_ci 615fd4e5da5Sopenharmony_ciTEST(TransformationMergeBlocksTest, 616fd4e5da5Sopenharmony_ci MergeWhenFirstBlockIsLoopMergeFollowedByUnconditionalBranch) { 617fd4e5da5Sopenharmony_ci std::string shader = R"( 618fd4e5da5Sopenharmony_ci OpCapability Shader 619fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 620fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 621fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 622fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 623fd4e5da5Sopenharmony_ci OpSource ESSL 310 624fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 625fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 626fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 627fd4e5da5Sopenharmony_ci %7 = OpTypePointer Function %6 628fd4e5da5Sopenharmony_ci %9 = OpConstant %6 2 629fd4e5da5Sopenharmony_ci %11 = OpConstant %6 3 630fd4e5da5Sopenharmony_ci %50 = OpTypeBool 631fd4e5da5Sopenharmony_ci %51 = OpConstantTrue %50 632fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 633fd4e5da5Sopenharmony_ci %5 = OpLabel 634fd4e5da5Sopenharmony_ci %8 = OpVariable %7 Function 635fd4e5da5Sopenharmony_ci %10 = OpVariable %7 Function 636fd4e5da5Sopenharmony_ci OpStore %8 %9 637fd4e5da5Sopenharmony_ci OpBranch %100 638fd4e5da5Sopenharmony_ci %100 = OpLabel 639fd4e5da5Sopenharmony_ci OpLoopMerge %102 %103 None 640fd4e5da5Sopenharmony_ci OpBranch %101 641fd4e5da5Sopenharmony_ci %101 = OpLabel 642fd4e5da5Sopenharmony_ci %200 = OpCopyObject %6 %9 643fd4e5da5Sopenharmony_ci OpBranchConditional %51 %102 %103 644fd4e5da5Sopenharmony_ci %103 = OpLabel 645fd4e5da5Sopenharmony_ci OpBranch %100 646fd4e5da5Sopenharmony_ci %102 = OpLabel 647fd4e5da5Sopenharmony_ci OpReturn 648fd4e5da5Sopenharmony_ci OpFunctionEnd 649fd4e5da5Sopenharmony_ci )"; 650fd4e5da5Sopenharmony_ci 651fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_4; 652fd4e5da5Sopenharmony_ci const auto consumer = nullptr; 653fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); 654fd4e5da5Sopenharmony_ci spvtools::ValidatorOptions validator_options; 655fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 656fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 657fd4e5da5Sopenharmony_ci TransformationContext transformation_context( 658fd4e5da5Sopenharmony_ci MakeUnique<FactManager>(context.get()), validator_options); 659fd4e5da5Sopenharmony_ci TransformationMergeBlocks transformation(101); 660fd4e5da5Sopenharmony_ci ASSERT_TRUE( 661fd4e5da5Sopenharmony_ci transformation.IsApplicable(context.get(), transformation_context)); 662fd4e5da5Sopenharmony_ci ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context); 663fd4e5da5Sopenharmony_ci ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 664fd4e5da5Sopenharmony_ci kConsoleMessageConsumer)); 665fd4e5da5Sopenharmony_ci 666fd4e5da5Sopenharmony_ci std::string after_transformation = R"( 667fd4e5da5Sopenharmony_ci OpCapability Shader 668fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 669fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 670fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 671fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 672fd4e5da5Sopenharmony_ci OpSource ESSL 310 673fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 674fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 675fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 676fd4e5da5Sopenharmony_ci %7 = OpTypePointer Function %6 677fd4e5da5Sopenharmony_ci %9 = OpConstant %6 2 678fd4e5da5Sopenharmony_ci %11 = OpConstant %6 3 679fd4e5da5Sopenharmony_ci %50 = OpTypeBool 680fd4e5da5Sopenharmony_ci %51 = OpConstantTrue %50 681fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 682fd4e5da5Sopenharmony_ci %5 = OpLabel 683fd4e5da5Sopenharmony_ci %8 = OpVariable %7 Function 684fd4e5da5Sopenharmony_ci %10 = OpVariable %7 Function 685fd4e5da5Sopenharmony_ci OpStore %8 %9 686fd4e5da5Sopenharmony_ci OpBranch %100 687fd4e5da5Sopenharmony_ci %100 = OpLabel 688fd4e5da5Sopenharmony_ci %200 = OpCopyObject %6 %9 689fd4e5da5Sopenharmony_ci OpLoopMerge %102 %103 None 690fd4e5da5Sopenharmony_ci OpBranchConditional %51 %102 %103 691fd4e5da5Sopenharmony_ci %103 = OpLabel 692fd4e5da5Sopenharmony_ci OpBranch %100 693fd4e5da5Sopenharmony_ci %102 = OpLabel 694fd4e5da5Sopenharmony_ci OpReturn 695fd4e5da5Sopenharmony_ci OpFunctionEnd 696fd4e5da5Sopenharmony_ci )"; 697fd4e5da5Sopenharmony_ci 698fd4e5da5Sopenharmony_ci ASSERT_TRUE(IsEqual(env, after_transformation, context.get())); 699fd4e5da5Sopenharmony_ci} 700fd4e5da5Sopenharmony_ci 701fd4e5da5Sopenharmony_ci} // namespace 702fd4e5da5Sopenharmony_ci} // namespace fuzz 703fd4e5da5Sopenharmony_ci} // namespace spvtools 704