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/reduce/remove_selection_reduction_opportunity_finder.h" 16fd4e5da5Sopenharmony_ci 17fd4e5da5Sopenharmony_ci#include "source/opt/build_module.h" 18fd4e5da5Sopenharmony_ci#include "source/reduce/reduction_opportunity.h" 19fd4e5da5Sopenharmony_ci#include "test/reduce/reduce_test_util.h" 20fd4e5da5Sopenharmony_ci 21fd4e5da5Sopenharmony_cinamespace spvtools { 22fd4e5da5Sopenharmony_cinamespace reduce { 23fd4e5da5Sopenharmony_cinamespace { 24fd4e5da5Sopenharmony_ci 25fd4e5da5Sopenharmony_ciTEST(RemoveSelectionTest, OpportunityBecauseSameTargetBlock) { 26fd4e5da5Sopenharmony_ci // A test with the following structure. The OpSelectionMerge instruction 27fd4e5da5Sopenharmony_ci // should be removed. 28fd4e5da5Sopenharmony_ci // 29fd4e5da5Sopenharmony_ci // header 30fd4e5da5Sopenharmony_ci // || 31fd4e5da5Sopenharmony_ci // block 32fd4e5da5Sopenharmony_ci // | 33fd4e5da5Sopenharmony_ci // merge 34fd4e5da5Sopenharmony_ci 35fd4e5da5Sopenharmony_ci std::string shader = R"( 36fd4e5da5Sopenharmony_ci OpCapability Shader 37fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 38fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 39fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %2 "main" 40fd4e5da5Sopenharmony_ci OpExecutionMode %2 OriginUpperLeft 41fd4e5da5Sopenharmony_ci OpSource ESSL 310 42fd4e5da5Sopenharmony_ci OpName %2 "main" 43fd4e5da5Sopenharmony_ci %3 = OpTypeVoid 44fd4e5da5Sopenharmony_ci %4 = OpTypeFunction %3 45fd4e5da5Sopenharmony_ci %5 = OpTypeInt 32 1 46fd4e5da5Sopenharmony_ci %6 = OpTypePointer Function %5 47fd4e5da5Sopenharmony_ci %7 = OpTypeBool 48fd4e5da5Sopenharmony_ci %8 = OpConstantTrue %7 49fd4e5da5Sopenharmony_ci %2 = OpFunction %3 None %4 50fd4e5da5Sopenharmony_ci %9 = OpLabel 51fd4e5da5Sopenharmony_ci OpSelectionMerge %10 None 52fd4e5da5Sopenharmony_ci OpBranchConditional %8 %11 %11 53fd4e5da5Sopenharmony_ci %11 = OpLabel 54fd4e5da5Sopenharmony_ci OpBranch %10 55fd4e5da5Sopenharmony_ci %10 = OpLabel 56fd4e5da5Sopenharmony_ci OpReturn 57fd4e5da5Sopenharmony_ci OpFunctionEnd 58fd4e5da5Sopenharmony_ci )"; 59fd4e5da5Sopenharmony_ci 60fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 61fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption); 62fd4e5da5Sopenharmony_ci 63fd4e5da5Sopenharmony_ci auto ops = 64fd4e5da5Sopenharmony_ci RemoveSelectionReductionOpportunityFinder().GetAvailableOpportunities( 65fd4e5da5Sopenharmony_ci context.get(), 0); 66fd4e5da5Sopenharmony_ci 67fd4e5da5Sopenharmony_ci ASSERT_EQ(1, ops.size()); 68fd4e5da5Sopenharmony_ci 69fd4e5da5Sopenharmony_ci ASSERT_TRUE(ops[0]->PreconditionHolds()); 70fd4e5da5Sopenharmony_ci ops[0]->TryToApply(); 71fd4e5da5Sopenharmony_ci CheckValid(env, context.get()); 72fd4e5da5Sopenharmony_ci 73fd4e5da5Sopenharmony_ci std::string after = R"( 74fd4e5da5Sopenharmony_ci OpCapability Shader 75fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 76fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 77fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %2 "main" 78fd4e5da5Sopenharmony_ci OpExecutionMode %2 OriginUpperLeft 79fd4e5da5Sopenharmony_ci OpSource ESSL 310 80fd4e5da5Sopenharmony_ci OpName %2 "main" 81fd4e5da5Sopenharmony_ci %3 = OpTypeVoid 82fd4e5da5Sopenharmony_ci %4 = OpTypeFunction %3 83fd4e5da5Sopenharmony_ci %5 = OpTypeInt 32 1 84fd4e5da5Sopenharmony_ci %6 = OpTypePointer Function %5 85fd4e5da5Sopenharmony_ci %7 = OpTypeBool 86fd4e5da5Sopenharmony_ci %8 = OpConstantTrue %7 87fd4e5da5Sopenharmony_ci %2 = OpFunction %3 None %4 88fd4e5da5Sopenharmony_ci %9 = OpLabel 89fd4e5da5Sopenharmony_ci OpBranchConditional %8 %11 %11 90fd4e5da5Sopenharmony_ci %11 = OpLabel 91fd4e5da5Sopenharmony_ci OpBranch %10 92fd4e5da5Sopenharmony_ci %10 = OpLabel 93fd4e5da5Sopenharmony_ci OpReturn 94fd4e5da5Sopenharmony_ci OpFunctionEnd 95fd4e5da5Sopenharmony_ci )"; 96fd4e5da5Sopenharmony_ci CheckEqual(env, after, context.get()); 97fd4e5da5Sopenharmony_ci 98fd4e5da5Sopenharmony_ci ops = RemoveSelectionReductionOpportunityFinder().GetAvailableOpportunities( 99fd4e5da5Sopenharmony_ci context.get(), 0); 100fd4e5da5Sopenharmony_ci ASSERT_EQ(0, ops.size()); 101fd4e5da5Sopenharmony_ci} 102fd4e5da5Sopenharmony_ci 103fd4e5da5Sopenharmony_ciTEST(RemoveSelectionTest, OpportunityBecauseSameTargetBlockMerge) { 104fd4e5da5Sopenharmony_ci // A test with the following structure. The OpSelectionMerge instruction 105fd4e5da5Sopenharmony_ci // should be removed. 106fd4e5da5Sopenharmony_ci // 107fd4e5da5Sopenharmony_ci // header 108fd4e5da5Sopenharmony_ci // || 109fd4e5da5Sopenharmony_ci // merge 110fd4e5da5Sopenharmony_ci 111fd4e5da5Sopenharmony_ci std::string shader = R"( 112fd4e5da5Sopenharmony_ci OpCapability Shader 113fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 114fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 115fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %2 "main" 116fd4e5da5Sopenharmony_ci OpExecutionMode %2 OriginUpperLeft 117fd4e5da5Sopenharmony_ci OpSource ESSL 310 118fd4e5da5Sopenharmony_ci OpName %2 "main" 119fd4e5da5Sopenharmony_ci %3 = OpTypeVoid 120fd4e5da5Sopenharmony_ci %4 = OpTypeFunction %3 121fd4e5da5Sopenharmony_ci %5 = OpTypeInt 32 1 122fd4e5da5Sopenharmony_ci %6 = OpTypePointer Function %5 123fd4e5da5Sopenharmony_ci %7 = OpTypeBool 124fd4e5da5Sopenharmony_ci %8 = OpConstantTrue %7 125fd4e5da5Sopenharmony_ci %2 = OpFunction %3 None %4 126fd4e5da5Sopenharmony_ci %9 = OpLabel 127fd4e5da5Sopenharmony_ci OpSelectionMerge %10 None 128fd4e5da5Sopenharmony_ci OpBranchConditional %8 %10 %10 129fd4e5da5Sopenharmony_ci %10 = OpLabel 130fd4e5da5Sopenharmony_ci OpReturn 131fd4e5da5Sopenharmony_ci OpFunctionEnd 132fd4e5da5Sopenharmony_ci )"; 133fd4e5da5Sopenharmony_ci 134fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 135fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption); 136fd4e5da5Sopenharmony_ci 137fd4e5da5Sopenharmony_ci auto ops = 138fd4e5da5Sopenharmony_ci RemoveSelectionReductionOpportunityFinder().GetAvailableOpportunities( 139fd4e5da5Sopenharmony_ci context.get(), 0); 140fd4e5da5Sopenharmony_ci 141fd4e5da5Sopenharmony_ci ASSERT_EQ(1, ops.size()); 142fd4e5da5Sopenharmony_ci 143fd4e5da5Sopenharmony_ci ASSERT_TRUE(ops[0]->PreconditionHolds()); 144fd4e5da5Sopenharmony_ci ops[0]->TryToApply(); 145fd4e5da5Sopenharmony_ci CheckValid(env, context.get()); 146fd4e5da5Sopenharmony_ci 147fd4e5da5Sopenharmony_ci std::string after = R"( 148fd4e5da5Sopenharmony_ci OpCapability Shader 149fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 150fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 151fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %2 "main" 152fd4e5da5Sopenharmony_ci OpExecutionMode %2 OriginUpperLeft 153fd4e5da5Sopenharmony_ci OpSource ESSL 310 154fd4e5da5Sopenharmony_ci OpName %2 "main" 155fd4e5da5Sopenharmony_ci %3 = OpTypeVoid 156fd4e5da5Sopenharmony_ci %4 = OpTypeFunction %3 157fd4e5da5Sopenharmony_ci %5 = OpTypeInt 32 1 158fd4e5da5Sopenharmony_ci %6 = OpTypePointer Function %5 159fd4e5da5Sopenharmony_ci %7 = OpTypeBool 160fd4e5da5Sopenharmony_ci %8 = OpConstantTrue %7 161fd4e5da5Sopenharmony_ci %2 = OpFunction %3 None %4 162fd4e5da5Sopenharmony_ci %9 = OpLabel 163fd4e5da5Sopenharmony_ci OpBranchConditional %8 %10 %10 164fd4e5da5Sopenharmony_ci %10 = OpLabel 165fd4e5da5Sopenharmony_ci OpReturn 166fd4e5da5Sopenharmony_ci OpFunctionEnd 167fd4e5da5Sopenharmony_ci )"; 168fd4e5da5Sopenharmony_ci CheckEqual(env, after, context.get()); 169fd4e5da5Sopenharmony_ci 170fd4e5da5Sopenharmony_ci ops = RemoveSelectionReductionOpportunityFinder().GetAvailableOpportunities( 171fd4e5da5Sopenharmony_ci context.get(), 0); 172fd4e5da5Sopenharmony_ci ASSERT_EQ(0, ops.size()); 173fd4e5da5Sopenharmony_ci} 174fd4e5da5Sopenharmony_ci 175fd4e5da5Sopenharmony_ciTEST(RemoveSelectionTest, NoOpportunityBecauseDifferentTargetBlocksOneMerge) { 176fd4e5da5Sopenharmony_ci // A test with the following structure. The OpSelectionMerge instruction 177fd4e5da5Sopenharmony_ci // should NOT be removed. 178fd4e5da5Sopenharmony_ci // 179fd4e5da5Sopenharmony_ci // header 180fd4e5da5Sopenharmony_ci // | | 181fd4e5da5Sopenharmony_ci // | block 182fd4e5da5Sopenharmony_ci // | | 183fd4e5da5Sopenharmony_ci // merge 184fd4e5da5Sopenharmony_ci 185fd4e5da5Sopenharmony_ci std::string shader = R"( 186fd4e5da5Sopenharmony_ci OpCapability Shader 187fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 188fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 189fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %2 "main" 190fd4e5da5Sopenharmony_ci OpExecutionMode %2 OriginUpperLeft 191fd4e5da5Sopenharmony_ci OpSource ESSL 310 192fd4e5da5Sopenharmony_ci OpName %2 "main" 193fd4e5da5Sopenharmony_ci %3 = OpTypeVoid 194fd4e5da5Sopenharmony_ci %4 = OpTypeFunction %3 195fd4e5da5Sopenharmony_ci %5 = OpTypeInt 32 1 196fd4e5da5Sopenharmony_ci %6 = OpTypePointer Function %5 197fd4e5da5Sopenharmony_ci %7 = OpTypeBool 198fd4e5da5Sopenharmony_ci %8 = OpConstantTrue %7 199fd4e5da5Sopenharmony_ci %2 = OpFunction %3 None %4 200fd4e5da5Sopenharmony_ci %9 = OpLabel 201fd4e5da5Sopenharmony_ci OpSelectionMerge %10 None 202fd4e5da5Sopenharmony_ci OpBranchConditional %8 %10 %11 203fd4e5da5Sopenharmony_ci %11 = OpLabel 204fd4e5da5Sopenharmony_ci OpBranch %10 205fd4e5da5Sopenharmony_ci %10 = OpLabel 206fd4e5da5Sopenharmony_ci OpReturn 207fd4e5da5Sopenharmony_ci OpFunctionEnd 208fd4e5da5Sopenharmony_ci )"; 209fd4e5da5Sopenharmony_ci 210fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 211fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption); 212fd4e5da5Sopenharmony_ci 213fd4e5da5Sopenharmony_ci auto ops = 214fd4e5da5Sopenharmony_ci RemoveSelectionReductionOpportunityFinder().GetAvailableOpportunities( 215fd4e5da5Sopenharmony_ci context.get(), 0); 216fd4e5da5Sopenharmony_ci ASSERT_EQ(0, ops.size()); 217fd4e5da5Sopenharmony_ci} 218fd4e5da5Sopenharmony_ci 219fd4e5da5Sopenharmony_ciTEST(RemoveSelectionTest, NoOpportunityBecauseDifferentTargetBlocks) { 220fd4e5da5Sopenharmony_ci // A test with the following structure. The OpSelectionMerge instruction 221fd4e5da5Sopenharmony_ci // should NOT be removed. 222fd4e5da5Sopenharmony_ci // 223fd4e5da5Sopenharmony_ci // header 224fd4e5da5Sopenharmony_ci // | | 225fd4e5da5Sopenharmony_ci // b b 226fd4e5da5Sopenharmony_ci // | | 227fd4e5da5Sopenharmony_ci // merge 228fd4e5da5Sopenharmony_ci 229fd4e5da5Sopenharmony_ci std::string shader = R"( 230fd4e5da5Sopenharmony_ci OpCapability Shader 231fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 232fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 233fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %2 "main" 234fd4e5da5Sopenharmony_ci OpExecutionMode %2 OriginUpperLeft 235fd4e5da5Sopenharmony_ci OpSource ESSL 310 236fd4e5da5Sopenharmony_ci OpName %2 "main" 237fd4e5da5Sopenharmony_ci %3 = OpTypeVoid 238fd4e5da5Sopenharmony_ci %4 = OpTypeFunction %3 239fd4e5da5Sopenharmony_ci %5 = OpTypeInt 32 1 240fd4e5da5Sopenharmony_ci %6 = OpTypePointer Function %5 241fd4e5da5Sopenharmony_ci %7 = OpTypeBool 242fd4e5da5Sopenharmony_ci %8 = OpConstantTrue %7 243fd4e5da5Sopenharmony_ci %2 = OpFunction %3 None %4 244fd4e5da5Sopenharmony_ci %9 = OpLabel 245fd4e5da5Sopenharmony_ci OpSelectionMerge %10 None 246fd4e5da5Sopenharmony_ci OpBranchConditional %8 %11 %12 247fd4e5da5Sopenharmony_ci %11 = OpLabel 248fd4e5da5Sopenharmony_ci OpBranch %10 249fd4e5da5Sopenharmony_ci %12 = OpLabel 250fd4e5da5Sopenharmony_ci OpBranch %10 251fd4e5da5Sopenharmony_ci %10 = OpLabel 252fd4e5da5Sopenharmony_ci OpReturn 253fd4e5da5Sopenharmony_ci OpFunctionEnd 254fd4e5da5Sopenharmony_ci )"; 255fd4e5da5Sopenharmony_ci 256fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 257fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption); 258fd4e5da5Sopenharmony_ci 259fd4e5da5Sopenharmony_ci auto ops = 260fd4e5da5Sopenharmony_ci RemoveSelectionReductionOpportunityFinder().GetAvailableOpportunities( 261fd4e5da5Sopenharmony_ci context.get(), 0); 262fd4e5da5Sopenharmony_ci ASSERT_EQ(0, ops.size()); 263fd4e5da5Sopenharmony_ci} 264fd4e5da5Sopenharmony_ci 265fd4e5da5Sopenharmony_ciTEST(RemoveSelectionTest, NoOpportunityBecauseMergeUsed) { 266fd4e5da5Sopenharmony_ci // A test with the following structure. The OpSelectionMerge instruction 267fd4e5da5Sopenharmony_ci // should NOT be removed. 268fd4e5da5Sopenharmony_ci // 269fd4e5da5Sopenharmony_ci // header 270fd4e5da5Sopenharmony_ci // || 271fd4e5da5Sopenharmony_ci // block 272fd4e5da5Sopenharmony_ci // | | 273fd4e5da5Sopenharmony_ci // | block 274fd4e5da5Sopenharmony_ci // | | 275fd4e5da5Sopenharmony_ci // merge 276fd4e5da5Sopenharmony_ci 277fd4e5da5Sopenharmony_ci std::string shader = R"( 278fd4e5da5Sopenharmony_ci OpCapability Shader 279fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 280fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 281fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %2 "main" 282fd4e5da5Sopenharmony_ci OpExecutionMode %2 OriginUpperLeft 283fd4e5da5Sopenharmony_ci OpSource ESSL 310 284fd4e5da5Sopenharmony_ci OpName %2 "main" 285fd4e5da5Sopenharmony_ci %3 = OpTypeVoid 286fd4e5da5Sopenharmony_ci %4 = OpTypeFunction %3 287fd4e5da5Sopenharmony_ci %5 = OpTypeInt 32 1 288fd4e5da5Sopenharmony_ci %6 = OpTypePointer Function %5 289fd4e5da5Sopenharmony_ci %7 = OpTypeBool 290fd4e5da5Sopenharmony_ci %8 = OpConstantTrue %7 291fd4e5da5Sopenharmony_ci %2 = OpFunction %3 None %4 292fd4e5da5Sopenharmony_ci %9 = OpLabel 293fd4e5da5Sopenharmony_ci OpSelectionMerge %10 None 294fd4e5da5Sopenharmony_ci OpBranchConditional %8 %11 %12 295fd4e5da5Sopenharmony_ci %11 = OpLabel 296fd4e5da5Sopenharmony_ci OpBranchConditional %8 %10 %12 297fd4e5da5Sopenharmony_ci %12 = OpLabel 298fd4e5da5Sopenharmony_ci OpBranch %10 299fd4e5da5Sopenharmony_ci %10 = OpLabel 300fd4e5da5Sopenharmony_ci OpReturn 301fd4e5da5Sopenharmony_ci OpFunctionEnd 302fd4e5da5Sopenharmony_ci )"; 303fd4e5da5Sopenharmony_ci 304fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 305fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption); 306fd4e5da5Sopenharmony_ci 307fd4e5da5Sopenharmony_ci auto ops = 308fd4e5da5Sopenharmony_ci RemoveSelectionReductionOpportunityFinder().GetAvailableOpportunities( 309fd4e5da5Sopenharmony_ci context.get(), 0); 310fd4e5da5Sopenharmony_ci ASSERT_EQ(0, ops.size()); 311fd4e5da5Sopenharmony_ci} 312fd4e5da5Sopenharmony_ci 313fd4e5da5Sopenharmony_ciTEST(RemoveSelectionTest, OpportunityBecauseLoopMergeUsed) { 314fd4e5da5Sopenharmony_ci // A test with the following structure. The OpSelectionMerge instruction 315fd4e5da5Sopenharmony_ci // should be removed. 316fd4e5da5Sopenharmony_ci // 317fd4e5da5Sopenharmony_ci // loop header 318fd4e5da5Sopenharmony_ci // | 319fd4e5da5Sopenharmony_ci // | 320fd4e5da5Sopenharmony_ci // s.header 321fd4e5da5Sopenharmony_ci // || 322fd4e5da5Sopenharmony_ci // block 323fd4e5da5Sopenharmony_ci // | | 324fd4e5da5Sopenharmony_ci // | | 325fd4e5da5Sopenharmony_ci // | | ^ (to loop header) 326fd4e5da5Sopenharmony_ci // s.merge | | 327fd4e5da5Sopenharmony_ci // | / loop continue target (unreachable) 328fd4e5da5Sopenharmony_ci // loop merge 329fd4e5da5Sopenharmony_ci // 330fd4e5da5Sopenharmony_ci // 331fd4e5da5Sopenharmony_ci // which becomes: 332fd4e5da5Sopenharmony_ci // 333fd4e5da5Sopenharmony_ci // loop header 334fd4e5da5Sopenharmony_ci // | 335fd4e5da5Sopenharmony_ci // | 336fd4e5da5Sopenharmony_ci // block 337fd4e5da5Sopenharmony_ci // || 338fd4e5da5Sopenharmony_ci // block 339fd4e5da5Sopenharmony_ci // | | 340fd4e5da5Sopenharmony_ci // | | 341fd4e5da5Sopenharmony_ci // | | ^ (to loop header) 342fd4e5da5Sopenharmony_ci // block | | 343fd4e5da5Sopenharmony_ci // | / loop continue target (unreachable) 344fd4e5da5Sopenharmony_ci // loop merge 345fd4e5da5Sopenharmony_ci 346fd4e5da5Sopenharmony_ci std::string shader = R"( 347fd4e5da5Sopenharmony_ci OpCapability Shader 348fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 349fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 350fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %2 "main" 351fd4e5da5Sopenharmony_ci OpExecutionMode %2 OriginUpperLeft 352fd4e5da5Sopenharmony_ci OpSource ESSL 310 353fd4e5da5Sopenharmony_ci OpName %2 "main" 354fd4e5da5Sopenharmony_ci %3 = OpTypeVoid 355fd4e5da5Sopenharmony_ci %4 = OpTypeFunction %3 356fd4e5da5Sopenharmony_ci %5 = OpTypeInt 32 1 357fd4e5da5Sopenharmony_ci %6 = OpTypePointer Function %5 358fd4e5da5Sopenharmony_ci %7 = OpTypeBool 359fd4e5da5Sopenharmony_ci %8 = OpConstantTrue %7 360fd4e5da5Sopenharmony_ci %2 = OpFunction %3 None %4 361fd4e5da5Sopenharmony_ci %9 = OpLabel 362fd4e5da5Sopenharmony_ci OpBranch %10 363fd4e5da5Sopenharmony_ci %10 = OpLabel 364fd4e5da5Sopenharmony_ci OpLoopMerge %11 %12 None 365fd4e5da5Sopenharmony_ci OpBranch %13 366fd4e5da5Sopenharmony_ci %13 = OpLabel 367fd4e5da5Sopenharmony_ci OpSelectionMerge %14 None 368fd4e5da5Sopenharmony_ci OpBranchConditional %8 %15 %15 369fd4e5da5Sopenharmony_ci %15 = OpLabel 370fd4e5da5Sopenharmony_ci OpBranchConditional %8 %14 %11 371fd4e5da5Sopenharmony_ci %14 = OpLabel 372fd4e5da5Sopenharmony_ci OpBranch %11 373fd4e5da5Sopenharmony_ci %12 = OpLabel 374fd4e5da5Sopenharmony_ci OpBranch %10 375fd4e5da5Sopenharmony_ci %11 = OpLabel 376fd4e5da5Sopenharmony_ci OpReturn 377fd4e5da5Sopenharmony_ci OpFunctionEnd 378fd4e5da5Sopenharmony_ci )"; 379fd4e5da5Sopenharmony_ci 380fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 381fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption); 382fd4e5da5Sopenharmony_ci 383fd4e5da5Sopenharmony_ci CheckValid(env, context.get()); 384fd4e5da5Sopenharmony_ci 385fd4e5da5Sopenharmony_ci auto ops = 386fd4e5da5Sopenharmony_ci RemoveSelectionReductionOpportunityFinder().GetAvailableOpportunities( 387fd4e5da5Sopenharmony_ci context.get(), 0); 388fd4e5da5Sopenharmony_ci 389fd4e5da5Sopenharmony_ci ASSERT_EQ(1, ops.size()); 390fd4e5da5Sopenharmony_ci 391fd4e5da5Sopenharmony_ci ASSERT_TRUE(ops[0]->PreconditionHolds()); 392fd4e5da5Sopenharmony_ci ops[0]->TryToApply(); 393fd4e5da5Sopenharmony_ci CheckValid(env, context.get()); 394fd4e5da5Sopenharmony_ci 395fd4e5da5Sopenharmony_ci std::string after = R"( 396fd4e5da5Sopenharmony_ci OpCapability Shader 397fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 398fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 399fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %2 "main" 400fd4e5da5Sopenharmony_ci OpExecutionMode %2 OriginUpperLeft 401fd4e5da5Sopenharmony_ci OpSource ESSL 310 402fd4e5da5Sopenharmony_ci OpName %2 "main" 403fd4e5da5Sopenharmony_ci %3 = OpTypeVoid 404fd4e5da5Sopenharmony_ci %4 = OpTypeFunction %3 405fd4e5da5Sopenharmony_ci %5 = OpTypeInt 32 1 406fd4e5da5Sopenharmony_ci %6 = OpTypePointer Function %5 407fd4e5da5Sopenharmony_ci %7 = OpTypeBool 408fd4e5da5Sopenharmony_ci %8 = OpConstantTrue %7 409fd4e5da5Sopenharmony_ci %2 = OpFunction %3 None %4 410fd4e5da5Sopenharmony_ci %9 = OpLabel 411fd4e5da5Sopenharmony_ci OpBranch %10 412fd4e5da5Sopenharmony_ci %10 = OpLabel 413fd4e5da5Sopenharmony_ci OpLoopMerge %11 %12 None 414fd4e5da5Sopenharmony_ci OpBranch %13 415fd4e5da5Sopenharmony_ci %13 = OpLabel 416fd4e5da5Sopenharmony_ci OpBranchConditional %8 %15 %15 417fd4e5da5Sopenharmony_ci %15 = OpLabel 418fd4e5da5Sopenharmony_ci OpBranchConditional %8 %14 %11 419fd4e5da5Sopenharmony_ci %14 = OpLabel 420fd4e5da5Sopenharmony_ci OpBranch %11 421fd4e5da5Sopenharmony_ci %12 = OpLabel 422fd4e5da5Sopenharmony_ci OpBranch %10 423fd4e5da5Sopenharmony_ci %11 = OpLabel 424fd4e5da5Sopenharmony_ci OpReturn 425fd4e5da5Sopenharmony_ci OpFunctionEnd 426fd4e5da5Sopenharmony_ci )"; 427fd4e5da5Sopenharmony_ci CheckEqual(env, after, context.get()); 428fd4e5da5Sopenharmony_ci 429fd4e5da5Sopenharmony_ci ops = RemoveSelectionReductionOpportunityFinder().GetAvailableOpportunities( 430fd4e5da5Sopenharmony_ci context.get(), 0); 431fd4e5da5Sopenharmony_ci ASSERT_EQ(0, ops.size()); 432fd4e5da5Sopenharmony_ci} 433fd4e5da5Sopenharmony_ci 434fd4e5da5Sopenharmony_ciTEST(RemoveSelectionTest, OpportunityBecauseLoopContinueUsed) { 435fd4e5da5Sopenharmony_ci // A test with the following structure. The OpSelectionMerge instruction 436fd4e5da5Sopenharmony_ci // should be removed. 437fd4e5da5Sopenharmony_ci // 438fd4e5da5Sopenharmony_ci // loop header 439fd4e5da5Sopenharmony_ci // | 440fd4e5da5Sopenharmony_ci // | 441fd4e5da5Sopenharmony_ci // s.header 442fd4e5da5Sopenharmony_ci // || 443fd4e5da5Sopenharmony_ci // block 444fd4e5da5Sopenharmony_ci // | | 445fd4e5da5Sopenharmony_ci // | | 446fd4e5da5Sopenharmony_ci // | | ^ (to loop header) 447fd4e5da5Sopenharmony_ci // s.merge | | 448fd4e5da5Sopenharmony_ci // | loop continue target 449fd4e5da5Sopenharmony_ci // loop merge 450fd4e5da5Sopenharmony_ci // 451fd4e5da5Sopenharmony_ci // 452fd4e5da5Sopenharmony_ci // which becomes: 453fd4e5da5Sopenharmony_ci // 454fd4e5da5Sopenharmony_ci // loop header 455fd4e5da5Sopenharmony_ci // | 456fd4e5da5Sopenharmony_ci // | 457fd4e5da5Sopenharmony_ci // block 458fd4e5da5Sopenharmony_ci // || 459fd4e5da5Sopenharmony_ci // block 460fd4e5da5Sopenharmony_ci // | | 461fd4e5da5Sopenharmony_ci // | | 462fd4e5da5Sopenharmony_ci // | | ^ (to loop header) 463fd4e5da5Sopenharmony_ci // block | | 464fd4e5da5Sopenharmony_ci // | loop continue target 465fd4e5da5Sopenharmony_ci // loop merge 466fd4e5da5Sopenharmony_ci 467fd4e5da5Sopenharmony_ci std::string shader = R"( 468fd4e5da5Sopenharmony_ci OpCapability Shader 469fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 470fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 471fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %2 "main" 472fd4e5da5Sopenharmony_ci OpExecutionMode %2 OriginUpperLeft 473fd4e5da5Sopenharmony_ci OpSource ESSL 310 474fd4e5da5Sopenharmony_ci OpName %2 "main" 475fd4e5da5Sopenharmony_ci %3 = OpTypeVoid 476fd4e5da5Sopenharmony_ci %4 = OpTypeFunction %3 477fd4e5da5Sopenharmony_ci %5 = OpTypeInt 32 1 478fd4e5da5Sopenharmony_ci %6 = OpTypePointer Function %5 479fd4e5da5Sopenharmony_ci %7 = OpTypeBool 480fd4e5da5Sopenharmony_ci %8 = OpConstantTrue %7 481fd4e5da5Sopenharmony_ci %2 = OpFunction %3 None %4 482fd4e5da5Sopenharmony_ci %9 = OpLabel 483fd4e5da5Sopenharmony_ci OpBranch %10 484fd4e5da5Sopenharmony_ci %10 = OpLabel 485fd4e5da5Sopenharmony_ci OpLoopMerge %11 %12 None 486fd4e5da5Sopenharmony_ci OpBranch %13 487fd4e5da5Sopenharmony_ci %13 = OpLabel 488fd4e5da5Sopenharmony_ci OpSelectionMerge %14 None 489fd4e5da5Sopenharmony_ci OpBranchConditional %8 %15 %15 490fd4e5da5Sopenharmony_ci %15 = OpLabel 491fd4e5da5Sopenharmony_ci OpBranchConditional %8 %14 %12 492fd4e5da5Sopenharmony_ci %14 = OpLabel 493fd4e5da5Sopenharmony_ci OpBranch %11 494fd4e5da5Sopenharmony_ci %12 = OpLabel 495fd4e5da5Sopenharmony_ci OpBranch %10 496fd4e5da5Sopenharmony_ci %11 = OpLabel 497fd4e5da5Sopenharmony_ci OpReturn 498fd4e5da5Sopenharmony_ci OpFunctionEnd 499fd4e5da5Sopenharmony_ci )"; 500fd4e5da5Sopenharmony_ci 501fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 502fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption); 503fd4e5da5Sopenharmony_ci 504fd4e5da5Sopenharmony_ci CheckValid(env, context.get()); 505fd4e5da5Sopenharmony_ci 506fd4e5da5Sopenharmony_ci auto ops = 507fd4e5da5Sopenharmony_ci RemoveSelectionReductionOpportunityFinder().GetAvailableOpportunities( 508fd4e5da5Sopenharmony_ci context.get(), 0); 509fd4e5da5Sopenharmony_ci 510fd4e5da5Sopenharmony_ci ASSERT_EQ(1, ops.size()); 511fd4e5da5Sopenharmony_ci 512fd4e5da5Sopenharmony_ci ASSERT_TRUE(ops[0]->PreconditionHolds()); 513fd4e5da5Sopenharmony_ci ops[0]->TryToApply(); 514fd4e5da5Sopenharmony_ci CheckValid(env, context.get()); 515fd4e5da5Sopenharmony_ci 516fd4e5da5Sopenharmony_ci std::string after = R"( 517fd4e5da5Sopenharmony_ci OpCapability Shader 518fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 519fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 520fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %2 "main" 521fd4e5da5Sopenharmony_ci OpExecutionMode %2 OriginUpperLeft 522fd4e5da5Sopenharmony_ci OpSource ESSL 310 523fd4e5da5Sopenharmony_ci OpName %2 "main" 524fd4e5da5Sopenharmony_ci %3 = OpTypeVoid 525fd4e5da5Sopenharmony_ci %4 = OpTypeFunction %3 526fd4e5da5Sopenharmony_ci %5 = OpTypeInt 32 1 527fd4e5da5Sopenharmony_ci %6 = OpTypePointer Function %5 528fd4e5da5Sopenharmony_ci %7 = OpTypeBool 529fd4e5da5Sopenharmony_ci %8 = OpConstantTrue %7 530fd4e5da5Sopenharmony_ci %2 = OpFunction %3 None %4 531fd4e5da5Sopenharmony_ci %9 = OpLabel 532fd4e5da5Sopenharmony_ci OpBranch %10 533fd4e5da5Sopenharmony_ci %10 = OpLabel 534fd4e5da5Sopenharmony_ci OpLoopMerge %11 %12 None 535fd4e5da5Sopenharmony_ci OpBranch %13 536fd4e5da5Sopenharmony_ci %13 = OpLabel 537fd4e5da5Sopenharmony_ci OpBranchConditional %8 %15 %15 538fd4e5da5Sopenharmony_ci %15 = OpLabel 539fd4e5da5Sopenharmony_ci OpBranchConditional %8 %14 %12 540fd4e5da5Sopenharmony_ci %14 = OpLabel 541fd4e5da5Sopenharmony_ci OpBranch %11 542fd4e5da5Sopenharmony_ci %12 = OpLabel 543fd4e5da5Sopenharmony_ci OpBranch %10 544fd4e5da5Sopenharmony_ci %11 = OpLabel 545fd4e5da5Sopenharmony_ci OpReturn 546fd4e5da5Sopenharmony_ci OpFunctionEnd 547fd4e5da5Sopenharmony_ci )"; 548fd4e5da5Sopenharmony_ci CheckEqual(env, after, context.get()); 549fd4e5da5Sopenharmony_ci 550fd4e5da5Sopenharmony_ci ops = RemoveSelectionReductionOpportunityFinder().GetAvailableOpportunities( 551fd4e5da5Sopenharmony_ci context.get(), 0); 552fd4e5da5Sopenharmony_ci ASSERT_EQ(0, ops.size()); 553fd4e5da5Sopenharmony_ci} 554fd4e5da5Sopenharmony_ci 555fd4e5da5Sopenharmony_ci} // namespace 556fd4e5da5Sopenharmony_ci} // namespace reduce 557fd4e5da5Sopenharmony_ci} // namespace spvtools 558