1fd4e5da5Sopenharmony_ci// Copyright (c) 2018 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/structured_loop_to_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(StructuredLoopToSelectionReductionPassTest, LoopyShader1) { 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 %2 = OpTypeVoid 34fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 35fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 36fd4e5da5Sopenharmony_ci %7 = OpTypePointer Function %6 37fd4e5da5Sopenharmony_ci %9 = OpConstant %6 0 38fd4e5da5Sopenharmony_ci %16 = OpConstant %6 100 39fd4e5da5Sopenharmony_ci %17 = OpTypeBool 40fd4e5da5Sopenharmony_ci %20 = OpConstant %6 1 41fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 42fd4e5da5Sopenharmony_ci %5 = OpLabel 43fd4e5da5Sopenharmony_ci %8 = OpVariable %7 Function 44fd4e5da5Sopenharmony_ci OpStore %8 %9 45fd4e5da5Sopenharmony_ci OpBranch %10 46fd4e5da5Sopenharmony_ci %10 = OpLabel 47fd4e5da5Sopenharmony_ci OpLoopMerge %12 %13 None 48fd4e5da5Sopenharmony_ci OpBranch %14 49fd4e5da5Sopenharmony_ci %14 = OpLabel 50fd4e5da5Sopenharmony_ci %15 = OpLoad %6 %8 51fd4e5da5Sopenharmony_ci %18 = OpSLessThan %17 %15 %16 52fd4e5da5Sopenharmony_ci OpBranchConditional %18 %11 %12 53fd4e5da5Sopenharmony_ci %11 = OpLabel 54fd4e5da5Sopenharmony_ci OpBranch %13 55fd4e5da5Sopenharmony_ci %13 = OpLabel 56fd4e5da5Sopenharmony_ci %19 = OpLoad %6 %8 57fd4e5da5Sopenharmony_ci %21 = OpIAdd %6 %19 %20 58fd4e5da5Sopenharmony_ci OpStore %8 %21 59fd4e5da5Sopenharmony_ci OpBranch %10 60fd4e5da5Sopenharmony_ci %12 = OpLabel 61fd4e5da5Sopenharmony_ci OpReturn 62fd4e5da5Sopenharmony_ci OpFunctionEnd 63fd4e5da5Sopenharmony_ci )"; 64fd4e5da5Sopenharmony_ci 65fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 66fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption); 67fd4e5da5Sopenharmony_ci const auto ops = StructuredLoopToSelectionReductionOpportunityFinder() 68fd4e5da5Sopenharmony_ci .GetAvailableOpportunities(context.get(), 0); 69fd4e5da5Sopenharmony_ci ASSERT_EQ(1, ops.size()); 70fd4e5da5Sopenharmony_ci 71fd4e5da5Sopenharmony_ci ASSERT_TRUE(ops[0]->PreconditionHolds()); 72fd4e5da5Sopenharmony_ci ops[0]->TryToApply(); 73fd4e5da5Sopenharmony_ci CheckValid(env, context.get()); 74fd4e5da5Sopenharmony_ci 75fd4e5da5Sopenharmony_ci std::string after_op_0 = R"( 76fd4e5da5Sopenharmony_ci OpCapability Shader 77fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 78fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 79fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 80fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 81fd4e5da5Sopenharmony_ci OpSource ESSL 310 82fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 83fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 84fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 85fd4e5da5Sopenharmony_ci %7 = OpTypePointer Function %6 86fd4e5da5Sopenharmony_ci %9 = OpConstant %6 0 87fd4e5da5Sopenharmony_ci %16 = OpConstant %6 100 88fd4e5da5Sopenharmony_ci %17 = OpTypeBool 89fd4e5da5Sopenharmony_ci %20 = OpConstant %6 1 90fd4e5da5Sopenharmony_ci %22 = OpConstantTrue %17 91fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 92fd4e5da5Sopenharmony_ci %5 = OpLabel 93fd4e5da5Sopenharmony_ci %8 = OpVariable %7 Function 94fd4e5da5Sopenharmony_ci OpStore %8 %9 95fd4e5da5Sopenharmony_ci OpBranch %10 96fd4e5da5Sopenharmony_ci %10 = OpLabel 97fd4e5da5Sopenharmony_ci OpSelectionMerge %12 None 98fd4e5da5Sopenharmony_ci OpBranchConditional %22 %14 %12 99fd4e5da5Sopenharmony_ci %14 = OpLabel 100fd4e5da5Sopenharmony_ci %15 = OpLoad %6 %8 101fd4e5da5Sopenharmony_ci %18 = OpSLessThan %17 %15 %16 102fd4e5da5Sopenharmony_ci OpBranchConditional %18 %11 %12 103fd4e5da5Sopenharmony_ci %11 = OpLabel 104fd4e5da5Sopenharmony_ci OpBranch %12 105fd4e5da5Sopenharmony_ci %13 = OpLabel 106fd4e5da5Sopenharmony_ci %19 = OpLoad %6 %8 107fd4e5da5Sopenharmony_ci %21 = OpIAdd %6 %19 %20 108fd4e5da5Sopenharmony_ci OpStore %8 %21 109fd4e5da5Sopenharmony_ci OpBranch %10 110fd4e5da5Sopenharmony_ci %12 = OpLabel 111fd4e5da5Sopenharmony_ci OpReturn 112fd4e5da5Sopenharmony_ci OpFunctionEnd 113fd4e5da5Sopenharmony_ci )"; 114fd4e5da5Sopenharmony_ci CheckEqual(env, after_op_0, context.get()); 115fd4e5da5Sopenharmony_ci} 116fd4e5da5Sopenharmony_ci 117fd4e5da5Sopenharmony_ciTEST(StructuredLoopToSelectionReductionPassTest, LoopyShader2) { 118fd4e5da5Sopenharmony_ci std::string shader = R"( 119fd4e5da5Sopenharmony_ci OpCapability Shader 120fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 121fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 122fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 123fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 124fd4e5da5Sopenharmony_ci OpSource ESSL 310 125fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 126fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 127fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 128fd4e5da5Sopenharmony_ci %7 = OpTypePointer Function %6 129fd4e5da5Sopenharmony_ci %9 = OpConstant %6 0 130fd4e5da5Sopenharmony_ci %16 = OpConstant %6 100 131fd4e5da5Sopenharmony_ci %17 = OpTypeBool 132fd4e5da5Sopenharmony_ci %28 = OpConstant %6 1 133fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 134fd4e5da5Sopenharmony_ci %5 = OpLabel 135fd4e5da5Sopenharmony_ci %8 = OpVariable %7 Function 136fd4e5da5Sopenharmony_ci %19 = OpVariable %7 Function 137fd4e5da5Sopenharmony_ci %32 = OpVariable %7 Function 138fd4e5da5Sopenharmony_ci %40 = OpVariable %7 Function 139fd4e5da5Sopenharmony_ci OpStore %8 %9 140fd4e5da5Sopenharmony_ci OpBranch %10 141fd4e5da5Sopenharmony_ci %10 = OpLabel 142fd4e5da5Sopenharmony_ci OpLoopMerge %12 %13 None 143fd4e5da5Sopenharmony_ci OpBranch %14 144fd4e5da5Sopenharmony_ci %14 = OpLabel 145fd4e5da5Sopenharmony_ci %15 = OpLoad %6 %8 146fd4e5da5Sopenharmony_ci %18 = OpSLessThan %17 %15 %16 147fd4e5da5Sopenharmony_ci OpBranchConditional %18 %11 %12 148fd4e5da5Sopenharmony_ci %11 = OpLabel 149fd4e5da5Sopenharmony_ci OpStore %19 %9 150fd4e5da5Sopenharmony_ci OpBranch %20 151fd4e5da5Sopenharmony_ci %20 = OpLabel 152fd4e5da5Sopenharmony_ci OpLoopMerge %22 %23 None 153fd4e5da5Sopenharmony_ci OpBranch %24 154fd4e5da5Sopenharmony_ci %24 = OpLabel 155fd4e5da5Sopenharmony_ci %25 = OpLoad %6 %19 156fd4e5da5Sopenharmony_ci %26 = OpSLessThan %17 %25 %16 157fd4e5da5Sopenharmony_ci OpBranchConditional %26 %21 %22 158fd4e5da5Sopenharmony_ci %21 = OpLabel 159fd4e5da5Sopenharmony_ci OpBranch %23 160fd4e5da5Sopenharmony_ci %23 = OpLabel 161fd4e5da5Sopenharmony_ci %27 = OpLoad %6 %19 162fd4e5da5Sopenharmony_ci %29 = OpIAdd %6 %27 %28 163fd4e5da5Sopenharmony_ci OpStore %19 %29 164fd4e5da5Sopenharmony_ci OpBranch %20 165fd4e5da5Sopenharmony_ci %22 = OpLabel 166fd4e5da5Sopenharmony_ci OpBranch %13 167fd4e5da5Sopenharmony_ci %13 = OpLabel 168fd4e5da5Sopenharmony_ci %30 = OpLoad %6 %8 169fd4e5da5Sopenharmony_ci %31 = OpIAdd %6 %30 %28 170fd4e5da5Sopenharmony_ci OpStore %8 %31 171fd4e5da5Sopenharmony_ci OpBranch %10 172fd4e5da5Sopenharmony_ci %12 = OpLabel 173fd4e5da5Sopenharmony_ci OpStore %32 %9 174fd4e5da5Sopenharmony_ci OpBranch %33 175fd4e5da5Sopenharmony_ci %33 = OpLabel 176fd4e5da5Sopenharmony_ci OpLoopMerge %35 %36 None 177fd4e5da5Sopenharmony_ci OpBranch %37 178fd4e5da5Sopenharmony_ci %37 = OpLabel 179fd4e5da5Sopenharmony_ci %38 = OpLoad %6 %32 180fd4e5da5Sopenharmony_ci %39 = OpSLessThan %17 %38 %16 181fd4e5da5Sopenharmony_ci OpBranchConditional %39 %34 %35 182fd4e5da5Sopenharmony_ci %34 = OpLabel 183fd4e5da5Sopenharmony_ci OpStore %40 %9 184fd4e5da5Sopenharmony_ci OpBranch %41 185fd4e5da5Sopenharmony_ci %41 = OpLabel 186fd4e5da5Sopenharmony_ci OpLoopMerge %43 %44 None 187fd4e5da5Sopenharmony_ci OpBranch %45 188fd4e5da5Sopenharmony_ci %45 = OpLabel 189fd4e5da5Sopenharmony_ci %46 = OpLoad %6 %40 190fd4e5da5Sopenharmony_ci %47 = OpSLessThan %17 %46 %16 191fd4e5da5Sopenharmony_ci OpBranchConditional %47 %42 %43 192fd4e5da5Sopenharmony_ci %42 = OpLabel 193fd4e5da5Sopenharmony_ci OpBranch %44 194fd4e5da5Sopenharmony_ci %44 = OpLabel 195fd4e5da5Sopenharmony_ci %48 = OpLoad %6 %40 196fd4e5da5Sopenharmony_ci %49 = OpIAdd %6 %48 %28 197fd4e5da5Sopenharmony_ci OpStore %40 %49 198fd4e5da5Sopenharmony_ci OpBranch %41 199fd4e5da5Sopenharmony_ci %43 = OpLabel 200fd4e5da5Sopenharmony_ci OpBranch %36 201fd4e5da5Sopenharmony_ci %36 = OpLabel 202fd4e5da5Sopenharmony_ci %50 = OpLoad %6 %32 203fd4e5da5Sopenharmony_ci %51 = OpIAdd %6 %50 %28 204fd4e5da5Sopenharmony_ci OpStore %32 %51 205fd4e5da5Sopenharmony_ci OpBranch %33 206fd4e5da5Sopenharmony_ci %35 = OpLabel 207fd4e5da5Sopenharmony_ci OpReturn 208fd4e5da5Sopenharmony_ci OpFunctionEnd 209fd4e5da5Sopenharmony_ci )"; 210fd4e5da5Sopenharmony_ci 211fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 212fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption); 213fd4e5da5Sopenharmony_ci const auto ops = StructuredLoopToSelectionReductionOpportunityFinder() 214fd4e5da5Sopenharmony_ci .GetAvailableOpportunities(context.get(), 0); 215fd4e5da5Sopenharmony_ci ASSERT_EQ(4, ops.size()); 216fd4e5da5Sopenharmony_ci 217fd4e5da5Sopenharmony_ci ASSERT_TRUE(ops[0]->PreconditionHolds()); 218fd4e5da5Sopenharmony_ci ops[0]->TryToApply(); 219fd4e5da5Sopenharmony_ci CheckValid(env, context.get()); 220fd4e5da5Sopenharmony_ci std::string after_op_0 = R"( 221fd4e5da5Sopenharmony_ci OpCapability Shader 222fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 223fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 224fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 225fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 226fd4e5da5Sopenharmony_ci OpSource ESSL 310 227fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 228fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 229fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 230fd4e5da5Sopenharmony_ci %7 = OpTypePointer Function %6 231fd4e5da5Sopenharmony_ci %9 = OpConstant %6 0 232fd4e5da5Sopenharmony_ci %16 = OpConstant %6 100 233fd4e5da5Sopenharmony_ci %17 = OpTypeBool 234fd4e5da5Sopenharmony_ci %28 = OpConstant %6 1 235fd4e5da5Sopenharmony_ci %52 = OpConstantTrue %17 236fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 237fd4e5da5Sopenharmony_ci %5 = OpLabel 238fd4e5da5Sopenharmony_ci %8 = OpVariable %7 Function 239fd4e5da5Sopenharmony_ci %19 = OpVariable %7 Function 240fd4e5da5Sopenharmony_ci %32 = OpVariable %7 Function 241fd4e5da5Sopenharmony_ci %40 = OpVariable %7 Function 242fd4e5da5Sopenharmony_ci OpStore %8 %9 243fd4e5da5Sopenharmony_ci OpBranch %10 244fd4e5da5Sopenharmony_ci %10 = OpLabel 245fd4e5da5Sopenharmony_ci OpSelectionMerge %12 None 246fd4e5da5Sopenharmony_ci OpBranchConditional %52 %14 %12 247fd4e5da5Sopenharmony_ci %14 = OpLabel 248fd4e5da5Sopenharmony_ci %15 = OpLoad %6 %8 249fd4e5da5Sopenharmony_ci %18 = OpSLessThan %17 %15 %16 250fd4e5da5Sopenharmony_ci OpBranchConditional %18 %11 %12 251fd4e5da5Sopenharmony_ci %11 = OpLabel 252fd4e5da5Sopenharmony_ci OpStore %19 %9 253fd4e5da5Sopenharmony_ci OpBranch %20 254fd4e5da5Sopenharmony_ci %20 = OpLabel 255fd4e5da5Sopenharmony_ci OpLoopMerge %22 %23 None 256fd4e5da5Sopenharmony_ci OpBranch %24 257fd4e5da5Sopenharmony_ci %24 = OpLabel 258fd4e5da5Sopenharmony_ci %25 = OpLoad %6 %19 259fd4e5da5Sopenharmony_ci %26 = OpSLessThan %17 %25 %16 260fd4e5da5Sopenharmony_ci OpBranchConditional %26 %21 %22 261fd4e5da5Sopenharmony_ci %21 = OpLabel 262fd4e5da5Sopenharmony_ci OpBranch %23 263fd4e5da5Sopenharmony_ci %23 = OpLabel 264fd4e5da5Sopenharmony_ci %27 = OpLoad %6 %19 265fd4e5da5Sopenharmony_ci %29 = OpIAdd %6 %27 %28 266fd4e5da5Sopenharmony_ci OpStore %19 %29 267fd4e5da5Sopenharmony_ci OpBranch %20 268fd4e5da5Sopenharmony_ci %22 = OpLabel 269fd4e5da5Sopenharmony_ci OpBranch %12 270fd4e5da5Sopenharmony_ci %13 = OpLabel 271fd4e5da5Sopenharmony_ci %30 = OpLoad %6 %8 272fd4e5da5Sopenharmony_ci %31 = OpIAdd %6 %30 %28 273fd4e5da5Sopenharmony_ci OpStore %8 %31 274fd4e5da5Sopenharmony_ci OpBranch %10 275fd4e5da5Sopenharmony_ci %12 = OpLabel 276fd4e5da5Sopenharmony_ci OpStore %32 %9 277fd4e5da5Sopenharmony_ci OpBranch %33 278fd4e5da5Sopenharmony_ci %33 = OpLabel 279fd4e5da5Sopenharmony_ci OpLoopMerge %35 %36 None 280fd4e5da5Sopenharmony_ci OpBranch %37 281fd4e5da5Sopenharmony_ci %37 = OpLabel 282fd4e5da5Sopenharmony_ci %38 = OpLoad %6 %32 283fd4e5da5Sopenharmony_ci %39 = OpSLessThan %17 %38 %16 284fd4e5da5Sopenharmony_ci OpBranchConditional %39 %34 %35 285fd4e5da5Sopenharmony_ci %34 = OpLabel 286fd4e5da5Sopenharmony_ci OpStore %40 %9 287fd4e5da5Sopenharmony_ci OpBranch %41 288fd4e5da5Sopenharmony_ci %41 = OpLabel 289fd4e5da5Sopenharmony_ci OpLoopMerge %43 %44 None 290fd4e5da5Sopenharmony_ci OpBranch %45 291fd4e5da5Sopenharmony_ci %45 = OpLabel 292fd4e5da5Sopenharmony_ci %46 = OpLoad %6 %40 293fd4e5da5Sopenharmony_ci %47 = OpSLessThan %17 %46 %16 294fd4e5da5Sopenharmony_ci OpBranchConditional %47 %42 %43 295fd4e5da5Sopenharmony_ci %42 = OpLabel 296fd4e5da5Sopenharmony_ci OpBranch %44 297fd4e5da5Sopenharmony_ci %44 = OpLabel 298fd4e5da5Sopenharmony_ci %48 = OpLoad %6 %40 299fd4e5da5Sopenharmony_ci %49 = OpIAdd %6 %48 %28 300fd4e5da5Sopenharmony_ci OpStore %40 %49 301fd4e5da5Sopenharmony_ci OpBranch %41 302fd4e5da5Sopenharmony_ci %43 = OpLabel 303fd4e5da5Sopenharmony_ci OpBranch %36 304fd4e5da5Sopenharmony_ci %36 = OpLabel 305fd4e5da5Sopenharmony_ci %50 = OpLoad %6 %32 306fd4e5da5Sopenharmony_ci %51 = OpIAdd %6 %50 %28 307fd4e5da5Sopenharmony_ci OpStore %32 %51 308fd4e5da5Sopenharmony_ci OpBranch %33 309fd4e5da5Sopenharmony_ci %35 = OpLabel 310fd4e5da5Sopenharmony_ci OpReturn 311fd4e5da5Sopenharmony_ci OpFunctionEnd 312fd4e5da5Sopenharmony_ci )"; 313fd4e5da5Sopenharmony_ci CheckEqual(env, after_op_0, context.get()); 314fd4e5da5Sopenharmony_ci 315fd4e5da5Sopenharmony_ci ASSERT_TRUE(ops[1]->PreconditionHolds()); 316fd4e5da5Sopenharmony_ci ops[1]->TryToApply(); 317fd4e5da5Sopenharmony_ci CheckValid(env, context.get()); 318fd4e5da5Sopenharmony_ci std::string after_op_1 = R"( 319fd4e5da5Sopenharmony_ci OpCapability Shader 320fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 321fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 322fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 323fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 324fd4e5da5Sopenharmony_ci OpSource ESSL 310 325fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 326fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 327fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 328fd4e5da5Sopenharmony_ci %7 = OpTypePointer Function %6 329fd4e5da5Sopenharmony_ci %9 = OpConstant %6 0 330fd4e5da5Sopenharmony_ci %16 = OpConstant %6 100 331fd4e5da5Sopenharmony_ci %17 = OpTypeBool 332fd4e5da5Sopenharmony_ci %28 = OpConstant %6 1 333fd4e5da5Sopenharmony_ci %52 = OpConstantTrue %17 334fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 335fd4e5da5Sopenharmony_ci %5 = OpLabel 336fd4e5da5Sopenharmony_ci %8 = OpVariable %7 Function 337fd4e5da5Sopenharmony_ci %19 = OpVariable %7 Function 338fd4e5da5Sopenharmony_ci %32 = OpVariable %7 Function 339fd4e5da5Sopenharmony_ci %40 = OpVariable %7 Function 340fd4e5da5Sopenharmony_ci OpStore %8 %9 341fd4e5da5Sopenharmony_ci OpBranch %10 342fd4e5da5Sopenharmony_ci %10 = OpLabel 343fd4e5da5Sopenharmony_ci OpSelectionMerge %12 None 344fd4e5da5Sopenharmony_ci OpBranchConditional %52 %14 %12 345fd4e5da5Sopenharmony_ci %14 = OpLabel 346fd4e5da5Sopenharmony_ci %15 = OpLoad %6 %8 347fd4e5da5Sopenharmony_ci %18 = OpSLessThan %17 %15 %16 348fd4e5da5Sopenharmony_ci OpBranchConditional %18 %11 %12 349fd4e5da5Sopenharmony_ci %11 = OpLabel 350fd4e5da5Sopenharmony_ci OpStore %19 %9 351fd4e5da5Sopenharmony_ci OpBranch %20 352fd4e5da5Sopenharmony_ci %20 = OpLabel 353fd4e5da5Sopenharmony_ci OpSelectionMerge %22 None 354fd4e5da5Sopenharmony_ci OpBranchConditional %52 %24 %22 355fd4e5da5Sopenharmony_ci %24 = OpLabel 356fd4e5da5Sopenharmony_ci %25 = OpLoad %6 %19 357fd4e5da5Sopenharmony_ci %26 = OpSLessThan %17 %25 %16 358fd4e5da5Sopenharmony_ci OpBranchConditional %26 %21 %22 359fd4e5da5Sopenharmony_ci %21 = OpLabel 360fd4e5da5Sopenharmony_ci OpBranch %22 361fd4e5da5Sopenharmony_ci %23 = OpLabel 362fd4e5da5Sopenharmony_ci %27 = OpLoad %6 %19 363fd4e5da5Sopenharmony_ci %29 = OpIAdd %6 %27 %28 364fd4e5da5Sopenharmony_ci OpStore %19 %29 365fd4e5da5Sopenharmony_ci OpBranch %20 366fd4e5da5Sopenharmony_ci %22 = OpLabel 367fd4e5da5Sopenharmony_ci OpBranch %12 368fd4e5da5Sopenharmony_ci %13 = OpLabel 369fd4e5da5Sopenharmony_ci %30 = OpLoad %6 %8 370fd4e5da5Sopenharmony_ci %31 = OpIAdd %6 %30 %28 371fd4e5da5Sopenharmony_ci OpStore %8 %31 372fd4e5da5Sopenharmony_ci OpBranch %10 373fd4e5da5Sopenharmony_ci %12 = OpLabel 374fd4e5da5Sopenharmony_ci OpStore %32 %9 375fd4e5da5Sopenharmony_ci OpBranch %33 376fd4e5da5Sopenharmony_ci %33 = OpLabel 377fd4e5da5Sopenharmony_ci OpLoopMerge %35 %36 None 378fd4e5da5Sopenharmony_ci OpBranch %37 379fd4e5da5Sopenharmony_ci %37 = OpLabel 380fd4e5da5Sopenharmony_ci %38 = OpLoad %6 %32 381fd4e5da5Sopenharmony_ci %39 = OpSLessThan %17 %38 %16 382fd4e5da5Sopenharmony_ci OpBranchConditional %39 %34 %35 383fd4e5da5Sopenharmony_ci %34 = OpLabel 384fd4e5da5Sopenharmony_ci OpStore %40 %9 385fd4e5da5Sopenharmony_ci OpBranch %41 386fd4e5da5Sopenharmony_ci %41 = OpLabel 387fd4e5da5Sopenharmony_ci OpLoopMerge %43 %44 None 388fd4e5da5Sopenharmony_ci OpBranch %45 389fd4e5da5Sopenharmony_ci %45 = OpLabel 390fd4e5da5Sopenharmony_ci %46 = OpLoad %6 %40 391fd4e5da5Sopenharmony_ci %47 = OpSLessThan %17 %46 %16 392fd4e5da5Sopenharmony_ci OpBranchConditional %47 %42 %43 393fd4e5da5Sopenharmony_ci %42 = OpLabel 394fd4e5da5Sopenharmony_ci OpBranch %44 395fd4e5da5Sopenharmony_ci %44 = OpLabel 396fd4e5da5Sopenharmony_ci %48 = OpLoad %6 %40 397fd4e5da5Sopenharmony_ci %49 = OpIAdd %6 %48 %28 398fd4e5da5Sopenharmony_ci OpStore %40 %49 399fd4e5da5Sopenharmony_ci OpBranch %41 400fd4e5da5Sopenharmony_ci %43 = OpLabel 401fd4e5da5Sopenharmony_ci OpBranch %36 402fd4e5da5Sopenharmony_ci %36 = OpLabel 403fd4e5da5Sopenharmony_ci %50 = OpLoad %6 %32 404fd4e5da5Sopenharmony_ci %51 = OpIAdd %6 %50 %28 405fd4e5da5Sopenharmony_ci OpStore %32 %51 406fd4e5da5Sopenharmony_ci OpBranch %33 407fd4e5da5Sopenharmony_ci %35 = OpLabel 408fd4e5da5Sopenharmony_ci OpReturn 409fd4e5da5Sopenharmony_ci OpFunctionEnd 410fd4e5da5Sopenharmony_ci )"; 411fd4e5da5Sopenharmony_ci CheckEqual(env, after_op_1, context.get()); 412fd4e5da5Sopenharmony_ci 413fd4e5da5Sopenharmony_ci ASSERT_TRUE(ops[2]->PreconditionHolds()); 414fd4e5da5Sopenharmony_ci ops[2]->TryToApply(); 415fd4e5da5Sopenharmony_ci CheckValid(env, context.get()); 416fd4e5da5Sopenharmony_ci std::string after_op_2 = R"( 417fd4e5da5Sopenharmony_ci OpCapability Shader 418fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 419fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 420fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 421fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 422fd4e5da5Sopenharmony_ci OpSource ESSL 310 423fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 424fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 425fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 426fd4e5da5Sopenharmony_ci %7 = OpTypePointer Function %6 427fd4e5da5Sopenharmony_ci %9 = OpConstant %6 0 428fd4e5da5Sopenharmony_ci %16 = OpConstant %6 100 429fd4e5da5Sopenharmony_ci %17 = OpTypeBool 430fd4e5da5Sopenharmony_ci %28 = OpConstant %6 1 431fd4e5da5Sopenharmony_ci %52 = OpConstantTrue %17 432fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 433fd4e5da5Sopenharmony_ci %5 = OpLabel 434fd4e5da5Sopenharmony_ci %8 = OpVariable %7 Function 435fd4e5da5Sopenharmony_ci %19 = OpVariable %7 Function 436fd4e5da5Sopenharmony_ci %32 = OpVariable %7 Function 437fd4e5da5Sopenharmony_ci %40 = OpVariable %7 Function 438fd4e5da5Sopenharmony_ci OpStore %8 %9 439fd4e5da5Sopenharmony_ci OpBranch %10 440fd4e5da5Sopenharmony_ci %10 = OpLabel 441fd4e5da5Sopenharmony_ci OpSelectionMerge %12 None 442fd4e5da5Sopenharmony_ci OpBranchConditional %52 %14 %12 443fd4e5da5Sopenharmony_ci %14 = OpLabel 444fd4e5da5Sopenharmony_ci %15 = OpLoad %6 %8 445fd4e5da5Sopenharmony_ci %18 = OpSLessThan %17 %15 %16 446fd4e5da5Sopenharmony_ci OpBranchConditional %18 %11 %12 447fd4e5da5Sopenharmony_ci %11 = OpLabel 448fd4e5da5Sopenharmony_ci OpStore %19 %9 449fd4e5da5Sopenharmony_ci OpBranch %20 450fd4e5da5Sopenharmony_ci %20 = OpLabel 451fd4e5da5Sopenharmony_ci OpSelectionMerge %22 None 452fd4e5da5Sopenharmony_ci OpBranchConditional %52 %24 %22 453fd4e5da5Sopenharmony_ci %24 = OpLabel 454fd4e5da5Sopenharmony_ci %25 = OpLoad %6 %19 455fd4e5da5Sopenharmony_ci %26 = OpSLessThan %17 %25 %16 456fd4e5da5Sopenharmony_ci OpBranchConditional %26 %21 %22 457fd4e5da5Sopenharmony_ci %21 = OpLabel 458fd4e5da5Sopenharmony_ci OpBranch %22 459fd4e5da5Sopenharmony_ci %23 = OpLabel 460fd4e5da5Sopenharmony_ci %27 = OpLoad %6 %19 461fd4e5da5Sopenharmony_ci %29 = OpIAdd %6 %27 %28 462fd4e5da5Sopenharmony_ci OpStore %19 %29 463fd4e5da5Sopenharmony_ci OpBranch %20 464fd4e5da5Sopenharmony_ci %22 = OpLabel 465fd4e5da5Sopenharmony_ci OpBranch %12 466fd4e5da5Sopenharmony_ci %13 = OpLabel 467fd4e5da5Sopenharmony_ci %30 = OpLoad %6 %8 468fd4e5da5Sopenharmony_ci %31 = OpIAdd %6 %30 %28 469fd4e5da5Sopenharmony_ci OpStore %8 %31 470fd4e5da5Sopenharmony_ci OpBranch %10 471fd4e5da5Sopenharmony_ci %12 = OpLabel 472fd4e5da5Sopenharmony_ci OpStore %32 %9 473fd4e5da5Sopenharmony_ci OpBranch %33 474fd4e5da5Sopenharmony_ci %33 = OpLabel 475fd4e5da5Sopenharmony_ci OpSelectionMerge %35 None 476fd4e5da5Sopenharmony_ci OpBranchConditional %52 %37 %35 477fd4e5da5Sopenharmony_ci %37 = OpLabel 478fd4e5da5Sopenharmony_ci %38 = OpLoad %6 %32 479fd4e5da5Sopenharmony_ci %39 = OpSLessThan %17 %38 %16 480fd4e5da5Sopenharmony_ci OpBranchConditional %39 %34 %35 481fd4e5da5Sopenharmony_ci %34 = OpLabel 482fd4e5da5Sopenharmony_ci OpStore %40 %9 483fd4e5da5Sopenharmony_ci OpBranch %41 484fd4e5da5Sopenharmony_ci %41 = OpLabel 485fd4e5da5Sopenharmony_ci OpLoopMerge %43 %44 None 486fd4e5da5Sopenharmony_ci OpBranch %45 487fd4e5da5Sopenharmony_ci %45 = OpLabel 488fd4e5da5Sopenharmony_ci %46 = OpLoad %6 %40 489fd4e5da5Sopenharmony_ci %47 = OpSLessThan %17 %46 %16 490fd4e5da5Sopenharmony_ci OpBranchConditional %47 %42 %43 491fd4e5da5Sopenharmony_ci %42 = OpLabel 492fd4e5da5Sopenharmony_ci OpBranch %44 493fd4e5da5Sopenharmony_ci %44 = OpLabel 494fd4e5da5Sopenharmony_ci %48 = OpLoad %6 %40 495fd4e5da5Sopenharmony_ci %49 = OpIAdd %6 %48 %28 496fd4e5da5Sopenharmony_ci OpStore %40 %49 497fd4e5da5Sopenharmony_ci OpBranch %41 498fd4e5da5Sopenharmony_ci %43 = OpLabel 499fd4e5da5Sopenharmony_ci OpBranch %35 500fd4e5da5Sopenharmony_ci %36 = OpLabel 501fd4e5da5Sopenharmony_ci %50 = OpLoad %6 %32 502fd4e5da5Sopenharmony_ci %51 = OpIAdd %6 %50 %28 503fd4e5da5Sopenharmony_ci OpStore %32 %51 504fd4e5da5Sopenharmony_ci OpBranch %33 505fd4e5da5Sopenharmony_ci %35 = OpLabel 506fd4e5da5Sopenharmony_ci OpReturn 507fd4e5da5Sopenharmony_ci OpFunctionEnd 508fd4e5da5Sopenharmony_ci )"; 509fd4e5da5Sopenharmony_ci CheckEqual(env, after_op_2, context.get()); 510fd4e5da5Sopenharmony_ci 511fd4e5da5Sopenharmony_ci ASSERT_TRUE(ops[3]->PreconditionHolds()); 512fd4e5da5Sopenharmony_ci ops[3]->TryToApply(); 513fd4e5da5Sopenharmony_ci CheckValid(env, context.get()); 514fd4e5da5Sopenharmony_ci std::string after_op_3 = R"( 515fd4e5da5Sopenharmony_ci OpCapability Shader 516fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 517fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 518fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 519fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 520fd4e5da5Sopenharmony_ci OpSource ESSL 310 521fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 522fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 523fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 524fd4e5da5Sopenharmony_ci %7 = OpTypePointer Function %6 525fd4e5da5Sopenharmony_ci %9 = OpConstant %6 0 526fd4e5da5Sopenharmony_ci %16 = OpConstant %6 100 527fd4e5da5Sopenharmony_ci %17 = OpTypeBool 528fd4e5da5Sopenharmony_ci %28 = OpConstant %6 1 529fd4e5da5Sopenharmony_ci %52 = OpConstantTrue %17 530fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 531fd4e5da5Sopenharmony_ci %5 = OpLabel 532fd4e5da5Sopenharmony_ci %8 = OpVariable %7 Function 533fd4e5da5Sopenharmony_ci %19 = OpVariable %7 Function 534fd4e5da5Sopenharmony_ci %32 = OpVariable %7 Function 535fd4e5da5Sopenharmony_ci %40 = OpVariable %7 Function 536fd4e5da5Sopenharmony_ci OpStore %8 %9 537fd4e5da5Sopenharmony_ci OpBranch %10 538fd4e5da5Sopenharmony_ci %10 = OpLabel 539fd4e5da5Sopenharmony_ci OpSelectionMerge %12 None 540fd4e5da5Sopenharmony_ci OpBranchConditional %52 %14 %12 541fd4e5da5Sopenharmony_ci %14 = OpLabel 542fd4e5da5Sopenharmony_ci %15 = OpLoad %6 %8 543fd4e5da5Sopenharmony_ci %18 = OpSLessThan %17 %15 %16 544fd4e5da5Sopenharmony_ci OpBranchConditional %18 %11 %12 545fd4e5da5Sopenharmony_ci %11 = OpLabel 546fd4e5da5Sopenharmony_ci OpStore %19 %9 547fd4e5da5Sopenharmony_ci OpBranch %20 548fd4e5da5Sopenharmony_ci %20 = OpLabel 549fd4e5da5Sopenharmony_ci OpSelectionMerge %22 None 550fd4e5da5Sopenharmony_ci OpBranchConditional %52 %24 %22 551fd4e5da5Sopenharmony_ci %24 = OpLabel 552fd4e5da5Sopenharmony_ci %25 = OpLoad %6 %19 553fd4e5da5Sopenharmony_ci %26 = OpSLessThan %17 %25 %16 554fd4e5da5Sopenharmony_ci OpBranchConditional %26 %21 %22 555fd4e5da5Sopenharmony_ci %21 = OpLabel 556fd4e5da5Sopenharmony_ci OpBranch %22 557fd4e5da5Sopenharmony_ci %23 = OpLabel 558fd4e5da5Sopenharmony_ci %27 = OpLoad %6 %19 559fd4e5da5Sopenharmony_ci %29 = OpIAdd %6 %27 %28 560fd4e5da5Sopenharmony_ci OpStore %19 %29 561fd4e5da5Sopenharmony_ci OpBranch %20 562fd4e5da5Sopenharmony_ci %22 = OpLabel 563fd4e5da5Sopenharmony_ci OpBranch %12 564fd4e5da5Sopenharmony_ci %13 = OpLabel 565fd4e5da5Sopenharmony_ci %30 = OpLoad %6 %8 566fd4e5da5Sopenharmony_ci %31 = OpIAdd %6 %30 %28 567fd4e5da5Sopenharmony_ci OpStore %8 %31 568fd4e5da5Sopenharmony_ci OpBranch %10 569fd4e5da5Sopenharmony_ci %12 = OpLabel 570fd4e5da5Sopenharmony_ci OpStore %32 %9 571fd4e5da5Sopenharmony_ci OpBranch %33 572fd4e5da5Sopenharmony_ci %33 = OpLabel 573fd4e5da5Sopenharmony_ci OpSelectionMerge %35 None 574fd4e5da5Sopenharmony_ci OpBranchConditional %52 %37 %35 575fd4e5da5Sopenharmony_ci %37 = OpLabel 576fd4e5da5Sopenharmony_ci %38 = OpLoad %6 %32 577fd4e5da5Sopenharmony_ci %39 = OpSLessThan %17 %38 %16 578fd4e5da5Sopenharmony_ci OpBranchConditional %39 %34 %35 579fd4e5da5Sopenharmony_ci %34 = OpLabel 580fd4e5da5Sopenharmony_ci OpStore %40 %9 581fd4e5da5Sopenharmony_ci OpBranch %41 582fd4e5da5Sopenharmony_ci %41 = OpLabel 583fd4e5da5Sopenharmony_ci OpSelectionMerge %43 None 584fd4e5da5Sopenharmony_ci OpBranchConditional %52 %45 %43 585fd4e5da5Sopenharmony_ci %45 = OpLabel 586fd4e5da5Sopenharmony_ci %46 = OpLoad %6 %40 587fd4e5da5Sopenharmony_ci %47 = OpSLessThan %17 %46 %16 588fd4e5da5Sopenharmony_ci OpBranchConditional %47 %42 %43 589fd4e5da5Sopenharmony_ci %42 = OpLabel 590fd4e5da5Sopenharmony_ci OpBranch %43 591fd4e5da5Sopenharmony_ci %44 = OpLabel 592fd4e5da5Sopenharmony_ci %48 = OpLoad %6 %40 593fd4e5da5Sopenharmony_ci %49 = OpIAdd %6 %48 %28 594fd4e5da5Sopenharmony_ci OpStore %40 %49 595fd4e5da5Sopenharmony_ci OpBranch %41 596fd4e5da5Sopenharmony_ci %43 = OpLabel 597fd4e5da5Sopenharmony_ci OpBranch %35 598fd4e5da5Sopenharmony_ci %36 = OpLabel 599fd4e5da5Sopenharmony_ci %50 = OpLoad %6 %32 600fd4e5da5Sopenharmony_ci %51 = OpIAdd %6 %50 %28 601fd4e5da5Sopenharmony_ci OpStore %32 %51 602fd4e5da5Sopenharmony_ci OpBranch %33 603fd4e5da5Sopenharmony_ci %35 = OpLabel 604fd4e5da5Sopenharmony_ci OpReturn 605fd4e5da5Sopenharmony_ci OpFunctionEnd 606fd4e5da5Sopenharmony_ci )"; 607fd4e5da5Sopenharmony_ci CheckEqual(env, after_op_3, context.get()); 608fd4e5da5Sopenharmony_ci} 609fd4e5da5Sopenharmony_ci 610fd4e5da5Sopenharmony_ciTEST(StructuredLoopToSelectionReductionPassTest, LoopyShader3) { 611fd4e5da5Sopenharmony_ci std::string shader = R"( 612fd4e5da5Sopenharmony_ci OpCapability Shader 613fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 614fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 615fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 616fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 617fd4e5da5Sopenharmony_ci OpSource ESSL 310 618fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 619fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 620fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 621fd4e5da5Sopenharmony_ci %7 = OpTypePointer Function %6 622fd4e5da5Sopenharmony_ci %9 = OpConstant %6 10 623fd4e5da5Sopenharmony_ci %16 = OpConstant %6 0 624fd4e5da5Sopenharmony_ci %17 = OpTypeBool 625fd4e5da5Sopenharmony_ci %20 = OpConstant %6 1 626fd4e5da5Sopenharmony_ci %23 = OpConstant %6 3 627fd4e5da5Sopenharmony_ci %40 = OpConstant %6 5 628fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 629fd4e5da5Sopenharmony_ci %5 = OpLabel 630fd4e5da5Sopenharmony_ci %8 = OpVariable %7 Function 631fd4e5da5Sopenharmony_ci OpStore %8 %9 632fd4e5da5Sopenharmony_ci OpBranch %10 633fd4e5da5Sopenharmony_ci %10 = OpLabel 634fd4e5da5Sopenharmony_ci OpLoopMerge %12 %13 None 635fd4e5da5Sopenharmony_ci OpBranch %14 636fd4e5da5Sopenharmony_ci %14 = OpLabel 637fd4e5da5Sopenharmony_ci %15 = OpLoad %6 %8 638fd4e5da5Sopenharmony_ci %18 = OpSGreaterThan %17 %15 %16 639fd4e5da5Sopenharmony_ci OpBranchConditional %18 %11 %12 640fd4e5da5Sopenharmony_ci %11 = OpLabel 641fd4e5da5Sopenharmony_ci %19 = OpLoad %6 %8 642fd4e5da5Sopenharmony_ci %21 = OpISub %6 %19 %20 643fd4e5da5Sopenharmony_ci OpStore %8 %21 644fd4e5da5Sopenharmony_ci %22 = OpLoad %6 %8 645fd4e5da5Sopenharmony_ci %24 = OpSLessThan %17 %22 %23 646fd4e5da5Sopenharmony_ci OpSelectionMerge %26 None 647fd4e5da5Sopenharmony_ci OpBranchConditional %24 %25 %26 648fd4e5da5Sopenharmony_ci %25 = OpLabel 649fd4e5da5Sopenharmony_ci OpBranch %13 650fd4e5da5Sopenharmony_ci %26 = OpLabel 651fd4e5da5Sopenharmony_ci OpBranch %28 652fd4e5da5Sopenharmony_ci %28 = OpLabel 653fd4e5da5Sopenharmony_ci OpLoopMerge %30 %31 None 654fd4e5da5Sopenharmony_ci OpBranch %29 655fd4e5da5Sopenharmony_ci %29 = OpLabel 656fd4e5da5Sopenharmony_ci %32 = OpLoad %6 %8 657fd4e5da5Sopenharmony_ci %33 = OpISub %6 %32 %20 658fd4e5da5Sopenharmony_ci OpStore %8 %33 659fd4e5da5Sopenharmony_ci %34 = OpLoad %6 %8 660fd4e5da5Sopenharmony_ci %35 = OpIEqual %17 %34 %20 661fd4e5da5Sopenharmony_ci OpSelectionMerge %37 None 662fd4e5da5Sopenharmony_ci OpBranchConditional %35 %36 %37 663fd4e5da5Sopenharmony_ci %36 = OpLabel 664fd4e5da5Sopenharmony_ci OpReturn ; This return spoils everything: it means the merge does not post-dominate the header. 665fd4e5da5Sopenharmony_ci %37 = OpLabel 666fd4e5da5Sopenharmony_ci OpBranch %31 667fd4e5da5Sopenharmony_ci %31 = OpLabel 668fd4e5da5Sopenharmony_ci %39 = OpLoad %6 %8 669fd4e5da5Sopenharmony_ci %41 = OpSGreaterThan %17 %39 %40 670fd4e5da5Sopenharmony_ci OpBranchConditional %41 %28 %30 671fd4e5da5Sopenharmony_ci %30 = OpLabel 672fd4e5da5Sopenharmony_ci OpBranch %13 673fd4e5da5Sopenharmony_ci %13 = OpLabel 674fd4e5da5Sopenharmony_ci OpBranch %10 675fd4e5da5Sopenharmony_ci %12 = OpLabel 676fd4e5da5Sopenharmony_ci OpReturn 677fd4e5da5Sopenharmony_ci OpFunctionEnd 678fd4e5da5Sopenharmony_ci )"; 679fd4e5da5Sopenharmony_ci 680fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 681fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption); 682fd4e5da5Sopenharmony_ci const auto ops = StructuredLoopToSelectionReductionOpportunityFinder() 683fd4e5da5Sopenharmony_ci .GetAvailableOpportunities(context.get(), 0); 684fd4e5da5Sopenharmony_ci ASSERT_EQ(0, ops.size()); 685fd4e5da5Sopenharmony_ci} 686fd4e5da5Sopenharmony_ci 687fd4e5da5Sopenharmony_ciTEST(StructuredLoopToSelectionReductionPassTest, LoopyShader4) { 688fd4e5da5Sopenharmony_ci std::string shader = R"( 689fd4e5da5Sopenharmony_ci OpCapability Shader 690fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 691fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 692fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 693fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 694fd4e5da5Sopenharmony_ci OpSource ESSL 310 695fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 696fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 697fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 698fd4e5da5Sopenharmony_ci %7 = OpTypePointer Function %6 699fd4e5da5Sopenharmony_ci %8 = OpTypeFunction %6 %7 700fd4e5da5Sopenharmony_ci %13 = OpConstant %6 0 701fd4e5da5Sopenharmony_ci %22 = OpTypeBool 702fd4e5da5Sopenharmony_ci %25 = OpConstant %6 1 703fd4e5da5Sopenharmony_ci %39 = OpConstant %6 100 704fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 705fd4e5da5Sopenharmony_ci %5 = OpLabel 706fd4e5da5Sopenharmony_ci %45 = OpVariable %7 Function 707fd4e5da5Sopenharmony_ci %46 = OpVariable %7 Function 708fd4e5da5Sopenharmony_ci %47 = OpVariable %7 Function 709fd4e5da5Sopenharmony_ci %32 = OpVariable %7 Function 710fd4e5da5Sopenharmony_ci %42 = OpVariable %7 Function 711fd4e5da5Sopenharmony_ci OpStore %32 %13 712fd4e5da5Sopenharmony_ci OpBranch %33 713fd4e5da5Sopenharmony_ci %33 = OpLabel 714fd4e5da5Sopenharmony_ci OpLoopMerge %35 %36 None 715fd4e5da5Sopenharmony_ci OpBranch %37 716fd4e5da5Sopenharmony_ci %37 = OpLabel 717fd4e5da5Sopenharmony_ci %38 = OpLoad %6 %32 718fd4e5da5Sopenharmony_ci %40 = OpSLessThan %22 %38 %39 719fd4e5da5Sopenharmony_ci OpBranchConditional %40 %34 %35 720fd4e5da5Sopenharmony_ci %34 = OpLabel 721fd4e5da5Sopenharmony_ci OpBranch %36 722fd4e5da5Sopenharmony_ci %36 = OpLabel 723fd4e5da5Sopenharmony_ci %41 = OpLoad %6 %32 724fd4e5da5Sopenharmony_ci OpStore %42 %25 725fd4e5da5Sopenharmony_ci OpStore %45 %13 726fd4e5da5Sopenharmony_ci OpStore %46 %13 727fd4e5da5Sopenharmony_ci OpBranch %48 728fd4e5da5Sopenharmony_ci %48 = OpLabel 729fd4e5da5Sopenharmony_ci OpLoopMerge %49 %50 None 730fd4e5da5Sopenharmony_ci OpBranch %51 731fd4e5da5Sopenharmony_ci %51 = OpLabel 732fd4e5da5Sopenharmony_ci %52 = OpLoad %6 %46 733fd4e5da5Sopenharmony_ci %53 = OpLoad %6 %42 734fd4e5da5Sopenharmony_ci %54 = OpSLessThan %22 %52 %53 735fd4e5da5Sopenharmony_ci OpBranchConditional %54 %55 %49 736fd4e5da5Sopenharmony_ci %55 = OpLabel 737fd4e5da5Sopenharmony_ci %56 = OpLoad %6 %45 738fd4e5da5Sopenharmony_ci %57 = OpIAdd %6 %56 %25 739fd4e5da5Sopenharmony_ci OpStore %45 %57 740fd4e5da5Sopenharmony_ci OpBranch %50 741fd4e5da5Sopenharmony_ci %50 = OpLabel 742fd4e5da5Sopenharmony_ci %58 = OpLoad %6 %46 743fd4e5da5Sopenharmony_ci %59 = OpIAdd %6 %58 %25 744fd4e5da5Sopenharmony_ci OpStore %46 %59 745fd4e5da5Sopenharmony_ci OpBranch %48 746fd4e5da5Sopenharmony_ci %49 = OpLabel 747fd4e5da5Sopenharmony_ci %60 = OpLoad %6 %45 748fd4e5da5Sopenharmony_ci OpStore %47 %60 749fd4e5da5Sopenharmony_ci %43 = OpLoad %6 %47 750fd4e5da5Sopenharmony_ci %44 = OpIAdd %6 %41 %43 751fd4e5da5Sopenharmony_ci OpStore %32 %44 752fd4e5da5Sopenharmony_ci OpBranch %33 753fd4e5da5Sopenharmony_ci %35 = OpLabel 754fd4e5da5Sopenharmony_ci OpReturn 755fd4e5da5Sopenharmony_ci OpFunctionEnd 756fd4e5da5Sopenharmony_ci )"; 757fd4e5da5Sopenharmony_ci 758fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 759fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption); 760fd4e5da5Sopenharmony_ci const auto ops = StructuredLoopToSelectionReductionOpportunityFinder() 761fd4e5da5Sopenharmony_ci .GetAvailableOpportunities(context.get(), 0); 762fd4e5da5Sopenharmony_ci 763fd4e5da5Sopenharmony_ci // Initially there are two opportunities. 764fd4e5da5Sopenharmony_ci ASSERT_EQ(2, ops.size()); 765fd4e5da5Sopenharmony_ci 766fd4e5da5Sopenharmony_ci ASSERT_TRUE(ops[0]->PreconditionHolds()); 767fd4e5da5Sopenharmony_ci ops[0]->TryToApply(); 768fd4e5da5Sopenharmony_ci CheckValid(env, context.get()); 769fd4e5da5Sopenharmony_ci std::string after_op_0 = R"( 770fd4e5da5Sopenharmony_ci OpCapability Shader 771fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 772fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 773fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 774fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 775fd4e5da5Sopenharmony_ci OpSource ESSL 310 776fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 777fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 778fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 779fd4e5da5Sopenharmony_ci %7 = OpTypePointer Function %6 780fd4e5da5Sopenharmony_ci %8 = OpTypeFunction %6 %7 781fd4e5da5Sopenharmony_ci %13 = OpConstant %6 0 782fd4e5da5Sopenharmony_ci %22 = OpTypeBool 783fd4e5da5Sopenharmony_ci %25 = OpConstant %6 1 784fd4e5da5Sopenharmony_ci %39 = OpConstant %6 100 785fd4e5da5Sopenharmony_ci %61 = OpConstantTrue %22 786fd4e5da5Sopenharmony_ci %62 = OpUndef %6 787fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 788fd4e5da5Sopenharmony_ci %5 = OpLabel 789fd4e5da5Sopenharmony_ci %45 = OpVariable %7 Function 790fd4e5da5Sopenharmony_ci %46 = OpVariable %7 Function 791fd4e5da5Sopenharmony_ci %47 = OpVariable %7 Function 792fd4e5da5Sopenharmony_ci %32 = OpVariable %7 Function 793fd4e5da5Sopenharmony_ci %42 = OpVariable %7 Function 794fd4e5da5Sopenharmony_ci OpStore %32 %13 795fd4e5da5Sopenharmony_ci OpBranch %33 796fd4e5da5Sopenharmony_ci %33 = OpLabel 797fd4e5da5Sopenharmony_ci OpSelectionMerge %35 None 798fd4e5da5Sopenharmony_ci OpBranchConditional %61 %37 %35 799fd4e5da5Sopenharmony_ci %37 = OpLabel 800fd4e5da5Sopenharmony_ci %38 = OpLoad %6 %32 801fd4e5da5Sopenharmony_ci %40 = OpSLessThan %22 %38 %39 802fd4e5da5Sopenharmony_ci OpBranchConditional %40 %34 %35 803fd4e5da5Sopenharmony_ci %34 = OpLabel 804fd4e5da5Sopenharmony_ci OpBranch %35 805fd4e5da5Sopenharmony_ci %36 = OpLabel 806fd4e5da5Sopenharmony_ci %41 = OpLoad %6 %32 807fd4e5da5Sopenharmony_ci OpStore %42 %25 808fd4e5da5Sopenharmony_ci OpStore %45 %13 809fd4e5da5Sopenharmony_ci OpStore %46 %13 810fd4e5da5Sopenharmony_ci OpBranch %48 811fd4e5da5Sopenharmony_ci %48 = OpLabel 812fd4e5da5Sopenharmony_ci OpLoopMerge %49 %50 None 813fd4e5da5Sopenharmony_ci OpBranch %51 814fd4e5da5Sopenharmony_ci %51 = OpLabel 815fd4e5da5Sopenharmony_ci %52 = OpLoad %6 %46 816fd4e5da5Sopenharmony_ci %53 = OpLoad %6 %42 817fd4e5da5Sopenharmony_ci %54 = OpSLessThan %22 %52 %53 818fd4e5da5Sopenharmony_ci OpBranchConditional %54 %55 %49 819fd4e5da5Sopenharmony_ci %55 = OpLabel 820fd4e5da5Sopenharmony_ci %56 = OpLoad %6 %45 821fd4e5da5Sopenharmony_ci %57 = OpIAdd %6 %56 %25 822fd4e5da5Sopenharmony_ci OpStore %45 %57 823fd4e5da5Sopenharmony_ci OpBranch %50 824fd4e5da5Sopenharmony_ci %50 = OpLabel 825fd4e5da5Sopenharmony_ci %58 = OpLoad %6 %46 826fd4e5da5Sopenharmony_ci %59 = OpIAdd %6 %58 %25 827fd4e5da5Sopenharmony_ci OpStore %46 %59 828fd4e5da5Sopenharmony_ci OpBranch %48 829fd4e5da5Sopenharmony_ci %49 = OpLabel 830fd4e5da5Sopenharmony_ci %60 = OpLoad %6 %45 831fd4e5da5Sopenharmony_ci OpStore %47 %60 832fd4e5da5Sopenharmony_ci %43 = OpLoad %6 %47 833fd4e5da5Sopenharmony_ci %44 = OpIAdd %6 %62 %43 834fd4e5da5Sopenharmony_ci OpStore %32 %44 835fd4e5da5Sopenharmony_ci OpBranch %33 836fd4e5da5Sopenharmony_ci %35 = OpLabel 837fd4e5da5Sopenharmony_ci OpReturn 838fd4e5da5Sopenharmony_ci OpFunctionEnd 839fd4e5da5Sopenharmony_ci )"; 840fd4e5da5Sopenharmony_ci CheckEqual(env, after_op_0, context.get()); 841fd4e5da5Sopenharmony_ci 842fd4e5da5Sopenharmony_ci // Applying the first opportunity has killed the second opportunity, because 843fd4e5da5Sopenharmony_ci // there was a loop embedded in the continue target of the loop we have just 844fd4e5da5Sopenharmony_ci // eliminated; the continue-embedded loop is now unreachable. 845fd4e5da5Sopenharmony_ci ASSERT_FALSE(ops[1]->PreconditionHolds()); 846fd4e5da5Sopenharmony_ci} 847fd4e5da5Sopenharmony_ci 848fd4e5da5Sopenharmony_ciTEST(StructuredLoopToSelectionReductionPassTest, ConditionalBreak1) { 849fd4e5da5Sopenharmony_ci std::string shader = R"( 850fd4e5da5Sopenharmony_ci OpCapability Shader 851fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 852fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 853fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 854fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 855fd4e5da5Sopenharmony_ci OpSource ESSL 310 856fd4e5da5Sopenharmony_ci OpName %4 "main" 857fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 858fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 859fd4e5da5Sopenharmony_ci %10 = OpTypeBool 860fd4e5da5Sopenharmony_ci %11 = OpConstantFalse %10 861fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 862fd4e5da5Sopenharmony_ci %5 = OpLabel 863fd4e5da5Sopenharmony_ci OpBranch %6 864fd4e5da5Sopenharmony_ci %6 = OpLabel 865fd4e5da5Sopenharmony_ci OpLoopMerge %8 %9 None 866fd4e5da5Sopenharmony_ci OpBranch %7 867fd4e5da5Sopenharmony_ci %7 = OpLabel 868fd4e5da5Sopenharmony_ci OpSelectionMerge %13 None 869fd4e5da5Sopenharmony_ci OpBranchConditional %11 %12 %13 870fd4e5da5Sopenharmony_ci %12 = OpLabel 871fd4e5da5Sopenharmony_ci OpBranch %8 872fd4e5da5Sopenharmony_ci %13 = OpLabel 873fd4e5da5Sopenharmony_ci OpBranch %9 874fd4e5da5Sopenharmony_ci %9 = OpLabel 875fd4e5da5Sopenharmony_ci OpBranchConditional %11 %6 %8 876fd4e5da5Sopenharmony_ci %8 = OpLabel 877fd4e5da5Sopenharmony_ci OpReturn 878fd4e5da5Sopenharmony_ci OpFunctionEnd 879fd4e5da5Sopenharmony_ci )"; 880fd4e5da5Sopenharmony_ci 881fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 882fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption); 883fd4e5da5Sopenharmony_ci const auto ops = StructuredLoopToSelectionReductionOpportunityFinder() 884fd4e5da5Sopenharmony_ci .GetAvailableOpportunities(context.get(), 0); 885fd4e5da5Sopenharmony_ci ASSERT_EQ(1, ops.size()); 886fd4e5da5Sopenharmony_ci 887fd4e5da5Sopenharmony_ci ASSERT_TRUE(ops[0]->PreconditionHolds()); 888fd4e5da5Sopenharmony_ci ops[0]->TryToApply(); 889fd4e5da5Sopenharmony_ci CheckValid(env, context.get()); 890fd4e5da5Sopenharmony_ci std::string after_op_0 = R"( 891fd4e5da5Sopenharmony_ci OpCapability Shader 892fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 893fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 894fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 895fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 896fd4e5da5Sopenharmony_ci OpSource ESSL 310 897fd4e5da5Sopenharmony_ci OpName %4 "main" 898fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 899fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 900fd4e5da5Sopenharmony_ci %10 = OpTypeBool 901fd4e5da5Sopenharmony_ci %11 = OpConstantFalse %10 902fd4e5da5Sopenharmony_ci %14 = OpConstantTrue %10 903fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 904fd4e5da5Sopenharmony_ci %5 = OpLabel 905fd4e5da5Sopenharmony_ci OpBranch %6 906fd4e5da5Sopenharmony_ci %6 = OpLabel 907fd4e5da5Sopenharmony_ci OpSelectionMerge %8 None 908fd4e5da5Sopenharmony_ci OpBranchConditional %14 %7 %8 909fd4e5da5Sopenharmony_ci %7 = OpLabel 910fd4e5da5Sopenharmony_ci OpSelectionMerge %13 None 911fd4e5da5Sopenharmony_ci OpBranchConditional %11 %12 %13 912fd4e5da5Sopenharmony_ci %12 = OpLabel 913fd4e5da5Sopenharmony_ci OpBranch %13 914fd4e5da5Sopenharmony_ci %13 = OpLabel 915fd4e5da5Sopenharmony_ci OpBranch %8 916fd4e5da5Sopenharmony_ci %9 = OpLabel 917fd4e5da5Sopenharmony_ci OpBranchConditional %11 %6 %8 918fd4e5da5Sopenharmony_ci %8 = OpLabel 919fd4e5da5Sopenharmony_ci OpReturn 920fd4e5da5Sopenharmony_ci OpFunctionEnd 921fd4e5da5Sopenharmony_ci )"; 922fd4e5da5Sopenharmony_ci CheckEqual(env, after_op_0, context.get()); 923fd4e5da5Sopenharmony_ci} 924fd4e5da5Sopenharmony_ci 925fd4e5da5Sopenharmony_ciTEST(StructuredLoopToSelectionReductionPassTest, ConditionalBreak2) { 926fd4e5da5Sopenharmony_ci std::string shader = R"( 927fd4e5da5Sopenharmony_ci OpCapability Shader 928fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 929fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 930fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 931fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 932fd4e5da5Sopenharmony_ci OpSource ESSL 310 933fd4e5da5Sopenharmony_ci OpName %4 "main" 934fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 935fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 936fd4e5da5Sopenharmony_ci %10 = OpTypeBool 937fd4e5da5Sopenharmony_ci %11 = OpConstantFalse %10 938fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 939fd4e5da5Sopenharmony_ci %5 = OpLabel 940fd4e5da5Sopenharmony_ci OpBranch %6 941fd4e5da5Sopenharmony_ci %6 = OpLabel 942fd4e5da5Sopenharmony_ci OpLoopMerge %8 %9 None 943fd4e5da5Sopenharmony_ci OpBranch %7 944fd4e5da5Sopenharmony_ci %7 = OpLabel 945fd4e5da5Sopenharmony_ci OpSelectionMerge %13 None 946fd4e5da5Sopenharmony_ci OpBranchConditional %11 %8 %13 947fd4e5da5Sopenharmony_ci %13 = OpLabel 948fd4e5da5Sopenharmony_ci OpBranch %9 949fd4e5da5Sopenharmony_ci %9 = OpLabel 950fd4e5da5Sopenharmony_ci OpBranchConditional %11 %6 %8 951fd4e5da5Sopenharmony_ci %8 = OpLabel 952fd4e5da5Sopenharmony_ci OpReturn 953fd4e5da5Sopenharmony_ci OpFunctionEnd 954fd4e5da5Sopenharmony_ci )"; 955fd4e5da5Sopenharmony_ci 956fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 957fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption); 958fd4e5da5Sopenharmony_ci const auto ops = StructuredLoopToSelectionReductionOpportunityFinder() 959fd4e5da5Sopenharmony_ci .GetAvailableOpportunities(context.get(), 0); 960fd4e5da5Sopenharmony_ci ASSERT_EQ(1, ops.size()); 961fd4e5da5Sopenharmony_ci 962fd4e5da5Sopenharmony_ci ASSERT_TRUE(ops[0]->PreconditionHolds()); 963fd4e5da5Sopenharmony_ci ops[0]->TryToApply(); 964fd4e5da5Sopenharmony_ci CheckValid(env, context.get()); 965fd4e5da5Sopenharmony_ci std::string after_op_0 = R"( 966fd4e5da5Sopenharmony_ci OpCapability Shader 967fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 968fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 969fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 970fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 971fd4e5da5Sopenharmony_ci OpSource ESSL 310 972fd4e5da5Sopenharmony_ci OpName %4 "main" 973fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 974fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 975fd4e5da5Sopenharmony_ci %10 = OpTypeBool 976fd4e5da5Sopenharmony_ci %11 = OpConstantFalse %10 977fd4e5da5Sopenharmony_ci %14 = OpConstantTrue %10 978fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 979fd4e5da5Sopenharmony_ci %5 = OpLabel 980fd4e5da5Sopenharmony_ci OpBranch %6 981fd4e5da5Sopenharmony_ci %6 = OpLabel 982fd4e5da5Sopenharmony_ci OpSelectionMerge %8 None 983fd4e5da5Sopenharmony_ci OpBranchConditional %14 %7 %8 984fd4e5da5Sopenharmony_ci %7 = OpLabel 985fd4e5da5Sopenharmony_ci OpSelectionMerge %13 None 986fd4e5da5Sopenharmony_ci OpBranchConditional %11 %13 %13 987fd4e5da5Sopenharmony_ci %13 = OpLabel 988fd4e5da5Sopenharmony_ci OpBranch %8 989fd4e5da5Sopenharmony_ci %9 = OpLabel 990fd4e5da5Sopenharmony_ci OpBranchConditional %11 %6 %8 991fd4e5da5Sopenharmony_ci %8 = OpLabel 992fd4e5da5Sopenharmony_ci OpReturn 993fd4e5da5Sopenharmony_ci OpFunctionEnd 994fd4e5da5Sopenharmony_ci )"; 995fd4e5da5Sopenharmony_ci CheckEqual(env, after_op_0, context.get()); 996fd4e5da5Sopenharmony_ci} 997fd4e5da5Sopenharmony_ci 998fd4e5da5Sopenharmony_ciTEST(StructuredLoopToSelectionReductionPassTest, UnconditionalBreak) { 999fd4e5da5Sopenharmony_ci std::string shader = R"( 1000fd4e5da5Sopenharmony_ci OpCapability Shader 1001fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 1002fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1003fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 1004fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 1005fd4e5da5Sopenharmony_ci OpSource ESSL 310 1006fd4e5da5Sopenharmony_ci OpName %4 "main" 1007fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 1008fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 1009fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 1010fd4e5da5Sopenharmony_ci %5 = OpLabel 1011fd4e5da5Sopenharmony_ci OpBranch %6 1012fd4e5da5Sopenharmony_ci %6 = OpLabel 1013fd4e5da5Sopenharmony_ci OpLoopMerge %8 %9 None 1014fd4e5da5Sopenharmony_ci OpBranch %7 1015fd4e5da5Sopenharmony_ci %7 = OpLabel 1016fd4e5da5Sopenharmony_ci OpBranch %8 1017fd4e5da5Sopenharmony_ci %9 = OpLabel 1018fd4e5da5Sopenharmony_ci OpBranch %6 1019fd4e5da5Sopenharmony_ci %8 = OpLabel 1020fd4e5da5Sopenharmony_ci OpReturn 1021fd4e5da5Sopenharmony_ci OpFunctionEnd 1022fd4e5da5Sopenharmony_ci )"; 1023fd4e5da5Sopenharmony_ci 1024fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 1025fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption); 1026fd4e5da5Sopenharmony_ci const auto ops = StructuredLoopToSelectionReductionOpportunityFinder() 1027fd4e5da5Sopenharmony_ci .GetAvailableOpportunities(context.get(), 0); 1028fd4e5da5Sopenharmony_ci ASSERT_EQ(1, ops.size()); 1029fd4e5da5Sopenharmony_ci 1030fd4e5da5Sopenharmony_ci ASSERT_TRUE(ops[0]->PreconditionHolds()); 1031fd4e5da5Sopenharmony_ci ops[0]->TryToApply(); 1032fd4e5da5Sopenharmony_ci CheckValid(env, context.get()); 1033fd4e5da5Sopenharmony_ci std::string after_op_0 = R"( 1034fd4e5da5Sopenharmony_ci OpCapability Shader 1035fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 1036fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1037fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 1038fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 1039fd4e5da5Sopenharmony_ci OpSource ESSL 310 1040fd4e5da5Sopenharmony_ci OpName %4 "main" 1041fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 1042fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 1043fd4e5da5Sopenharmony_ci %10 = OpTypeBool 1044fd4e5da5Sopenharmony_ci %11 = OpConstantTrue %10 1045fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 1046fd4e5da5Sopenharmony_ci %5 = OpLabel 1047fd4e5da5Sopenharmony_ci OpBranch %6 1048fd4e5da5Sopenharmony_ci %6 = OpLabel 1049fd4e5da5Sopenharmony_ci OpSelectionMerge %8 None 1050fd4e5da5Sopenharmony_ci OpBranchConditional %11 %7 %8 1051fd4e5da5Sopenharmony_ci %7 = OpLabel 1052fd4e5da5Sopenharmony_ci OpBranch %8 1053fd4e5da5Sopenharmony_ci %9 = OpLabel 1054fd4e5da5Sopenharmony_ci OpBranch %6 1055fd4e5da5Sopenharmony_ci %8 = OpLabel 1056fd4e5da5Sopenharmony_ci OpReturn 1057fd4e5da5Sopenharmony_ci OpFunctionEnd 1058fd4e5da5Sopenharmony_ci )"; 1059fd4e5da5Sopenharmony_ci CheckEqual(env, after_op_0, context.get()); 1060fd4e5da5Sopenharmony_ci} 1061fd4e5da5Sopenharmony_ci 1062fd4e5da5Sopenharmony_ciTEST(StructuredLoopToSelectionReductionPassTest, Complex) { 1063fd4e5da5Sopenharmony_ci std::string shader = R"( 1064fd4e5da5Sopenharmony_ci OpCapability Shader 1065fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 1066fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1067fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %2 "main" %3 1068fd4e5da5Sopenharmony_ci OpExecutionMode %2 OriginUpperLeft 1069fd4e5da5Sopenharmony_ci OpSource ESSL 310 1070fd4e5da5Sopenharmony_ci OpMemberDecorate %4 0 Offset 0 1071fd4e5da5Sopenharmony_ci OpMemberDecorate %4 1 Offset 4 1072fd4e5da5Sopenharmony_ci OpMemberDecorate %4 2 Offset 8 1073fd4e5da5Sopenharmony_ci OpMemberDecorate %4 3 Offset 12 1074fd4e5da5Sopenharmony_ci OpDecorate %4 Block 1075fd4e5da5Sopenharmony_ci OpDecorate %5 DescriptorSet 0 1076fd4e5da5Sopenharmony_ci OpDecorate %5 Binding 0 1077fd4e5da5Sopenharmony_ci OpDecorate %3 Location 0 1078fd4e5da5Sopenharmony_ci %6 = OpTypeVoid 1079fd4e5da5Sopenharmony_ci %7 = OpTypeFunction %6 1080fd4e5da5Sopenharmony_ci %8 = OpTypeBool 1081fd4e5da5Sopenharmony_ci %9 = OpTypePointer Function %8 1082fd4e5da5Sopenharmony_ci %10 = OpTypeInt 32 1 1083fd4e5da5Sopenharmony_ci %4 = OpTypeStruct %10 %10 %10 %10 1084fd4e5da5Sopenharmony_ci %11 = OpTypePointer Uniform %4 1085fd4e5da5Sopenharmony_ci %5 = OpVariable %11 Uniform 1086fd4e5da5Sopenharmony_ci %12 = OpConstant %10 0 1087fd4e5da5Sopenharmony_ci %13 = OpTypePointer Uniform %10 1088fd4e5da5Sopenharmony_ci %14 = OpTypeInt 32 0 1089fd4e5da5Sopenharmony_ci %15 = OpConstant %14 0 1090fd4e5da5Sopenharmony_ci %16 = OpConstant %10 1 1091fd4e5da5Sopenharmony_ci %17 = OpConstant %10 2 1092fd4e5da5Sopenharmony_ci %18 = OpConstant %10 3 1093fd4e5da5Sopenharmony_ci %19 = OpTypePointer Function %10 1094fd4e5da5Sopenharmony_ci %20 = OpConstantFalse %8 1095fd4e5da5Sopenharmony_ci %21 = OpTypeFloat 32 1096fd4e5da5Sopenharmony_ci %22 = OpTypeVector %21 4 1097fd4e5da5Sopenharmony_ci %23 = OpTypePointer Output %22 1098fd4e5da5Sopenharmony_ci %3 = OpVariable %23 Output 1099fd4e5da5Sopenharmony_ci %2 = OpFunction %6 None %7 1100fd4e5da5Sopenharmony_ci %24 = OpLabel 1101fd4e5da5Sopenharmony_ci %25 = OpVariable %9 Function 1102fd4e5da5Sopenharmony_ci %26 = OpVariable %9 Function 1103fd4e5da5Sopenharmony_ci %27 = OpVariable %9 Function 1104fd4e5da5Sopenharmony_ci %28 = OpVariable %9 Function 1105fd4e5da5Sopenharmony_ci %29 = OpVariable %9 Function 1106fd4e5da5Sopenharmony_ci %30 = OpVariable %19 Function 1107fd4e5da5Sopenharmony_ci %31 = OpAccessChain %13 %5 %12 1108fd4e5da5Sopenharmony_ci %32 = OpLoad %10 %31 1109fd4e5da5Sopenharmony_ci %33 = OpINotEqual %8 %32 %15 1110fd4e5da5Sopenharmony_ci OpStore %25 %33 1111fd4e5da5Sopenharmony_ci %34 = OpAccessChain %13 %5 %16 1112fd4e5da5Sopenharmony_ci %35 = OpLoad %10 %34 1113fd4e5da5Sopenharmony_ci %36 = OpINotEqual %8 %35 %15 1114fd4e5da5Sopenharmony_ci OpStore %26 %36 1115fd4e5da5Sopenharmony_ci %37 = OpAccessChain %13 %5 %17 1116fd4e5da5Sopenharmony_ci %38 = OpLoad %10 %37 1117fd4e5da5Sopenharmony_ci %39 = OpINotEqual %8 %38 %15 1118fd4e5da5Sopenharmony_ci OpStore %27 %39 1119fd4e5da5Sopenharmony_ci %40 = OpAccessChain %13 %5 %18 1120fd4e5da5Sopenharmony_ci %41 = OpLoad %10 %40 1121fd4e5da5Sopenharmony_ci %42 = OpINotEqual %8 %41 %15 1122fd4e5da5Sopenharmony_ci OpStore %28 %42 1123fd4e5da5Sopenharmony_ci %43 = OpLoad %8 %25 1124fd4e5da5Sopenharmony_ci OpStore %29 %43 1125fd4e5da5Sopenharmony_ci OpStore %30 %12 1126fd4e5da5Sopenharmony_ci OpBranch %44 1127fd4e5da5Sopenharmony_ci %44 = OpLabel 1128fd4e5da5Sopenharmony_ci OpLoopMerge %45 %46 None 1129fd4e5da5Sopenharmony_ci OpBranch %47 1130fd4e5da5Sopenharmony_ci %47 = OpLabel 1131fd4e5da5Sopenharmony_ci %48 = OpLoad %8 %29 1132fd4e5da5Sopenharmony_ci OpBranchConditional %48 %49 %45 1133fd4e5da5Sopenharmony_ci %49 = OpLabel 1134fd4e5da5Sopenharmony_ci %50 = OpLoad %8 %25 1135fd4e5da5Sopenharmony_ci OpSelectionMerge %51 None 1136fd4e5da5Sopenharmony_ci OpBranchConditional %50 %52 %51 1137fd4e5da5Sopenharmony_ci %52 = OpLabel 1138fd4e5da5Sopenharmony_ci %53 = OpLoad %8 %26 1139fd4e5da5Sopenharmony_ci OpStore %29 %53 1140fd4e5da5Sopenharmony_ci %54 = OpLoad %10 %30 1141fd4e5da5Sopenharmony_ci %55 = OpIAdd %10 %54 %16 1142fd4e5da5Sopenharmony_ci OpStore %30 %55 1143fd4e5da5Sopenharmony_ci OpBranch %51 1144fd4e5da5Sopenharmony_ci %51 = OpLabel 1145fd4e5da5Sopenharmony_ci %56 = OpLoad %8 %26 1146fd4e5da5Sopenharmony_ci OpSelectionMerge %57 None 1147fd4e5da5Sopenharmony_ci OpBranchConditional %56 %58 %57 1148fd4e5da5Sopenharmony_ci %58 = OpLabel 1149fd4e5da5Sopenharmony_ci %59 = OpLoad %10 %30 1150fd4e5da5Sopenharmony_ci %60 = OpIAdd %10 %59 %16 1151fd4e5da5Sopenharmony_ci OpStore %30 %60 1152fd4e5da5Sopenharmony_ci %61 = OpLoad %8 %29 1153fd4e5da5Sopenharmony_ci %62 = OpLoad %8 %25 1154fd4e5da5Sopenharmony_ci %63 = OpLogicalOr %8 %61 %62 1155fd4e5da5Sopenharmony_ci OpStore %29 %63 1156fd4e5da5Sopenharmony_ci %64 = OpLoad %8 %27 1157fd4e5da5Sopenharmony_ci OpSelectionMerge %65 None 1158fd4e5da5Sopenharmony_ci OpBranchConditional %64 %66 %65 1159fd4e5da5Sopenharmony_ci %66 = OpLabel 1160fd4e5da5Sopenharmony_ci %67 = OpLoad %10 %30 1161fd4e5da5Sopenharmony_ci %68 = OpIAdd %10 %67 %17 1162fd4e5da5Sopenharmony_ci OpStore %30 %68 1163fd4e5da5Sopenharmony_ci %69 = OpLoad %8 %29 1164fd4e5da5Sopenharmony_ci %70 = OpLogicalNot %8 %69 1165fd4e5da5Sopenharmony_ci OpStore %29 %70 1166fd4e5da5Sopenharmony_ci OpBranch %46 1167fd4e5da5Sopenharmony_ci %65 = OpLabel 1168fd4e5da5Sopenharmony_ci %71 = OpLoad %8 %29 1169fd4e5da5Sopenharmony_ci %72 = OpLogicalOr %8 %71 %20 1170fd4e5da5Sopenharmony_ci OpStore %29 %72 1171fd4e5da5Sopenharmony_ci OpBranch %46 1172fd4e5da5Sopenharmony_ci %57 = OpLabel 1173fd4e5da5Sopenharmony_ci OpBranch %73 1174fd4e5da5Sopenharmony_ci %73 = OpLabel 1175fd4e5da5Sopenharmony_ci OpLoopMerge %74 %75 None 1176fd4e5da5Sopenharmony_ci OpBranch %76 1177fd4e5da5Sopenharmony_ci %76 = OpLabel 1178fd4e5da5Sopenharmony_ci %77 = OpLoad %8 %28 1179fd4e5da5Sopenharmony_ci OpSelectionMerge %78 None 1180fd4e5da5Sopenharmony_ci OpBranchConditional %77 %79 %80 1181fd4e5da5Sopenharmony_ci %79 = OpLabel 1182fd4e5da5Sopenharmony_ci %81 = OpLoad %10 %30 1183fd4e5da5Sopenharmony_ci OpSelectionMerge %82 None 1184fd4e5da5Sopenharmony_ci OpSwitch %81 %83 1 %84 2 %85 1185fd4e5da5Sopenharmony_ci %83 = OpLabel 1186fd4e5da5Sopenharmony_ci OpBranch %82 1187fd4e5da5Sopenharmony_ci %84 = OpLabel 1188fd4e5da5Sopenharmony_ci %86 = OpLoad %8 %29 1189fd4e5da5Sopenharmony_ci %87 = OpSelect %10 %86 %16 %17 1190fd4e5da5Sopenharmony_ci %88 = OpLoad %10 %30 1191fd4e5da5Sopenharmony_ci %89 = OpIAdd %10 %88 %87 1192fd4e5da5Sopenharmony_ci OpStore %30 %89 1193fd4e5da5Sopenharmony_ci OpBranch %82 1194fd4e5da5Sopenharmony_ci %85 = OpLabel 1195fd4e5da5Sopenharmony_ci OpBranch %75 1196fd4e5da5Sopenharmony_ci %82 = OpLabel 1197fd4e5da5Sopenharmony_ci %90 = OpLoad %8 %27 1198fd4e5da5Sopenharmony_ci OpSelectionMerge %91 None 1199fd4e5da5Sopenharmony_ci OpBranchConditional %90 %92 %91 1200fd4e5da5Sopenharmony_ci %92 = OpLabel 1201fd4e5da5Sopenharmony_ci OpBranch %75 1202fd4e5da5Sopenharmony_ci %91 = OpLabel 1203fd4e5da5Sopenharmony_ci OpBranch %78 1204fd4e5da5Sopenharmony_ci %80 = OpLabel 1205fd4e5da5Sopenharmony_ci OpBranch %74 1206fd4e5da5Sopenharmony_ci %78 = OpLabel 1207fd4e5da5Sopenharmony_ci OpBranch %75 1208fd4e5da5Sopenharmony_ci %75 = OpLabel 1209fd4e5da5Sopenharmony_ci %93 = OpLoad %8 %29 1210fd4e5da5Sopenharmony_ci OpBranchConditional %93 %73 %74 1211fd4e5da5Sopenharmony_ci %74 = OpLabel 1212fd4e5da5Sopenharmony_ci OpBranch %46 1213fd4e5da5Sopenharmony_ci %46 = OpLabel 1214fd4e5da5Sopenharmony_ci OpBranch %44 1215fd4e5da5Sopenharmony_ci %45 = OpLabel 1216fd4e5da5Sopenharmony_ci %94 = OpLoad %10 %30 1217fd4e5da5Sopenharmony_ci %95 = OpConvertSToF %21 %94 1218fd4e5da5Sopenharmony_ci %96 = OpCompositeConstruct %22 %95 %95 %95 %95 1219fd4e5da5Sopenharmony_ci OpStore %3 %96 1220fd4e5da5Sopenharmony_ci OpReturn 1221fd4e5da5Sopenharmony_ci OpFunctionEnd 1222fd4e5da5Sopenharmony_ci )"; 1223fd4e5da5Sopenharmony_ci 1224fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 1225fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption); 1226fd4e5da5Sopenharmony_ci const auto ops = StructuredLoopToSelectionReductionOpportunityFinder() 1227fd4e5da5Sopenharmony_ci .GetAvailableOpportunities(context.get(), 0); 1228fd4e5da5Sopenharmony_ci 1229fd4e5da5Sopenharmony_ci ASSERT_EQ(2, ops.size()); 1230fd4e5da5Sopenharmony_ci ASSERT_TRUE(ops[0]->PreconditionHolds()); 1231fd4e5da5Sopenharmony_ci ops[0]->TryToApply(); 1232fd4e5da5Sopenharmony_ci CheckValid(env, context.get()); 1233fd4e5da5Sopenharmony_ci std::string after_op_0 = R"( 1234fd4e5da5Sopenharmony_ci OpCapability Shader 1235fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 1236fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1237fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %2 "main" %3 1238fd4e5da5Sopenharmony_ci OpExecutionMode %2 OriginUpperLeft 1239fd4e5da5Sopenharmony_ci OpSource ESSL 310 1240fd4e5da5Sopenharmony_ci OpMemberDecorate %4 0 Offset 0 1241fd4e5da5Sopenharmony_ci OpMemberDecorate %4 1 Offset 4 1242fd4e5da5Sopenharmony_ci OpMemberDecorate %4 2 Offset 8 1243fd4e5da5Sopenharmony_ci OpMemberDecorate %4 3 Offset 12 1244fd4e5da5Sopenharmony_ci OpDecorate %4 Block 1245fd4e5da5Sopenharmony_ci OpDecorate %5 DescriptorSet 0 1246fd4e5da5Sopenharmony_ci OpDecorate %5 Binding 0 1247fd4e5da5Sopenharmony_ci OpDecorate %3 Location 0 1248fd4e5da5Sopenharmony_ci %6 = OpTypeVoid 1249fd4e5da5Sopenharmony_ci %7 = OpTypeFunction %6 1250fd4e5da5Sopenharmony_ci %8 = OpTypeBool 1251fd4e5da5Sopenharmony_ci %9 = OpTypePointer Function %8 1252fd4e5da5Sopenharmony_ci %10 = OpTypeInt 32 1 1253fd4e5da5Sopenharmony_ci %4 = OpTypeStruct %10 %10 %10 %10 1254fd4e5da5Sopenharmony_ci %11 = OpTypePointer Uniform %4 1255fd4e5da5Sopenharmony_ci %5 = OpVariable %11 Uniform 1256fd4e5da5Sopenharmony_ci %12 = OpConstant %10 0 1257fd4e5da5Sopenharmony_ci %13 = OpTypePointer Uniform %10 1258fd4e5da5Sopenharmony_ci %14 = OpTypeInt 32 0 1259fd4e5da5Sopenharmony_ci %15 = OpConstant %14 0 1260fd4e5da5Sopenharmony_ci %16 = OpConstant %10 1 1261fd4e5da5Sopenharmony_ci %17 = OpConstant %10 2 1262fd4e5da5Sopenharmony_ci %18 = OpConstant %10 3 1263fd4e5da5Sopenharmony_ci %19 = OpTypePointer Function %10 1264fd4e5da5Sopenharmony_ci %20 = OpConstantFalse %8 1265fd4e5da5Sopenharmony_ci %21 = OpTypeFloat 32 1266fd4e5da5Sopenharmony_ci %22 = OpTypeVector %21 4 1267fd4e5da5Sopenharmony_ci %23 = OpTypePointer Output %22 1268fd4e5da5Sopenharmony_ci %3 = OpVariable %23 Output 1269fd4e5da5Sopenharmony_ci %97 = OpConstantTrue %8 1270fd4e5da5Sopenharmony_ci %2 = OpFunction %6 None %7 1271fd4e5da5Sopenharmony_ci %24 = OpLabel 1272fd4e5da5Sopenharmony_ci %25 = OpVariable %9 Function 1273fd4e5da5Sopenharmony_ci %26 = OpVariable %9 Function 1274fd4e5da5Sopenharmony_ci %27 = OpVariable %9 Function 1275fd4e5da5Sopenharmony_ci %28 = OpVariable %9 Function 1276fd4e5da5Sopenharmony_ci %29 = OpVariable %9 Function 1277fd4e5da5Sopenharmony_ci %30 = OpVariable %19 Function 1278fd4e5da5Sopenharmony_ci %31 = OpAccessChain %13 %5 %12 1279fd4e5da5Sopenharmony_ci %32 = OpLoad %10 %31 1280fd4e5da5Sopenharmony_ci %33 = OpINotEqual %8 %32 %15 1281fd4e5da5Sopenharmony_ci OpStore %25 %33 1282fd4e5da5Sopenharmony_ci %34 = OpAccessChain %13 %5 %16 1283fd4e5da5Sopenharmony_ci %35 = OpLoad %10 %34 1284fd4e5da5Sopenharmony_ci %36 = OpINotEqual %8 %35 %15 1285fd4e5da5Sopenharmony_ci OpStore %26 %36 1286fd4e5da5Sopenharmony_ci %37 = OpAccessChain %13 %5 %17 1287fd4e5da5Sopenharmony_ci %38 = OpLoad %10 %37 1288fd4e5da5Sopenharmony_ci %39 = OpINotEqual %8 %38 %15 1289fd4e5da5Sopenharmony_ci OpStore %27 %39 1290fd4e5da5Sopenharmony_ci %40 = OpAccessChain %13 %5 %18 1291fd4e5da5Sopenharmony_ci %41 = OpLoad %10 %40 1292fd4e5da5Sopenharmony_ci %42 = OpINotEqual %8 %41 %15 1293fd4e5da5Sopenharmony_ci OpStore %28 %42 1294fd4e5da5Sopenharmony_ci %43 = OpLoad %8 %25 1295fd4e5da5Sopenharmony_ci OpStore %29 %43 1296fd4e5da5Sopenharmony_ci OpStore %30 %12 1297fd4e5da5Sopenharmony_ci OpBranch %44 1298fd4e5da5Sopenharmony_ci %44 = OpLabel 1299fd4e5da5Sopenharmony_ci OpSelectionMerge %45 None ; Was OpLoopMerge %45 %46 None 1300fd4e5da5Sopenharmony_ci OpBranchConditional %97 %47 %45 ; Was OpBranch %47 1301fd4e5da5Sopenharmony_ci %47 = OpLabel 1302fd4e5da5Sopenharmony_ci %48 = OpLoad %8 %29 1303fd4e5da5Sopenharmony_ci OpBranchConditional %48 %49 %45 1304fd4e5da5Sopenharmony_ci %49 = OpLabel 1305fd4e5da5Sopenharmony_ci %50 = OpLoad %8 %25 1306fd4e5da5Sopenharmony_ci OpSelectionMerge %51 None 1307fd4e5da5Sopenharmony_ci OpBranchConditional %50 %52 %51 1308fd4e5da5Sopenharmony_ci %52 = OpLabel 1309fd4e5da5Sopenharmony_ci %53 = OpLoad %8 %26 1310fd4e5da5Sopenharmony_ci OpStore %29 %53 1311fd4e5da5Sopenharmony_ci %54 = OpLoad %10 %30 1312fd4e5da5Sopenharmony_ci %55 = OpIAdd %10 %54 %16 1313fd4e5da5Sopenharmony_ci OpStore %30 %55 1314fd4e5da5Sopenharmony_ci OpBranch %51 1315fd4e5da5Sopenharmony_ci %51 = OpLabel 1316fd4e5da5Sopenharmony_ci %56 = OpLoad %8 %26 1317fd4e5da5Sopenharmony_ci OpSelectionMerge %57 None 1318fd4e5da5Sopenharmony_ci OpBranchConditional %56 %58 %57 1319fd4e5da5Sopenharmony_ci %58 = OpLabel 1320fd4e5da5Sopenharmony_ci %59 = OpLoad %10 %30 1321fd4e5da5Sopenharmony_ci %60 = OpIAdd %10 %59 %16 1322fd4e5da5Sopenharmony_ci OpStore %30 %60 1323fd4e5da5Sopenharmony_ci %61 = OpLoad %8 %29 1324fd4e5da5Sopenharmony_ci %62 = OpLoad %8 %25 1325fd4e5da5Sopenharmony_ci %63 = OpLogicalOr %8 %61 %62 1326fd4e5da5Sopenharmony_ci OpStore %29 %63 1327fd4e5da5Sopenharmony_ci %64 = OpLoad %8 %27 1328fd4e5da5Sopenharmony_ci OpSelectionMerge %65 None 1329fd4e5da5Sopenharmony_ci OpBranchConditional %64 %66 %65 1330fd4e5da5Sopenharmony_ci %66 = OpLabel 1331fd4e5da5Sopenharmony_ci %67 = OpLoad %10 %30 1332fd4e5da5Sopenharmony_ci %68 = OpIAdd %10 %67 %17 1333fd4e5da5Sopenharmony_ci OpStore %30 %68 1334fd4e5da5Sopenharmony_ci %69 = OpLoad %8 %29 1335fd4e5da5Sopenharmony_ci %70 = OpLogicalNot %8 %69 1336fd4e5da5Sopenharmony_ci OpStore %29 %70 1337fd4e5da5Sopenharmony_ci OpBranch %65 ; Was OpBranch %46 1338fd4e5da5Sopenharmony_ci %65 = OpLabel 1339fd4e5da5Sopenharmony_ci %71 = OpLoad %8 %29 1340fd4e5da5Sopenharmony_ci %72 = OpLogicalOr %8 %71 %20 1341fd4e5da5Sopenharmony_ci OpStore %29 %72 1342fd4e5da5Sopenharmony_ci OpBranch %57 ; Was OpBranch %46 1343fd4e5da5Sopenharmony_ci %57 = OpLabel 1344fd4e5da5Sopenharmony_ci OpBranch %73 1345fd4e5da5Sopenharmony_ci %73 = OpLabel 1346fd4e5da5Sopenharmony_ci OpLoopMerge %74 %75 None 1347fd4e5da5Sopenharmony_ci OpBranch %76 1348fd4e5da5Sopenharmony_ci %76 = OpLabel 1349fd4e5da5Sopenharmony_ci %77 = OpLoad %8 %28 1350fd4e5da5Sopenharmony_ci OpSelectionMerge %78 None 1351fd4e5da5Sopenharmony_ci OpBranchConditional %77 %79 %80 1352fd4e5da5Sopenharmony_ci %79 = OpLabel 1353fd4e5da5Sopenharmony_ci %81 = OpLoad %10 %30 1354fd4e5da5Sopenharmony_ci OpSelectionMerge %82 None 1355fd4e5da5Sopenharmony_ci OpSwitch %81 %83 1 %84 2 %85 1356fd4e5da5Sopenharmony_ci %83 = OpLabel 1357fd4e5da5Sopenharmony_ci OpBranch %82 1358fd4e5da5Sopenharmony_ci %84 = OpLabel 1359fd4e5da5Sopenharmony_ci %86 = OpLoad %8 %29 1360fd4e5da5Sopenharmony_ci %87 = OpSelect %10 %86 %16 %17 1361fd4e5da5Sopenharmony_ci %88 = OpLoad %10 %30 1362fd4e5da5Sopenharmony_ci %89 = OpIAdd %10 %88 %87 1363fd4e5da5Sopenharmony_ci OpStore %30 %89 1364fd4e5da5Sopenharmony_ci OpBranch %82 1365fd4e5da5Sopenharmony_ci %85 = OpLabel 1366fd4e5da5Sopenharmony_ci OpBranch %75 1367fd4e5da5Sopenharmony_ci %82 = OpLabel 1368fd4e5da5Sopenharmony_ci %90 = OpLoad %8 %27 1369fd4e5da5Sopenharmony_ci OpSelectionMerge %91 None 1370fd4e5da5Sopenharmony_ci OpBranchConditional %90 %92 %91 1371fd4e5da5Sopenharmony_ci %92 = OpLabel 1372fd4e5da5Sopenharmony_ci OpBranch %75 1373fd4e5da5Sopenharmony_ci %91 = OpLabel 1374fd4e5da5Sopenharmony_ci OpBranch %78 1375fd4e5da5Sopenharmony_ci %80 = OpLabel 1376fd4e5da5Sopenharmony_ci OpBranch %74 1377fd4e5da5Sopenharmony_ci %78 = OpLabel 1378fd4e5da5Sopenharmony_ci OpBranch %75 1379fd4e5da5Sopenharmony_ci %75 = OpLabel 1380fd4e5da5Sopenharmony_ci %93 = OpLoad %8 %29 1381fd4e5da5Sopenharmony_ci OpBranchConditional %93 %73 %74 1382fd4e5da5Sopenharmony_ci %74 = OpLabel 1383fd4e5da5Sopenharmony_ci OpBranch %45 ; Was OpBranch %46 1384fd4e5da5Sopenharmony_ci %46 = OpLabel 1385fd4e5da5Sopenharmony_ci OpBranch %44 1386fd4e5da5Sopenharmony_ci %45 = OpLabel 1387fd4e5da5Sopenharmony_ci %94 = OpLoad %10 %30 1388fd4e5da5Sopenharmony_ci %95 = OpConvertSToF %21 %94 1389fd4e5da5Sopenharmony_ci %96 = OpCompositeConstruct %22 %95 %95 %95 %95 1390fd4e5da5Sopenharmony_ci OpStore %3 %96 1391fd4e5da5Sopenharmony_ci OpReturn 1392fd4e5da5Sopenharmony_ci OpFunctionEnd 1393fd4e5da5Sopenharmony_ci )"; 1394fd4e5da5Sopenharmony_ci CheckEqual(env, after_op_0, context.get()); 1395fd4e5da5Sopenharmony_ci ASSERT_TRUE(ops[1]->PreconditionHolds()); 1396fd4e5da5Sopenharmony_ci ops[1]->TryToApply(); 1397fd4e5da5Sopenharmony_ci CheckValid(env, context.get()); 1398fd4e5da5Sopenharmony_ci 1399fd4e5da5Sopenharmony_ci std::string after_op_1 = R"( 1400fd4e5da5Sopenharmony_ci OpCapability Shader 1401fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 1402fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1403fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %2 "main" %3 1404fd4e5da5Sopenharmony_ci OpExecutionMode %2 OriginUpperLeft 1405fd4e5da5Sopenharmony_ci OpSource ESSL 310 1406fd4e5da5Sopenharmony_ci OpMemberDecorate %4 0 Offset 0 1407fd4e5da5Sopenharmony_ci OpMemberDecorate %4 1 Offset 4 1408fd4e5da5Sopenharmony_ci OpMemberDecorate %4 2 Offset 8 1409fd4e5da5Sopenharmony_ci OpMemberDecorate %4 3 Offset 12 1410fd4e5da5Sopenharmony_ci OpDecorate %4 Block 1411fd4e5da5Sopenharmony_ci OpDecorate %5 DescriptorSet 0 1412fd4e5da5Sopenharmony_ci OpDecorate %5 Binding 0 1413fd4e5da5Sopenharmony_ci OpDecorate %3 Location 0 1414fd4e5da5Sopenharmony_ci %6 = OpTypeVoid 1415fd4e5da5Sopenharmony_ci %7 = OpTypeFunction %6 1416fd4e5da5Sopenharmony_ci %8 = OpTypeBool 1417fd4e5da5Sopenharmony_ci %9 = OpTypePointer Function %8 1418fd4e5da5Sopenharmony_ci %10 = OpTypeInt 32 1 1419fd4e5da5Sopenharmony_ci %4 = OpTypeStruct %10 %10 %10 %10 1420fd4e5da5Sopenharmony_ci %11 = OpTypePointer Uniform %4 1421fd4e5da5Sopenharmony_ci %5 = OpVariable %11 Uniform 1422fd4e5da5Sopenharmony_ci %12 = OpConstant %10 0 1423fd4e5da5Sopenharmony_ci %13 = OpTypePointer Uniform %10 1424fd4e5da5Sopenharmony_ci %14 = OpTypeInt 32 0 1425fd4e5da5Sopenharmony_ci %15 = OpConstant %14 0 1426fd4e5da5Sopenharmony_ci %16 = OpConstant %10 1 1427fd4e5da5Sopenharmony_ci %17 = OpConstant %10 2 1428fd4e5da5Sopenharmony_ci %18 = OpConstant %10 3 1429fd4e5da5Sopenharmony_ci %19 = OpTypePointer Function %10 1430fd4e5da5Sopenharmony_ci %20 = OpConstantFalse %8 1431fd4e5da5Sopenharmony_ci %21 = OpTypeFloat 32 1432fd4e5da5Sopenharmony_ci %22 = OpTypeVector %21 4 1433fd4e5da5Sopenharmony_ci %23 = OpTypePointer Output %22 1434fd4e5da5Sopenharmony_ci %3 = OpVariable %23 Output 1435fd4e5da5Sopenharmony_ci %97 = OpConstantTrue %8 1436fd4e5da5Sopenharmony_ci %2 = OpFunction %6 None %7 1437fd4e5da5Sopenharmony_ci %24 = OpLabel 1438fd4e5da5Sopenharmony_ci %25 = OpVariable %9 Function 1439fd4e5da5Sopenharmony_ci %26 = OpVariable %9 Function 1440fd4e5da5Sopenharmony_ci %27 = OpVariable %9 Function 1441fd4e5da5Sopenharmony_ci %28 = OpVariable %9 Function 1442fd4e5da5Sopenharmony_ci %29 = OpVariable %9 Function 1443fd4e5da5Sopenharmony_ci %30 = OpVariable %19 Function 1444fd4e5da5Sopenharmony_ci %31 = OpAccessChain %13 %5 %12 1445fd4e5da5Sopenharmony_ci %32 = OpLoad %10 %31 1446fd4e5da5Sopenharmony_ci %33 = OpINotEqual %8 %32 %15 1447fd4e5da5Sopenharmony_ci OpStore %25 %33 1448fd4e5da5Sopenharmony_ci %34 = OpAccessChain %13 %5 %16 1449fd4e5da5Sopenharmony_ci %35 = OpLoad %10 %34 1450fd4e5da5Sopenharmony_ci %36 = OpINotEqual %8 %35 %15 1451fd4e5da5Sopenharmony_ci OpStore %26 %36 1452fd4e5da5Sopenharmony_ci %37 = OpAccessChain %13 %5 %17 1453fd4e5da5Sopenharmony_ci %38 = OpLoad %10 %37 1454fd4e5da5Sopenharmony_ci %39 = OpINotEqual %8 %38 %15 1455fd4e5da5Sopenharmony_ci OpStore %27 %39 1456fd4e5da5Sopenharmony_ci %40 = OpAccessChain %13 %5 %18 1457fd4e5da5Sopenharmony_ci %41 = OpLoad %10 %40 1458fd4e5da5Sopenharmony_ci %42 = OpINotEqual %8 %41 %15 1459fd4e5da5Sopenharmony_ci OpStore %28 %42 1460fd4e5da5Sopenharmony_ci %43 = OpLoad %8 %25 1461fd4e5da5Sopenharmony_ci OpStore %29 %43 1462fd4e5da5Sopenharmony_ci OpStore %30 %12 1463fd4e5da5Sopenharmony_ci OpBranch %44 1464fd4e5da5Sopenharmony_ci %44 = OpLabel 1465fd4e5da5Sopenharmony_ci OpSelectionMerge %45 None ; Was OpLoopMerge %45 %46 None 1466fd4e5da5Sopenharmony_ci OpBranchConditional %97 %47 %45 ; Was OpBranch %47 1467fd4e5da5Sopenharmony_ci %47 = OpLabel 1468fd4e5da5Sopenharmony_ci %48 = OpLoad %8 %29 1469fd4e5da5Sopenharmony_ci OpBranchConditional %48 %49 %45 1470fd4e5da5Sopenharmony_ci %49 = OpLabel 1471fd4e5da5Sopenharmony_ci %50 = OpLoad %8 %25 1472fd4e5da5Sopenharmony_ci OpSelectionMerge %51 None 1473fd4e5da5Sopenharmony_ci OpBranchConditional %50 %52 %51 1474fd4e5da5Sopenharmony_ci %52 = OpLabel 1475fd4e5da5Sopenharmony_ci %53 = OpLoad %8 %26 1476fd4e5da5Sopenharmony_ci OpStore %29 %53 1477fd4e5da5Sopenharmony_ci %54 = OpLoad %10 %30 1478fd4e5da5Sopenharmony_ci %55 = OpIAdd %10 %54 %16 1479fd4e5da5Sopenharmony_ci OpStore %30 %55 1480fd4e5da5Sopenharmony_ci OpBranch %51 1481fd4e5da5Sopenharmony_ci %51 = OpLabel 1482fd4e5da5Sopenharmony_ci %56 = OpLoad %8 %26 1483fd4e5da5Sopenharmony_ci OpSelectionMerge %57 None 1484fd4e5da5Sopenharmony_ci OpBranchConditional %56 %58 %57 1485fd4e5da5Sopenharmony_ci %58 = OpLabel 1486fd4e5da5Sopenharmony_ci %59 = OpLoad %10 %30 1487fd4e5da5Sopenharmony_ci %60 = OpIAdd %10 %59 %16 1488fd4e5da5Sopenharmony_ci OpStore %30 %60 1489fd4e5da5Sopenharmony_ci %61 = OpLoad %8 %29 1490fd4e5da5Sopenharmony_ci %62 = OpLoad %8 %25 1491fd4e5da5Sopenharmony_ci %63 = OpLogicalOr %8 %61 %62 1492fd4e5da5Sopenharmony_ci OpStore %29 %63 1493fd4e5da5Sopenharmony_ci %64 = OpLoad %8 %27 1494fd4e5da5Sopenharmony_ci OpSelectionMerge %65 None 1495fd4e5da5Sopenharmony_ci OpBranchConditional %64 %66 %65 1496fd4e5da5Sopenharmony_ci %66 = OpLabel 1497fd4e5da5Sopenharmony_ci %67 = OpLoad %10 %30 1498fd4e5da5Sopenharmony_ci %68 = OpIAdd %10 %67 %17 1499fd4e5da5Sopenharmony_ci OpStore %30 %68 1500fd4e5da5Sopenharmony_ci %69 = OpLoad %8 %29 1501fd4e5da5Sopenharmony_ci %70 = OpLogicalNot %8 %69 1502fd4e5da5Sopenharmony_ci OpStore %29 %70 1503fd4e5da5Sopenharmony_ci OpBranch %65 ; Was OpBranch %46 1504fd4e5da5Sopenharmony_ci %65 = OpLabel 1505fd4e5da5Sopenharmony_ci %71 = OpLoad %8 %29 1506fd4e5da5Sopenharmony_ci %72 = OpLogicalOr %8 %71 %20 1507fd4e5da5Sopenharmony_ci OpStore %29 %72 1508fd4e5da5Sopenharmony_ci OpBranch %57 ; Was OpBranch %46 1509fd4e5da5Sopenharmony_ci %57 = OpLabel 1510fd4e5da5Sopenharmony_ci OpBranch %73 1511fd4e5da5Sopenharmony_ci %73 = OpLabel 1512fd4e5da5Sopenharmony_ci OpSelectionMerge %74 None ; Was OpLoopMerge %74 %75 None 1513fd4e5da5Sopenharmony_ci OpBranchConditional %97 %76 %74 ; Was OpBranch %76 1514fd4e5da5Sopenharmony_ci %76 = OpLabel 1515fd4e5da5Sopenharmony_ci %77 = OpLoad %8 %28 1516fd4e5da5Sopenharmony_ci OpSelectionMerge %78 None 1517fd4e5da5Sopenharmony_ci OpBranchConditional %77 %79 %80 1518fd4e5da5Sopenharmony_ci %79 = OpLabel 1519fd4e5da5Sopenharmony_ci %81 = OpLoad %10 %30 1520fd4e5da5Sopenharmony_ci OpSelectionMerge %82 None 1521fd4e5da5Sopenharmony_ci OpSwitch %81 %83 1 %84 2 %85 1522fd4e5da5Sopenharmony_ci %83 = OpLabel 1523fd4e5da5Sopenharmony_ci OpBranch %82 1524fd4e5da5Sopenharmony_ci %84 = OpLabel 1525fd4e5da5Sopenharmony_ci %86 = OpLoad %8 %29 1526fd4e5da5Sopenharmony_ci %87 = OpSelect %10 %86 %16 %17 1527fd4e5da5Sopenharmony_ci %88 = OpLoad %10 %30 1528fd4e5da5Sopenharmony_ci %89 = OpIAdd %10 %88 %87 1529fd4e5da5Sopenharmony_ci OpStore %30 %89 1530fd4e5da5Sopenharmony_ci OpBranch %82 1531fd4e5da5Sopenharmony_ci %85 = OpLabel 1532fd4e5da5Sopenharmony_ci OpBranch %82 1533fd4e5da5Sopenharmony_ci %82 = OpLabel 1534fd4e5da5Sopenharmony_ci %90 = OpLoad %8 %27 1535fd4e5da5Sopenharmony_ci OpSelectionMerge %91 None 1536fd4e5da5Sopenharmony_ci OpBranchConditional %90 %92 %91 1537fd4e5da5Sopenharmony_ci %92 = OpLabel 1538fd4e5da5Sopenharmony_ci OpBranch %91 1539fd4e5da5Sopenharmony_ci %91 = OpLabel 1540fd4e5da5Sopenharmony_ci OpBranch %78 1541fd4e5da5Sopenharmony_ci %80 = OpLabel 1542fd4e5da5Sopenharmony_ci OpBranch %78 ; Was OpBranch %74 1543fd4e5da5Sopenharmony_ci %78 = OpLabel 1544fd4e5da5Sopenharmony_ci OpBranch %74 1545fd4e5da5Sopenharmony_ci %75 = OpLabel 1546fd4e5da5Sopenharmony_ci %93 = OpLoad %8 %29 1547fd4e5da5Sopenharmony_ci OpBranchConditional %93 %73 %74 1548fd4e5da5Sopenharmony_ci %74 = OpLabel 1549fd4e5da5Sopenharmony_ci OpBranch %45 ; Was OpBranch %46 1550fd4e5da5Sopenharmony_ci %46 = OpLabel 1551fd4e5da5Sopenharmony_ci OpBranch %44 1552fd4e5da5Sopenharmony_ci %45 = OpLabel 1553fd4e5da5Sopenharmony_ci %94 = OpLoad %10 %30 1554fd4e5da5Sopenharmony_ci %95 = OpConvertSToF %21 %94 1555fd4e5da5Sopenharmony_ci %96 = OpCompositeConstruct %22 %95 %95 %95 %95 1556fd4e5da5Sopenharmony_ci OpStore %3 %96 1557fd4e5da5Sopenharmony_ci OpReturn 1558fd4e5da5Sopenharmony_ci OpFunctionEnd 1559fd4e5da5Sopenharmony_ci )"; 1560fd4e5da5Sopenharmony_ci CheckEqual(env, after_op_1, context.get()); 1561fd4e5da5Sopenharmony_ci} 1562fd4e5da5Sopenharmony_ci 1563fd4e5da5Sopenharmony_ciTEST(StructuredLoopToSelectionReductionPassTest, ComplexOptimized) { 1564fd4e5da5Sopenharmony_ci std::string shader = R"( 1565fd4e5da5Sopenharmony_ci OpCapability Shader 1566fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 1567fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1568fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %2 "main" %3 1569fd4e5da5Sopenharmony_ci OpExecutionMode %2 OriginUpperLeft 1570fd4e5da5Sopenharmony_ci OpSource ESSL 310 1571fd4e5da5Sopenharmony_ci OpMemberDecorate %4 0 Offset 0 1572fd4e5da5Sopenharmony_ci OpMemberDecorate %4 1 Offset 4 1573fd4e5da5Sopenharmony_ci OpMemberDecorate %4 2 Offset 8 1574fd4e5da5Sopenharmony_ci OpMemberDecorate %4 3 Offset 12 1575fd4e5da5Sopenharmony_ci OpDecorate %4 Block 1576fd4e5da5Sopenharmony_ci OpDecorate %5 DescriptorSet 0 1577fd4e5da5Sopenharmony_ci OpDecorate %5 Binding 0 1578fd4e5da5Sopenharmony_ci OpDecorate %3 Location 0 1579fd4e5da5Sopenharmony_ci %6 = OpTypeVoid 1580fd4e5da5Sopenharmony_ci %7 = OpTypeFunction %6 1581fd4e5da5Sopenharmony_ci %8 = OpTypeBool 1582fd4e5da5Sopenharmony_ci %10 = OpTypeInt 32 1 1583fd4e5da5Sopenharmony_ci %4 = OpTypeStruct %10 %10 %10 %10 1584fd4e5da5Sopenharmony_ci %11 = OpTypePointer Uniform %4 1585fd4e5da5Sopenharmony_ci %5 = OpVariable %11 Uniform 1586fd4e5da5Sopenharmony_ci %12 = OpConstant %10 0 1587fd4e5da5Sopenharmony_ci %13 = OpTypePointer Uniform %10 1588fd4e5da5Sopenharmony_ci %14 = OpTypeInt 32 0 1589fd4e5da5Sopenharmony_ci %15 = OpConstant %14 0 1590fd4e5da5Sopenharmony_ci %16 = OpConstant %10 1 1591fd4e5da5Sopenharmony_ci %17 = OpConstant %10 2 1592fd4e5da5Sopenharmony_ci %18 = OpConstant %10 3 1593fd4e5da5Sopenharmony_ci %20 = OpConstantFalse %8 1594fd4e5da5Sopenharmony_ci %21 = OpTypeFloat 32 1595fd4e5da5Sopenharmony_ci %22 = OpTypeVector %21 4 1596fd4e5da5Sopenharmony_ci %23 = OpTypePointer Output %22 1597fd4e5da5Sopenharmony_ci %3 = OpVariable %23 Output 1598fd4e5da5Sopenharmony_ci %2 = OpFunction %6 None %7 1599fd4e5da5Sopenharmony_ci %24 = OpLabel 1600fd4e5da5Sopenharmony_ci %31 = OpAccessChain %13 %5 %12 1601fd4e5da5Sopenharmony_ci %32 = OpLoad %10 %31 1602fd4e5da5Sopenharmony_ci %33 = OpINotEqual %8 %32 %15 1603fd4e5da5Sopenharmony_ci %34 = OpAccessChain %13 %5 %16 1604fd4e5da5Sopenharmony_ci %35 = OpLoad %10 %34 1605fd4e5da5Sopenharmony_ci %36 = OpINotEqual %8 %35 %15 1606fd4e5da5Sopenharmony_ci %37 = OpAccessChain %13 %5 %17 1607fd4e5da5Sopenharmony_ci %38 = OpLoad %10 %37 1608fd4e5da5Sopenharmony_ci %39 = OpINotEqual %8 %38 %15 1609fd4e5da5Sopenharmony_ci %40 = OpAccessChain %13 %5 %18 1610fd4e5da5Sopenharmony_ci %41 = OpLoad %10 %40 1611fd4e5da5Sopenharmony_ci %42 = OpINotEqual %8 %41 %15 1612fd4e5da5Sopenharmony_ci OpBranch %44 1613fd4e5da5Sopenharmony_ci %44 = OpLabel 1614fd4e5da5Sopenharmony_ci %98 = OpPhi %10 %12 %24 %107 %46 1615fd4e5da5Sopenharmony_ci %97 = OpPhi %8 %33 %24 %105 %46 1616fd4e5da5Sopenharmony_ci OpLoopMerge %45 %46 None 1617fd4e5da5Sopenharmony_ci OpBranchConditional %97 %49 %45 1618fd4e5da5Sopenharmony_ci %49 = OpLabel 1619fd4e5da5Sopenharmony_ci OpSelectionMerge %51 None 1620fd4e5da5Sopenharmony_ci OpBranchConditional %33 %52 %51 1621fd4e5da5Sopenharmony_ci %52 = OpLabel 1622fd4e5da5Sopenharmony_ci %55 = OpIAdd %10 %98 %16 1623fd4e5da5Sopenharmony_ci OpBranch %51 1624fd4e5da5Sopenharmony_ci %51 = OpLabel 1625fd4e5da5Sopenharmony_ci %100 = OpPhi %10 %98 %49 %55 %52 1626fd4e5da5Sopenharmony_ci %113 = OpSelect %8 %33 %36 %97 1627fd4e5da5Sopenharmony_ci OpSelectionMerge %57 None 1628fd4e5da5Sopenharmony_ci OpBranchConditional %36 %58 %57 1629fd4e5da5Sopenharmony_ci %58 = OpLabel 1630fd4e5da5Sopenharmony_ci %60 = OpIAdd %10 %100 %16 1631fd4e5da5Sopenharmony_ci %63 = OpLogicalOr %8 %113 %33 1632fd4e5da5Sopenharmony_ci OpSelectionMerge %65 None 1633fd4e5da5Sopenharmony_ci OpBranchConditional %39 %66 %65 1634fd4e5da5Sopenharmony_ci %66 = OpLabel 1635fd4e5da5Sopenharmony_ci %68 = OpIAdd %10 %100 %18 1636fd4e5da5Sopenharmony_ci %70 = OpLogicalNot %8 %63 1637fd4e5da5Sopenharmony_ci OpBranch %46 1638fd4e5da5Sopenharmony_ci %65 = OpLabel 1639fd4e5da5Sopenharmony_ci %72 = OpLogicalOr %8 %63 %20 1640fd4e5da5Sopenharmony_ci OpBranch %46 1641fd4e5da5Sopenharmony_ci %57 = OpLabel 1642fd4e5da5Sopenharmony_ci OpBranch %73 1643fd4e5da5Sopenharmony_ci %73 = OpLabel 1644fd4e5da5Sopenharmony_ci %99 = OpPhi %10 %100 %57 %109 %75 1645fd4e5da5Sopenharmony_ci OpLoopMerge %74 %75 None 1646fd4e5da5Sopenharmony_ci OpBranch %76 1647fd4e5da5Sopenharmony_ci %76 = OpLabel 1648fd4e5da5Sopenharmony_ci OpSelectionMerge %78 None 1649fd4e5da5Sopenharmony_ci OpBranchConditional %42 %79 %80 1650fd4e5da5Sopenharmony_ci %79 = OpLabel 1651fd4e5da5Sopenharmony_ci OpSelectionMerge %82 None 1652fd4e5da5Sopenharmony_ci OpSwitch %99 %83 1 %84 2 %85 1653fd4e5da5Sopenharmony_ci %83 = OpLabel 1654fd4e5da5Sopenharmony_ci OpBranch %82 1655fd4e5da5Sopenharmony_ci %84 = OpLabel 1656fd4e5da5Sopenharmony_ci %87 = OpSelect %10 %113 %16 %17 1657fd4e5da5Sopenharmony_ci %89 = OpIAdd %10 %99 %87 1658fd4e5da5Sopenharmony_ci OpBranch %82 1659fd4e5da5Sopenharmony_ci %85 = OpLabel 1660fd4e5da5Sopenharmony_ci OpBranch %75 1661fd4e5da5Sopenharmony_ci %82 = OpLabel 1662fd4e5da5Sopenharmony_ci %110 = OpPhi %10 %99 %83 %89 %84 1663fd4e5da5Sopenharmony_ci OpSelectionMerge %91 None 1664fd4e5da5Sopenharmony_ci OpBranchConditional %39 %92 %91 1665fd4e5da5Sopenharmony_ci %92 = OpLabel 1666fd4e5da5Sopenharmony_ci OpBranch %75 1667fd4e5da5Sopenharmony_ci %91 = OpLabel 1668fd4e5da5Sopenharmony_ci OpBranch %78 1669fd4e5da5Sopenharmony_ci %80 = OpLabel 1670fd4e5da5Sopenharmony_ci OpBranch %74 1671fd4e5da5Sopenharmony_ci %78 = OpLabel 1672fd4e5da5Sopenharmony_ci OpBranch %75 1673fd4e5da5Sopenharmony_ci %75 = OpLabel 1674fd4e5da5Sopenharmony_ci %109 = OpPhi %10 %99 %85 %110 %92 %110 %78 1675fd4e5da5Sopenharmony_ci OpBranchConditional %113 %73 %74 1676fd4e5da5Sopenharmony_ci %74 = OpLabel 1677fd4e5da5Sopenharmony_ci %108 = OpPhi %10 %99 %80 %109 %75 1678fd4e5da5Sopenharmony_ci OpBranch %46 1679fd4e5da5Sopenharmony_ci %46 = OpLabel 1680fd4e5da5Sopenharmony_ci %107 = OpPhi %10 %68 %66 %60 %65 %108 %74 1681fd4e5da5Sopenharmony_ci %105 = OpPhi %8 %70 %66 %72 %65 %113 %74 1682fd4e5da5Sopenharmony_ci OpBranch %44 1683fd4e5da5Sopenharmony_ci %45 = OpLabel 1684fd4e5da5Sopenharmony_ci %95 = OpConvertSToF %21 %98 1685fd4e5da5Sopenharmony_ci %96 = OpCompositeConstruct %22 %95 %95 %95 %95 1686fd4e5da5Sopenharmony_ci OpStore %3 %96 1687fd4e5da5Sopenharmony_ci OpReturn 1688fd4e5da5Sopenharmony_ci OpFunctionEnd 1689fd4e5da5Sopenharmony_ci )"; 1690fd4e5da5Sopenharmony_ci 1691fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 1692fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption); 1693fd4e5da5Sopenharmony_ci const auto ops = StructuredLoopToSelectionReductionOpportunityFinder() 1694fd4e5da5Sopenharmony_ci .GetAvailableOpportunities(context.get(), 0); 1695fd4e5da5Sopenharmony_ci 1696fd4e5da5Sopenharmony_ci ASSERT_EQ(2, ops.size()); 1697fd4e5da5Sopenharmony_ci ASSERT_TRUE(ops[0]->PreconditionHolds()); 1698fd4e5da5Sopenharmony_ci ops[0]->TryToApply(); 1699fd4e5da5Sopenharmony_ci CheckValid(env, context.get()); 1700fd4e5da5Sopenharmony_ci std::string after_op_0 = R"( 1701fd4e5da5Sopenharmony_ci OpCapability Shader 1702fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 1703fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1704fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %2 "main" %3 1705fd4e5da5Sopenharmony_ci OpExecutionMode %2 OriginUpperLeft 1706fd4e5da5Sopenharmony_ci OpSource ESSL 310 1707fd4e5da5Sopenharmony_ci OpMemberDecorate %4 0 Offset 0 1708fd4e5da5Sopenharmony_ci OpMemberDecorate %4 1 Offset 4 1709fd4e5da5Sopenharmony_ci OpMemberDecorate %4 2 Offset 8 1710fd4e5da5Sopenharmony_ci OpMemberDecorate %4 3 Offset 12 1711fd4e5da5Sopenharmony_ci OpDecorate %4 Block 1712fd4e5da5Sopenharmony_ci OpDecorate %5 DescriptorSet 0 1713fd4e5da5Sopenharmony_ci OpDecorate %5 Binding 0 1714fd4e5da5Sopenharmony_ci OpDecorate %3 Location 0 1715fd4e5da5Sopenharmony_ci %6 = OpTypeVoid 1716fd4e5da5Sopenharmony_ci %7 = OpTypeFunction %6 1717fd4e5da5Sopenharmony_ci %8 = OpTypeBool 1718fd4e5da5Sopenharmony_ci %10 = OpTypeInt 32 1 1719fd4e5da5Sopenharmony_ci %4 = OpTypeStruct %10 %10 %10 %10 1720fd4e5da5Sopenharmony_ci %11 = OpTypePointer Uniform %4 1721fd4e5da5Sopenharmony_ci %5 = OpVariable %11 Uniform 1722fd4e5da5Sopenharmony_ci %12 = OpConstant %10 0 1723fd4e5da5Sopenharmony_ci %13 = OpTypePointer Uniform %10 1724fd4e5da5Sopenharmony_ci %14 = OpTypeInt 32 0 1725fd4e5da5Sopenharmony_ci %15 = OpConstant %14 0 1726fd4e5da5Sopenharmony_ci %16 = OpConstant %10 1 1727fd4e5da5Sopenharmony_ci %17 = OpConstant %10 2 1728fd4e5da5Sopenharmony_ci %18 = OpConstant %10 3 1729fd4e5da5Sopenharmony_ci %20 = OpConstantFalse %8 1730fd4e5da5Sopenharmony_ci %21 = OpTypeFloat 32 1731fd4e5da5Sopenharmony_ci %22 = OpTypeVector %21 4 1732fd4e5da5Sopenharmony_ci %23 = OpTypePointer Output %22 1733fd4e5da5Sopenharmony_ci %3 = OpVariable %23 Output 1734fd4e5da5Sopenharmony_ci %114 = OpUndef %10 1735fd4e5da5Sopenharmony_ci %115 = OpUndef %8 1736fd4e5da5Sopenharmony_ci %2 = OpFunction %6 None %7 1737fd4e5da5Sopenharmony_ci %24 = OpLabel 1738fd4e5da5Sopenharmony_ci %31 = OpAccessChain %13 %5 %12 1739fd4e5da5Sopenharmony_ci %32 = OpLoad %10 %31 1740fd4e5da5Sopenharmony_ci %33 = OpINotEqual %8 %32 %15 1741fd4e5da5Sopenharmony_ci %34 = OpAccessChain %13 %5 %16 1742fd4e5da5Sopenharmony_ci %35 = OpLoad %10 %34 1743fd4e5da5Sopenharmony_ci %36 = OpINotEqual %8 %35 %15 1744fd4e5da5Sopenharmony_ci %37 = OpAccessChain %13 %5 %17 1745fd4e5da5Sopenharmony_ci %38 = OpLoad %10 %37 1746fd4e5da5Sopenharmony_ci %39 = OpINotEqual %8 %38 %15 1747fd4e5da5Sopenharmony_ci %40 = OpAccessChain %13 %5 %18 1748fd4e5da5Sopenharmony_ci %41 = OpLoad %10 %40 1749fd4e5da5Sopenharmony_ci %42 = OpINotEqual %8 %41 %15 1750fd4e5da5Sopenharmony_ci OpBranch %44 1751fd4e5da5Sopenharmony_ci %44 = OpLabel 1752fd4e5da5Sopenharmony_ci %98 = OpPhi %10 %12 %24 %114 %46 1753fd4e5da5Sopenharmony_ci %97 = OpPhi %8 %33 %24 %115 %46 1754fd4e5da5Sopenharmony_ci OpSelectionMerge %45 None ; Was OpLoopMerge %45 %46 None 1755fd4e5da5Sopenharmony_ci OpBranchConditional %97 %49 %45 1756fd4e5da5Sopenharmony_ci %49 = OpLabel 1757fd4e5da5Sopenharmony_ci OpSelectionMerge %51 None 1758fd4e5da5Sopenharmony_ci OpBranchConditional %33 %52 %51 1759fd4e5da5Sopenharmony_ci %52 = OpLabel 1760fd4e5da5Sopenharmony_ci %55 = OpIAdd %10 %98 %16 1761fd4e5da5Sopenharmony_ci OpBranch %51 1762fd4e5da5Sopenharmony_ci %51 = OpLabel 1763fd4e5da5Sopenharmony_ci %100 = OpPhi %10 %98 %49 %55 %52 1764fd4e5da5Sopenharmony_ci %113 = OpSelect %8 %33 %36 %97 1765fd4e5da5Sopenharmony_ci OpSelectionMerge %57 None 1766fd4e5da5Sopenharmony_ci OpBranchConditional %36 %58 %57 1767fd4e5da5Sopenharmony_ci %58 = OpLabel 1768fd4e5da5Sopenharmony_ci %60 = OpIAdd %10 %100 %16 1769fd4e5da5Sopenharmony_ci %63 = OpLogicalOr %8 %113 %33 1770fd4e5da5Sopenharmony_ci OpSelectionMerge %65 None 1771fd4e5da5Sopenharmony_ci OpBranchConditional %39 %66 %65 1772fd4e5da5Sopenharmony_ci %66 = OpLabel 1773fd4e5da5Sopenharmony_ci %68 = OpIAdd %10 %100 %18 1774fd4e5da5Sopenharmony_ci %70 = OpLogicalNot %8 %63 1775fd4e5da5Sopenharmony_ci OpBranch %65 ; Was OpBranch %46 1776fd4e5da5Sopenharmony_ci %65 = OpLabel 1777fd4e5da5Sopenharmony_ci %72 = OpLogicalOr %8 %63 %20 1778fd4e5da5Sopenharmony_ci OpBranch %57 ; Was OpBranch %46 1779fd4e5da5Sopenharmony_ci %57 = OpLabel 1780fd4e5da5Sopenharmony_ci OpBranch %73 1781fd4e5da5Sopenharmony_ci %73 = OpLabel 1782fd4e5da5Sopenharmony_ci %99 = OpPhi %10 %100 %57 %109 %75 1783fd4e5da5Sopenharmony_ci OpLoopMerge %74 %75 None 1784fd4e5da5Sopenharmony_ci OpBranch %76 1785fd4e5da5Sopenharmony_ci %76 = OpLabel 1786fd4e5da5Sopenharmony_ci OpSelectionMerge %78 None 1787fd4e5da5Sopenharmony_ci OpBranchConditional %42 %79 %80 1788fd4e5da5Sopenharmony_ci %79 = OpLabel 1789fd4e5da5Sopenharmony_ci OpSelectionMerge %82 None 1790fd4e5da5Sopenharmony_ci OpSwitch %99 %83 1 %84 2 %85 1791fd4e5da5Sopenharmony_ci %83 = OpLabel 1792fd4e5da5Sopenharmony_ci OpBranch %82 1793fd4e5da5Sopenharmony_ci %84 = OpLabel 1794fd4e5da5Sopenharmony_ci %87 = OpSelect %10 %113 %16 %17 1795fd4e5da5Sopenharmony_ci %89 = OpIAdd %10 %99 %87 1796fd4e5da5Sopenharmony_ci OpBranch %82 1797fd4e5da5Sopenharmony_ci %85 = OpLabel 1798fd4e5da5Sopenharmony_ci OpBranch %75 1799fd4e5da5Sopenharmony_ci %82 = OpLabel 1800fd4e5da5Sopenharmony_ci %110 = OpPhi %10 %99 %83 %89 %84 1801fd4e5da5Sopenharmony_ci OpSelectionMerge %91 None 1802fd4e5da5Sopenharmony_ci OpBranchConditional %39 %92 %91 1803fd4e5da5Sopenharmony_ci %92 = OpLabel 1804fd4e5da5Sopenharmony_ci OpBranch %75 1805fd4e5da5Sopenharmony_ci %91 = OpLabel 1806fd4e5da5Sopenharmony_ci OpBranch %78 1807fd4e5da5Sopenharmony_ci %80 = OpLabel 1808fd4e5da5Sopenharmony_ci OpBranch %74 1809fd4e5da5Sopenharmony_ci %78 = OpLabel 1810fd4e5da5Sopenharmony_ci OpBranch %75 1811fd4e5da5Sopenharmony_ci %75 = OpLabel 1812fd4e5da5Sopenharmony_ci %109 = OpPhi %10 %99 %85 %110 %92 %110 %78 1813fd4e5da5Sopenharmony_ci OpBranchConditional %113 %73 %74 1814fd4e5da5Sopenharmony_ci %74 = OpLabel 1815fd4e5da5Sopenharmony_ci %108 = OpPhi %10 %99 %80 %109 %75 1816fd4e5da5Sopenharmony_ci OpBranch %45 ; Was OpBranch %46 1817fd4e5da5Sopenharmony_ci %46 = OpLabel 1818fd4e5da5Sopenharmony_ci %107 = OpPhi %10 ; Was OpPhi %10 %68 %66 %60 %65 %108 %74 1819fd4e5da5Sopenharmony_ci %105 = OpPhi %8 ; Was OpPhi %8 %70 %66 %72 %65 %113 %74 1820fd4e5da5Sopenharmony_ci OpBranch %44 1821fd4e5da5Sopenharmony_ci %45 = OpLabel 1822fd4e5da5Sopenharmony_ci %95 = OpConvertSToF %21 %98 1823fd4e5da5Sopenharmony_ci %96 = OpCompositeConstruct %22 %95 %95 %95 %95 1824fd4e5da5Sopenharmony_ci OpStore %3 %96 1825fd4e5da5Sopenharmony_ci OpReturn 1826fd4e5da5Sopenharmony_ci OpFunctionEnd 1827fd4e5da5Sopenharmony_ci )"; 1828fd4e5da5Sopenharmony_ci CheckEqual(env, after_op_0, context.get()); 1829fd4e5da5Sopenharmony_ci 1830fd4e5da5Sopenharmony_ci ASSERT_TRUE(ops[1]->PreconditionHolds()); 1831fd4e5da5Sopenharmony_ci ops[1]->TryToApply(); 1832fd4e5da5Sopenharmony_ci CheckValid(env, context.get()); 1833fd4e5da5Sopenharmony_ci std::string after_op_1 = R"( 1834fd4e5da5Sopenharmony_ci OpCapability Shader 1835fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 1836fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1837fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %2 "main" %3 1838fd4e5da5Sopenharmony_ci OpExecutionMode %2 OriginUpperLeft 1839fd4e5da5Sopenharmony_ci OpSource ESSL 310 1840fd4e5da5Sopenharmony_ci OpMemberDecorate %4 0 Offset 0 1841fd4e5da5Sopenharmony_ci OpMemberDecorate %4 1 Offset 4 1842fd4e5da5Sopenharmony_ci OpMemberDecorate %4 2 Offset 8 1843fd4e5da5Sopenharmony_ci OpMemberDecorate %4 3 Offset 12 1844fd4e5da5Sopenharmony_ci OpDecorate %4 Block 1845fd4e5da5Sopenharmony_ci OpDecorate %5 DescriptorSet 0 1846fd4e5da5Sopenharmony_ci OpDecorate %5 Binding 0 1847fd4e5da5Sopenharmony_ci OpDecorate %3 Location 0 1848fd4e5da5Sopenharmony_ci %6 = OpTypeVoid 1849fd4e5da5Sopenharmony_ci %7 = OpTypeFunction %6 1850fd4e5da5Sopenharmony_ci %8 = OpTypeBool 1851fd4e5da5Sopenharmony_ci %10 = OpTypeInt 32 1 1852fd4e5da5Sopenharmony_ci %4 = OpTypeStruct %10 %10 %10 %10 1853fd4e5da5Sopenharmony_ci %11 = OpTypePointer Uniform %4 1854fd4e5da5Sopenharmony_ci %5 = OpVariable %11 Uniform 1855fd4e5da5Sopenharmony_ci %12 = OpConstant %10 0 1856fd4e5da5Sopenharmony_ci %13 = OpTypePointer Uniform %10 1857fd4e5da5Sopenharmony_ci %14 = OpTypeInt 32 0 1858fd4e5da5Sopenharmony_ci %15 = OpConstant %14 0 1859fd4e5da5Sopenharmony_ci %16 = OpConstant %10 1 1860fd4e5da5Sopenharmony_ci %17 = OpConstant %10 2 1861fd4e5da5Sopenharmony_ci %18 = OpConstant %10 3 1862fd4e5da5Sopenharmony_ci %20 = OpConstantFalse %8 1863fd4e5da5Sopenharmony_ci %21 = OpTypeFloat 32 1864fd4e5da5Sopenharmony_ci %22 = OpTypeVector %21 4 1865fd4e5da5Sopenharmony_ci %23 = OpTypePointer Output %22 1866fd4e5da5Sopenharmony_ci %3 = OpVariable %23 Output 1867fd4e5da5Sopenharmony_ci %114 = OpUndef %10 1868fd4e5da5Sopenharmony_ci %115 = OpUndef %8 1869fd4e5da5Sopenharmony_ci %116 = OpConstantTrue %8 1870fd4e5da5Sopenharmony_ci %2 = OpFunction %6 None %7 1871fd4e5da5Sopenharmony_ci %24 = OpLabel 1872fd4e5da5Sopenharmony_ci %31 = OpAccessChain %13 %5 %12 1873fd4e5da5Sopenharmony_ci %32 = OpLoad %10 %31 1874fd4e5da5Sopenharmony_ci %33 = OpINotEqual %8 %32 %15 1875fd4e5da5Sopenharmony_ci %34 = OpAccessChain %13 %5 %16 1876fd4e5da5Sopenharmony_ci %35 = OpLoad %10 %34 1877fd4e5da5Sopenharmony_ci %36 = OpINotEqual %8 %35 %15 1878fd4e5da5Sopenharmony_ci %37 = OpAccessChain %13 %5 %17 1879fd4e5da5Sopenharmony_ci %38 = OpLoad %10 %37 1880fd4e5da5Sopenharmony_ci %39 = OpINotEqual %8 %38 %15 1881fd4e5da5Sopenharmony_ci %40 = OpAccessChain %13 %5 %18 1882fd4e5da5Sopenharmony_ci %41 = OpLoad %10 %40 1883fd4e5da5Sopenharmony_ci %42 = OpINotEqual %8 %41 %15 1884fd4e5da5Sopenharmony_ci OpBranch %44 1885fd4e5da5Sopenharmony_ci %44 = OpLabel 1886fd4e5da5Sopenharmony_ci %98 = OpPhi %10 %12 %24 %114 %46 1887fd4e5da5Sopenharmony_ci %97 = OpPhi %8 %33 %24 %115 %46 1888fd4e5da5Sopenharmony_ci OpSelectionMerge %45 None ; Was OpLoopMerge %45 %46 None 1889fd4e5da5Sopenharmony_ci OpBranchConditional %97 %49 %45 1890fd4e5da5Sopenharmony_ci %49 = OpLabel 1891fd4e5da5Sopenharmony_ci OpSelectionMerge %51 None 1892fd4e5da5Sopenharmony_ci OpBranchConditional %33 %52 %51 1893fd4e5da5Sopenharmony_ci %52 = OpLabel 1894fd4e5da5Sopenharmony_ci %55 = OpIAdd %10 %98 %16 1895fd4e5da5Sopenharmony_ci OpBranch %51 1896fd4e5da5Sopenharmony_ci %51 = OpLabel 1897fd4e5da5Sopenharmony_ci %100 = OpPhi %10 %98 %49 %55 %52 1898fd4e5da5Sopenharmony_ci %113 = OpSelect %8 %33 %36 %97 1899fd4e5da5Sopenharmony_ci OpSelectionMerge %57 None 1900fd4e5da5Sopenharmony_ci OpBranchConditional %36 %58 %57 1901fd4e5da5Sopenharmony_ci %58 = OpLabel 1902fd4e5da5Sopenharmony_ci %60 = OpIAdd %10 %100 %16 1903fd4e5da5Sopenharmony_ci %63 = OpLogicalOr %8 %113 %33 1904fd4e5da5Sopenharmony_ci OpSelectionMerge %65 None 1905fd4e5da5Sopenharmony_ci OpBranchConditional %39 %66 %65 1906fd4e5da5Sopenharmony_ci %66 = OpLabel 1907fd4e5da5Sopenharmony_ci %68 = OpIAdd %10 %100 %18 1908fd4e5da5Sopenharmony_ci %70 = OpLogicalNot %8 %63 1909fd4e5da5Sopenharmony_ci OpBranch %65 ; Was OpBranch %46 1910fd4e5da5Sopenharmony_ci %65 = OpLabel 1911fd4e5da5Sopenharmony_ci %72 = OpLogicalOr %8 %63 %20 1912fd4e5da5Sopenharmony_ci OpBranch %57 ; Was OpBranch %46 1913fd4e5da5Sopenharmony_ci %57 = OpLabel 1914fd4e5da5Sopenharmony_ci OpBranch %73 1915fd4e5da5Sopenharmony_ci %73 = OpLabel 1916fd4e5da5Sopenharmony_ci %99 = OpPhi %10 %100 %57 %114 %75 1917fd4e5da5Sopenharmony_ci OpSelectionMerge %74 None ; Was OpLoopMerge %74 %75 None 1918fd4e5da5Sopenharmony_ci OpBranchConditional %116 %76 %74 1919fd4e5da5Sopenharmony_ci %76 = OpLabel 1920fd4e5da5Sopenharmony_ci OpSelectionMerge %78 None 1921fd4e5da5Sopenharmony_ci OpBranchConditional %42 %79 %80 1922fd4e5da5Sopenharmony_ci %79 = OpLabel 1923fd4e5da5Sopenharmony_ci OpSelectionMerge %82 None 1924fd4e5da5Sopenharmony_ci OpSwitch %99 %83 1 %84 2 %85 1925fd4e5da5Sopenharmony_ci %83 = OpLabel 1926fd4e5da5Sopenharmony_ci OpBranch %82 1927fd4e5da5Sopenharmony_ci %84 = OpLabel 1928fd4e5da5Sopenharmony_ci %87 = OpSelect %10 %113 %16 %17 1929fd4e5da5Sopenharmony_ci %89 = OpIAdd %10 %99 %87 1930fd4e5da5Sopenharmony_ci OpBranch %82 1931fd4e5da5Sopenharmony_ci %85 = OpLabel 1932fd4e5da5Sopenharmony_ci OpBranch %82 ; Was OpBranch %75 1933fd4e5da5Sopenharmony_ci %82 = OpLabel 1934fd4e5da5Sopenharmony_ci %110 = OpPhi %10 %99 %83 %89 %84 %114 %85 ; Was OpPhi %10 %99 %83 %89 %84 1935fd4e5da5Sopenharmony_ci OpSelectionMerge %91 None 1936fd4e5da5Sopenharmony_ci OpBranchConditional %39 %92 %91 1937fd4e5da5Sopenharmony_ci %92 = OpLabel 1938fd4e5da5Sopenharmony_ci OpBranch %91 ; OpBranch %75 1939fd4e5da5Sopenharmony_ci %91 = OpLabel 1940fd4e5da5Sopenharmony_ci OpBranch %78 1941fd4e5da5Sopenharmony_ci %80 = OpLabel 1942fd4e5da5Sopenharmony_ci OpBranch %78 ; Was OpBranch %74 1943fd4e5da5Sopenharmony_ci %78 = OpLabel 1944fd4e5da5Sopenharmony_ci OpBranch %74 ; Was OpBranch %75 1945fd4e5da5Sopenharmony_ci %75 = OpLabel 1946fd4e5da5Sopenharmony_ci %109 = OpPhi %10 ; Was OpPhi %10 %99 %85 %110 %92 %110 %78 1947fd4e5da5Sopenharmony_ci OpBranchConditional %115 %73 %74 1948fd4e5da5Sopenharmony_ci %74 = OpLabel 1949fd4e5da5Sopenharmony_ci %108 = OpPhi %10 %114 %75 %114 %78 %114 %73 ; Was OpPhi %10 %99 %80 %109 %75 1950fd4e5da5Sopenharmony_ci OpBranch %45 ; Was OpBranch %46 1951fd4e5da5Sopenharmony_ci %46 = OpLabel 1952fd4e5da5Sopenharmony_ci %107 = OpPhi %10 ; Was OpPhi %10 %68 %66 %60 %65 %108 %74 1953fd4e5da5Sopenharmony_ci %105 = OpPhi %8 ; Was OpPhi %8 %70 %66 %72 %65 %113 %74 1954fd4e5da5Sopenharmony_ci OpBranch %44 1955fd4e5da5Sopenharmony_ci %45 = OpLabel 1956fd4e5da5Sopenharmony_ci %95 = OpConvertSToF %21 %98 1957fd4e5da5Sopenharmony_ci %96 = OpCompositeConstruct %22 %95 %95 %95 %95 1958fd4e5da5Sopenharmony_ci OpStore %3 %96 1959fd4e5da5Sopenharmony_ci OpReturn 1960fd4e5da5Sopenharmony_ci OpFunctionEnd 1961fd4e5da5Sopenharmony_ci )"; 1962fd4e5da5Sopenharmony_ci CheckEqual(env, after_op_1, context.get()); 1963fd4e5da5Sopenharmony_ci} 1964fd4e5da5Sopenharmony_ci 1965fd4e5da5Sopenharmony_ciTEST(StructuredLoopToSelectionReductionPassTest, DominanceIssue) { 1966fd4e5da5Sopenharmony_ci // Exposes a scenario where redirecting edges results in uses of ids being 1967fd4e5da5Sopenharmony_ci // non-dominated. We replace such uses with OpUndef to account for this. 1968fd4e5da5Sopenharmony_ci std::string shader = R"( 1969fd4e5da5Sopenharmony_ci OpCapability Shader 1970fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 1971fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 1972fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 1973fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 1974fd4e5da5Sopenharmony_ci OpSource ESSL 310 1975fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 1976fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 1977fd4e5da5Sopenharmony_ci %5 = OpTypeInt 32 1 1978fd4e5da5Sopenharmony_ci %7 = OpTypePointer Function %5 1979fd4e5da5Sopenharmony_ci %6 = OpTypeBool 1980fd4e5da5Sopenharmony_ci %8 = OpConstantTrue %6 1981fd4e5da5Sopenharmony_ci %9 = OpConstant %5 10 1982fd4e5da5Sopenharmony_ci %10 = OpConstant %5 20 1983fd4e5da5Sopenharmony_ci %11 = OpConstant %5 30 1984fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 1985fd4e5da5Sopenharmony_ci %12 = OpLabel 1986fd4e5da5Sopenharmony_ci OpBranch %13 1987fd4e5da5Sopenharmony_ci %13 = OpLabel 1988fd4e5da5Sopenharmony_ci OpLoopMerge %14 %15 None 1989fd4e5da5Sopenharmony_ci OpBranch %16 1990fd4e5da5Sopenharmony_ci %16 = OpLabel 1991fd4e5da5Sopenharmony_ci OpSelectionMerge %17 None 1992fd4e5da5Sopenharmony_ci OpBranchConditional %8 %18 %19 1993fd4e5da5Sopenharmony_ci %18 = OpLabel 1994fd4e5da5Sopenharmony_ci OpBranch %14 1995fd4e5da5Sopenharmony_ci %19 = OpLabel 1996fd4e5da5Sopenharmony_ci %20 = OpIAdd %5 %9 %10 1997fd4e5da5Sopenharmony_ci OpBranch %17 1998fd4e5da5Sopenharmony_ci %17 = OpLabel 1999fd4e5da5Sopenharmony_ci %21 = OpIAdd %5 %20 %11 2000fd4e5da5Sopenharmony_ci OpBranchConditional %8 %14 %15 2001fd4e5da5Sopenharmony_ci %15 = OpLabel 2002fd4e5da5Sopenharmony_ci OpBranch %13 2003fd4e5da5Sopenharmony_ci %14 = OpLabel 2004fd4e5da5Sopenharmony_ci OpReturn 2005fd4e5da5Sopenharmony_ci OpFunctionEnd 2006fd4e5da5Sopenharmony_ci )"; 2007fd4e5da5Sopenharmony_ci 2008fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 2009fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption); 2010fd4e5da5Sopenharmony_ci const auto ops = StructuredLoopToSelectionReductionOpportunityFinder() 2011fd4e5da5Sopenharmony_ci .GetAvailableOpportunities(context.get(), 0); 2012fd4e5da5Sopenharmony_ci ASSERT_EQ(1, ops.size()); 2013fd4e5da5Sopenharmony_ci 2014fd4e5da5Sopenharmony_ci ASSERT_TRUE(ops[0]->PreconditionHolds()); 2015fd4e5da5Sopenharmony_ci ops[0]->TryToApply(); 2016fd4e5da5Sopenharmony_ci CheckValid(env, context.get()); 2017fd4e5da5Sopenharmony_ci 2018fd4e5da5Sopenharmony_ci std::string expected = R"( 2019fd4e5da5Sopenharmony_ci OpCapability Shader 2020fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 2021fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 2022fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 2023fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 2024fd4e5da5Sopenharmony_ci OpSource ESSL 310 2025fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 2026fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 2027fd4e5da5Sopenharmony_ci %5 = OpTypeInt 32 1 2028fd4e5da5Sopenharmony_ci %7 = OpTypePointer Function %5 2029fd4e5da5Sopenharmony_ci %6 = OpTypeBool 2030fd4e5da5Sopenharmony_ci %8 = OpConstantTrue %6 2031fd4e5da5Sopenharmony_ci %9 = OpConstant %5 10 2032fd4e5da5Sopenharmony_ci %10 = OpConstant %5 20 2033fd4e5da5Sopenharmony_ci %11 = OpConstant %5 30 2034fd4e5da5Sopenharmony_ci %22 = OpUndef %5 2035fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 2036fd4e5da5Sopenharmony_ci %12 = OpLabel 2037fd4e5da5Sopenharmony_ci OpBranch %13 2038fd4e5da5Sopenharmony_ci %13 = OpLabel 2039fd4e5da5Sopenharmony_ci OpSelectionMerge %14 None 2040fd4e5da5Sopenharmony_ci OpBranchConditional %8 %16 %14 2041fd4e5da5Sopenharmony_ci %16 = OpLabel 2042fd4e5da5Sopenharmony_ci OpSelectionMerge %17 None 2043fd4e5da5Sopenharmony_ci OpBranchConditional %8 %18 %19 2044fd4e5da5Sopenharmony_ci %18 = OpLabel 2045fd4e5da5Sopenharmony_ci OpBranch %17 2046fd4e5da5Sopenharmony_ci %19 = OpLabel 2047fd4e5da5Sopenharmony_ci %20 = OpIAdd %5 %9 %10 2048fd4e5da5Sopenharmony_ci OpBranch %17 2049fd4e5da5Sopenharmony_ci %17 = OpLabel 2050fd4e5da5Sopenharmony_ci %21 = OpIAdd %5 %22 %11 2051fd4e5da5Sopenharmony_ci OpBranchConditional %8 %14 %14 2052fd4e5da5Sopenharmony_ci %15 = OpLabel 2053fd4e5da5Sopenharmony_ci OpBranch %13 2054fd4e5da5Sopenharmony_ci %14 = OpLabel 2055fd4e5da5Sopenharmony_ci OpReturn 2056fd4e5da5Sopenharmony_ci OpFunctionEnd 2057fd4e5da5Sopenharmony_ci )"; 2058fd4e5da5Sopenharmony_ci CheckEqual(env, expected, context.get()); 2059fd4e5da5Sopenharmony_ci} 2060fd4e5da5Sopenharmony_ci 2061fd4e5da5Sopenharmony_ciTEST(StructuredLoopToSelectionReductionPassTest, AccessChainIssue) { 2062fd4e5da5Sopenharmony_ci // Exposes a scenario where redirecting edges results in a use of an id 2063fd4e5da5Sopenharmony_ci // generated by an access chain being non-dominated. 2064fd4e5da5Sopenharmony_ci std::string shader = R"( 2065fd4e5da5Sopenharmony_ci OpCapability Shader 2066fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 2067fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 2068fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" %56 2069fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 2070fd4e5da5Sopenharmony_ci OpSource ESSL 310 2071fd4e5da5Sopenharmony_ci OpMemberDecorate %28 0 Offset 0 2072fd4e5da5Sopenharmony_ci OpDecorate %28 Block 2073fd4e5da5Sopenharmony_ci OpDecorate %30 DescriptorSet 0 2074fd4e5da5Sopenharmony_ci OpDecorate %30 Binding 0 2075fd4e5da5Sopenharmony_ci OpDecorate %56 Location 0 2076fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 2077fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 2078fd4e5da5Sopenharmony_ci %6 = OpTypeFloat 32 2079fd4e5da5Sopenharmony_ci %7 = OpTypeVector %6 2 2080fd4e5da5Sopenharmony_ci %8 = OpTypePointer Function %7 2081fd4e5da5Sopenharmony_ci %60 = OpTypePointer Private %7 2082fd4e5da5Sopenharmony_ci %10 = OpConstant %6 0 2083fd4e5da5Sopenharmony_ci %11 = OpConstantComposite %7 %10 %10 2084fd4e5da5Sopenharmony_ci %12 = OpTypePointer Function %6 2085fd4e5da5Sopenharmony_ci %59 = OpTypePointer Private %6 2086fd4e5da5Sopenharmony_ci %14 = OpTypeInt 32 1 2087fd4e5da5Sopenharmony_ci %15 = OpTypePointer Function %14 2088fd4e5da5Sopenharmony_ci %17 = OpConstant %14 0 2089fd4e5da5Sopenharmony_ci %24 = OpConstant %14 100 2090fd4e5da5Sopenharmony_ci %25 = OpTypeBool 2091fd4e5da5Sopenharmony_ci %28 = OpTypeStruct %6 2092fd4e5da5Sopenharmony_ci %29 = OpTypePointer Uniform %28 2093fd4e5da5Sopenharmony_ci %30 = OpVariable %29 Uniform 2094fd4e5da5Sopenharmony_ci %31 = OpTypePointer Uniform %6 2095fd4e5da5Sopenharmony_ci %39 = OpTypeInt 32 0 2096fd4e5da5Sopenharmony_ci %40 = OpConstant %39 1 2097fd4e5da5Sopenharmony_ci %45 = OpConstant %39 0 2098fd4e5da5Sopenharmony_ci %52 = OpConstant %14 1 2099fd4e5da5Sopenharmony_ci %54 = OpTypeVector %6 4 2100fd4e5da5Sopenharmony_ci %55 = OpTypePointer Output %54 2101fd4e5da5Sopenharmony_ci %56 = OpVariable %55 Output 2102fd4e5da5Sopenharmony_ci %9 = OpVariable %60 Private 2103fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 2104fd4e5da5Sopenharmony_ci %5 = OpLabel 2105fd4e5da5Sopenharmony_ci %13 = OpVariable %12 Function 2106fd4e5da5Sopenharmony_ci %16 = OpVariable %15 Function 2107fd4e5da5Sopenharmony_ci %38 = OpVariable %12 Function 2108fd4e5da5Sopenharmony_ci OpStore %9 %11 2109fd4e5da5Sopenharmony_ci OpStore %13 %10 2110fd4e5da5Sopenharmony_ci OpStore %16 %17 2111fd4e5da5Sopenharmony_ci OpBranch %18 2112fd4e5da5Sopenharmony_ci %18 = OpLabel 2113fd4e5da5Sopenharmony_ci OpLoopMerge %20 %21 None 2114fd4e5da5Sopenharmony_ci OpBranch %22 2115fd4e5da5Sopenharmony_ci %22 = OpLabel 2116fd4e5da5Sopenharmony_ci %23 = OpLoad %14 %16 2117fd4e5da5Sopenharmony_ci %26 = OpSLessThan %25 %23 %24 2118fd4e5da5Sopenharmony_ci OpBranchConditional %26 %19 %20 2119fd4e5da5Sopenharmony_ci %19 = OpLabel 2120fd4e5da5Sopenharmony_ci %27 = OpLoad %14 %16 2121fd4e5da5Sopenharmony_ci %32 = OpAccessChain %31 %30 %17 2122fd4e5da5Sopenharmony_ci %33 = OpLoad %6 %32 2123fd4e5da5Sopenharmony_ci %34 = OpConvertFToS %14 %33 2124fd4e5da5Sopenharmony_ci %35 = OpSLessThan %25 %27 %34 2125fd4e5da5Sopenharmony_ci OpSelectionMerge %37 None 2126fd4e5da5Sopenharmony_ci OpBranchConditional %35 %36 %44 2127fd4e5da5Sopenharmony_ci %36 = OpLabel 2128fd4e5da5Sopenharmony_ci %41 = OpAccessChain %59 %9 %40 2129fd4e5da5Sopenharmony_ci %42 = OpLoad %6 %41 2130fd4e5da5Sopenharmony_ci OpStore %38 %42 2131fd4e5da5Sopenharmony_ci OpBranch %20 2132fd4e5da5Sopenharmony_ci %44 = OpLabel 2133fd4e5da5Sopenharmony_ci %46 = OpAccessChain %59 %9 %45 2134fd4e5da5Sopenharmony_ci OpBranch %37 2135fd4e5da5Sopenharmony_ci %37 = OpLabel 2136fd4e5da5Sopenharmony_ci %47 = OpLoad %6 %46 2137fd4e5da5Sopenharmony_ci OpStore %38 %47 2138fd4e5da5Sopenharmony_ci %48 = OpLoad %6 %38 2139fd4e5da5Sopenharmony_ci %49 = OpLoad %6 %13 2140fd4e5da5Sopenharmony_ci %50 = OpFAdd %6 %49 %48 2141fd4e5da5Sopenharmony_ci OpStore %13 %50 2142fd4e5da5Sopenharmony_ci OpBranch %21 2143fd4e5da5Sopenharmony_ci %21 = OpLabel 2144fd4e5da5Sopenharmony_ci %51 = OpLoad %14 %16 2145fd4e5da5Sopenharmony_ci %53 = OpIAdd %14 %51 %52 2146fd4e5da5Sopenharmony_ci OpStore %16 %53 2147fd4e5da5Sopenharmony_ci OpBranch %18 2148fd4e5da5Sopenharmony_ci %20 = OpLabel 2149fd4e5da5Sopenharmony_ci %57 = OpLoad %6 %13 2150fd4e5da5Sopenharmony_ci %58 = OpCompositeConstruct %54 %57 %57 %57 %57 2151fd4e5da5Sopenharmony_ci OpStore %56 %58 2152fd4e5da5Sopenharmony_ci OpReturn 2153fd4e5da5Sopenharmony_ci OpFunctionEnd 2154fd4e5da5Sopenharmony_ci )"; 2155fd4e5da5Sopenharmony_ci 2156fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 2157fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption); 2158fd4e5da5Sopenharmony_ci const auto ops = StructuredLoopToSelectionReductionOpportunityFinder() 2159fd4e5da5Sopenharmony_ci .GetAvailableOpportunities(context.get(), 0); 2160fd4e5da5Sopenharmony_ci ASSERT_EQ(1, ops.size()); 2161fd4e5da5Sopenharmony_ci 2162fd4e5da5Sopenharmony_ci ASSERT_TRUE(ops[0]->PreconditionHolds()); 2163fd4e5da5Sopenharmony_ci ops[0]->TryToApply(); 2164fd4e5da5Sopenharmony_ci CheckValid(env, context.get()); 2165fd4e5da5Sopenharmony_ci 2166fd4e5da5Sopenharmony_ci std::string expected = R"( 2167fd4e5da5Sopenharmony_ci OpCapability Shader 2168fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 2169fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 2170fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" %56 2171fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 2172fd4e5da5Sopenharmony_ci OpSource ESSL 310 2173fd4e5da5Sopenharmony_ci OpMemberDecorate %28 0 Offset 0 2174fd4e5da5Sopenharmony_ci OpDecorate %28 Block 2175fd4e5da5Sopenharmony_ci OpDecorate %30 DescriptorSet 0 2176fd4e5da5Sopenharmony_ci OpDecorate %30 Binding 0 2177fd4e5da5Sopenharmony_ci OpDecorate %56 Location 0 2178fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 2179fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 2180fd4e5da5Sopenharmony_ci %6 = OpTypeFloat 32 2181fd4e5da5Sopenharmony_ci %7 = OpTypeVector %6 2 2182fd4e5da5Sopenharmony_ci %8 = OpTypePointer Function %7 2183fd4e5da5Sopenharmony_ci %60 = OpTypePointer Private %7 2184fd4e5da5Sopenharmony_ci %10 = OpConstant %6 0 2185fd4e5da5Sopenharmony_ci %11 = OpConstantComposite %7 %10 %10 2186fd4e5da5Sopenharmony_ci %12 = OpTypePointer Function %6 2187fd4e5da5Sopenharmony_ci %59 = OpTypePointer Private %6 2188fd4e5da5Sopenharmony_ci %14 = OpTypeInt 32 1 2189fd4e5da5Sopenharmony_ci %15 = OpTypePointer Function %14 2190fd4e5da5Sopenharmony_ci %17 = OpConstant %14 0 2191fd4e5da5Sopenharmony_ci %24 = OpConstant %14 100 2192fd4e5da5Sopenharmony_ci %25 = OpTypeBool 2193fd4e5da5Sopenharmony_ci %28 = OpTypeStruct %6 2194fd4e5da5Sopenharmony_ci %29 = OpTypePointer Uniform %28 2195fd4e5da5Sopenharmony_ci %30 = OpVariable %29 Uniform 2196fd4e5da5Sopenharmony_ci %31 = OpTypePointer Uniform %6 2197fd4e5da5Sopenharmony_ci %39 = OpTypeInt 32 0 2198fd4e5da5Sopenharmony_ci %40 = OpConstant %39 1 2199fd4e5da5Sopenharmony_ci %45 = OpConstant %39 0 2200fd4e5da5Sopenharmony_ci %52 = OpConstant %14 1 2201fd4e5da5Sopenharmony_ci %54 = OpTypeVector %6 4 2202fd4e5da5Sopenharmony_ci %55 = OpTypePointer Output %54 2203fd4e5da5Sopenharmony_ci %56 = OpVariable %55 Output 2204fd4e5da5Sopenharmony_ci %9 = OpVariable %60 Private 2205fd4e5da5Sopenharmony_ci %61 = OpConstantTrue %25 2206fd4e5da5Sopenharmony_ci %62 = OpVariable %59 Private 2207fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 2208fd4e5da5Sopenharmony_ci %5 = OpLabel 2209fd4e5da5Sopenharmony_ci %13 = OpVariable %12 Function 2210fd4e5da5Sopenharmony_ci %16 = OpVariable %15 Function 2211fd4e5da5Sopenharmony_ci %38 = OpVariable %12 Function 2212fd4e5da5Sopenharmony_ci OpStore %9 %11 2213fd4e5da5Sopenharmony_ci OpStore %13 %10 2214fd4e5da5Sopenharmony_ci OpStore %16 %17 2215fd4e5da5Sopenharmony_ci OpBranch %18 2216fd4e5da5Sopenharmony_ci %18 = OpLabel 2217fd4e5da5Sopenharmony_ci OpSelectionMerge %20 None 2218fd4e5da5Sopenharmony_ci OpBranchConditional %61 %22 %20 2219fd4e5da5Sopenharmony_ci %22 = OpLabel 2220fd4e5da5Sopenharmony_ci %23 = OpLoad %14 %16 2221fd4e5da5Sopenharmony_ci %26 = OpSLessThan %25 %23 %24 2222fd4e5da5Sopenharmony_ci OpBranchConditional %26 %19 %20 2223fd4e5da5Sopenharmony_ci %19 = OpLabel 2224fd4e5da5Sopenharmony_ci %27 = OpLoad %14 %16 2225fd4e5da5Sopenharmony_ci %32 = OpAccessChain %31 %30 %17 2226fd4e5da5Sopenharmony_ci %33 = OpLoad %6 %32 2227fd4e5da5Sopenharmony_ci %34 = OpConvertFToS %14 %33 2228fd4e5da5Sopenharmony_ci %35 = OpSLessThan %25 %27 %34 2229fd4e5da5Sopenharmony_ci OpSelectionMerge %37 None 2230fd4e5da5Sopenharmony_ci OpBranchConditional %35 %36 %44 2231fd4e5da5Sopenharmony_ci %36 = OpLabel 2232fd4e5da5Sopenharmony_ci %41 = OpAccessChain %59 %9 %40 2233fd4e5da5Sopenharmony_ci %42 = OpLoad %6 %41 2234fd4e5da5Sopenharmony_ci OpStore %38 %42 2235fd4e5da5Sopenharmony_ci OpBranch %37 2236fd4e5da5Sopenharmony_ci %44 = OpLabel 2237fd4e5da5Sopenharmony_ci %46 = OpAccessChain %59 %9 %45 2238fd4e5da5Sopenharmony_ci OpBranch %37 2239fd4e5da5Sopenharmony_ci %37 = OpLabel 2240fd4e5da5Sopenharmony_ci %47 = OpLoad %6 %62 2241fd4e5da5Sopenharmony_ci OpStore %38 %47 2242fd4e5da5Sopenharmony_ci %48 = OpLoad %6 %38 2243fd4e5da5Sopenharmony_ci %49 = OpLoad %6 %13 2244fd4e5da5Sopenharmony_ci %50 = OpFAdd %6 %49 %48 2245fd4e5da5Sopenharmony_ci OpStore %13 %50 2246fd4e5da5Sopenharmony_ci OpBranch %20 2247fd4e5da5Sopenharmony_ci %21 = OpLabel 2248fd4e5da5Sopenharmony_ci %51 = OpLoad %14 %16 2249fd4e5da5Sopenharmony_ci %53 = OpIAdd %14 %51 %52 2250fd4e5da5Sopenharmony_ci OpStore %16 %53 2251fd4e5da5Sopenharmony_ci OpBranch %18 2252fd4e5da5Sopenharmony_ci %20 = OpLabel 2253fd4e5da5Sopenharmony_ci %57 = OpLoad %6 %13 2254fd4e5da5Sopenharmony_ci %58 = OpCompositeConstruct %54 %57 %57 %57 %57 2255fd4e5da5Sopenharmony_ci OpStore %56 %58 2256fd4e5da5Sopenharmony_ci OpReturn 2257fd4e5da5Sopenharmony_ci OpFunctionEnd 2258fd4e5da5Sopenharmony_ci )"; 2259fd4e5da5Sopenharmony_ci CheckEqual(env, expected, context.get()); 2260fd4e5da5Sopenharmony_ci} 2261fd4e5da5Sopenharmony_ci 2262fd4e5da5Sopenharmony_ciTEST(StructuredLoopToSelectionReductionPassTest, DominanceAndPhiIssue) { 2263fd4e5da5Sopenharmony_ci // Exposes an interesting scenario where a use in a phi stops being dominated 2264fd4e5da5Sopenharmony_ci // by the block with which it is associated in the phi. 2265fd4e5da5Sopenharmony_ci std::string shader = R"( 2266fd4e5da5Sopenharmony_ci OpCapability Shader 2267fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 2268fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 2269fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 2270fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 2271fd4e5da5Sopenharmony_ci OpSource ESSL 310 2272fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 2273fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 2274fd4e5da5Sopenharmony_ci %17 = OpTypeBool 2275fd4e5da5Sopenharmony_ci %18 = OpConstantTrue %17 2276fd4e5da5Sopenharmony_ci %19 = OpConstantFalse %17 2277fd4e5da5Sopenharmony_ci %20 = OpTypeInt 32 1 2278fd4e5da5Sopenharmony_ci %21 = OpConstant %20 5 2279fd4e5da5Sopenharmony_ci %22 = OpConstant %20 6 2280fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 2281fd4e5da5Sopenharmony_ci %5 = OpLabel 2282fd4e5da5Sopenharmony_ci OpBranch %6 2283fd4e5da5Sopenharmony_ci %6 = OpLabel 2284fd4e5da5Sopenharmony_ci OpLoopMerge %16 %15 None 2285fd4e5da5Sopenharmony_ci OpBranch %7 2286fd4e5da5Sopenharmony_ci %7 = OpLabel 2287fd4e5da5Sopenharmony_ci OpSelectionMerge %13 None 2288fd4e5da5Sopenharmony_ci OpBranchConditional %18 %8 %9 2289fd4e5da5Sopenharmony_ci %8 = OpLabel 2290fd4e5da5Sopenharmony_ci OpSelectionMerge %12 None 2291fd4e5da5Sopenharmony_ci OpBranchConditional %18 %10 %11 2292fd4e5da5Sopenharmony_ci %9 = OpLabel 2293fd4e5da5Sopenharmony_ci OpBranch %16 2294fd4e5da5Sopenharmony_ci %10 = OpLabel 2295fd4e5da5Sopenharmony_ci OpBranch %16 2296fd4e5da5Sopenharmony_ci %11 = OpLabel 2297fd4e5da5Sopenharmony_ci %23 = OpIAdd %20 %21 %22 2298fd4e5da5Sopenharmony_ci OpBranch %12 2299fd4e5da5Sopenharmony_ci %12 = OpLabel 2300fd4e5da5Sopenharmony_ci OpBranch %13 2301fd4e5da5Sopenharmony_ci %13 = OpLabel 2302fd4e5da5Sopenharmony_ci OpBranch %14 2303fd4e5da5Sopenharmony_ci %14 = OpLabel 2304fd4e5da5Sopenharmony_ci %24 = OpPhi %20 %23 %13 2305fd4e5da5Sopenharmony_ci OpBranchConditional %19 %15 %16 2306fd4e5da5Sopenharmony_ci %15 = OpLabel 2307fd4e5da5Sopenharmony_ci OpBranch %6 2308fd4e5da5Sopenharmony_ci %16 = OpLabel 2309fd4e5da5Sopenharmony_ci OpReturn 2310fd4e5da5Sopenharmony_ci OpFunctionEnd 2311fd4e5da5Sopenharmony_ci )"; 2312fd4e5da5Sopenharmony_ci 2313fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 2314fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption); 2315fd4e5da5Sopenharmony_ci const auto ops = StructuredLoopToSelectionReductionOpportunityFinder() 2316fd4e5da5Sopenharmony_ci .GetAvailableOpportunities(context.get(), 0); 2317fd4e5da5Sopenharmony_ci ASSERT_EQ(1, ops.size()); 2318fd4e5da5Sopenharmony_ci 2319fd4e5da5Sopenharmony_ci ASSERT_TRUE(ops[0]->PreconditionHolds()); 2320fd4e5da5Sopenharmony_ci ops[0]->TryToApply(); 2321fd4e5da5Sopenharmony_ci 2322fd4e5da5Sopenharmony_ci CheckValid(env, context.get()); 2323fd4e5da5Sopenharmony_ci 2324fd4e5da5Sopenharmony_ci std::string expected = R"( 2325fd4e5da5Sopenharmony_ci OpCapability Shader 2326fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 2327fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 2328fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 2329fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 2330fd4e5da5Sopenharmony_ci OpSource ESSL 310 2331fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 2332fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 2333fd4e5da5Sopenharmony_ci %17 = OpTypeBool 2334fd4e5da5Sopenharmony_ci %18 = OpConstantTrue %17 2335fd4e5da5Sopenharmony_ci %19 = OpConstantFalse %17 2336fd4e5da5Sopenharmony_ci %20 = OpTypeInt 32 1 2337fd4e5da5Sopenharmony_ci %21 = OpConstant %20 5 2338fd4e5da5Sopenharmony_ci %22 = OpConstant %20 6 2339fd4e5da5Sopenharmony_ci %25 = OpUndef %20 2340fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 2341fd4e5da5Sopenharmony_ci %5 = OpLabel 2342fd4e5da5Sopenharmony_ci OpBranch %6 2343fd4e5da5Sopenharmony_ci %6 = OpLabel 2344fd4e5da5Sopenharmony_ci OpSelectionMerge %16 None 2345fd4e5da5Sopenharmony_ci OpBranchConditional %18 %7 %16 2346fd4e5da5Sopenharmony_ci %7 = OpLabel 2347fd4e5da5Sopenharmony_ci OpSelectionMerge %13 None 2348fd4e5da5Sopenharmony_ci OpBranchConditional %18 %8 %9 2349fd4e5da5Sopenharmony_ci %8 = OpLabel 2350fd4e5da5Sopenharmony_ci OpSelectionMerge %12 None 2351fd4e5da5Sopenharmony_ci OpBranchConditional %18 %10 %11 2352fd4e5da5Sopenharmony_ci %9 = OpLabel 2353fd4e5da5Sopenharmony_ci OpBranch %13 2354fd4e5da5Sopenharmony_ci %10 = OpLabel 2355fd4e5da5Sopenharmony_ci OpBranch %12 2356fd4e5da5Sopenharmony_ci %11 = OpLabel 2357fd4e5da5Sopenharmony_ci %23 = OpIAdd %20 %21 %22 2358fd4e5da5Sopenharmony_ci OpBranch %12 2359fd4e5da5Sopenharmony_ci %12 = OpLabel 2360fd4e5da5Sopenharmony_ci OpBranch %13 2361fd4e5da5Sopenharmony_ci %13 = OpLabel 2362fd4e5da5Sopenharmony_ci OpBranch %14 2363fd4e5da5Sopenharmony_ci %14 = OpLabel 2364fd4e5da5Sopenharmony_ci %24 = OpPhi %20 %25 %13 2365fd4e5da5Sopenharmony_ci OpBranchConditional %19 %16 %16 2366fd4e5da5Sopenharmony_ci %15 = OpLabel 2367fd4e5da5Sopenharmony_ci OpBranch %6 2368fd4e5da5Sopenharmony_ci %16 = OpLabel 2369fd4e5da5Sopenharmony_ci OpReturn 2370fd4e5da5Sopenharmony_ci OpFunctionEnd 2371fd4e5da5Sopenharmony_ci )"; 2372fd4e5da5Sopenharmony_ci CheckEqual(env, expected, context.get()); 2373fd4e5da5Sopenharmony_ci} 2374fd4e5da5Sopenharmony_ci 2375fd4e5da5Sopenharmony_ciTEST(StructuredLoopToSelectionReductionPassTest, OpLineBeforeOpPhi) { 2376fd4e5da5Sopenharmony_ci // Test to ensure the pass knows OpLine and OpPhi instructions can be 2377fd4e5da5Sopenharmony_ci // interleaved. 2378fd4e5da5Sopenharmony_ci std::string shader = R"( 2379fd4e5da5Sopenharmony_ci OpCapability Shader 2380fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 2381fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 2382fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %2 "main" 2383fd4e5da5Sopenharmony_ci OpExecutionMode %2 OriginUpperLeft 2384fd4e5da5Sopenharmony_ci OpSource ESSL 310 2385fd4e5da5Sopenharmony_ci %3 = OpString "somefile" 2386fd4e5da5Sopenharmony_ci %4 = OpTypeVoid 2387fd4e5da5Sopenharmony_ci %5 = OpTypeFunction %4 2388fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 2389fd4e5da5Sopenharmony_ci %7 = OpConstant %6 10 2390fd4e5da5Sopenharmony_ci %8 = OpConstant %6 20 2391fd4e5da5Sopenharmony_ci %9 = OpConstant %6 30 2392fd4e5da5Sopenharmony_ci %10 = OpTypeBool 2393fd4e5da5Sopenharmony_ci %11 = OpConstantTrue %10 2394fd4e5da5Sopenharmony_ci %2 = OpFunction %4 None %5 2395fd4e5da5Sopenharmony_ci %12 = OpLabel 2396fd4e5da5Sopenharmony_ci OpBranch %13 2397fd4e5da5Sopenharmony_ci %13 = OpLabel 2398fd4e5da5Sopenharmony_ci OpLoopMerge %14 %15 None 2399fd4e5da5Sopenharmony_ci OpBranch %16 2400fd4e5da5Sopenharmony_ci %16 = OpLabel 2401fd4e5da5Sopenharmony_ci OpSelectionMerge %17 None 2402fd4e5da5Sopenharmony_ci OpBranchConditional %11 %18 %19 2403fd4e5da5Sopenharmony_ci %18 = OpLabel 2404fd4e5da5Sopenharmony_ci %20 = OpIAdd %6 %7 %8 2405fd4e5da5Sopenharmony_ci %21 = OpIAdd %6 %7 %9 2406fd4e5da5Sopenharmony_ci OpBranch %17 2407fd4e5da5Sopenharmony_ci %19 = OpLabel 2408fd4e5da5Sopenharmony_ci OpBranch %14 2409fd4e5da5Sopenharmony_ci %17 = OpLabel 2410fd4e5da5Sopenharmony_ci %22 = OpPhi %6 %20 %18 2411fd4e5da5Sopenharmony_ci OpLine %3 0 0 2412fd4e5da5Sopenharmony_ci %23 = OpPhi %6 %21 %18 2413fd4e5da5Sopenharmony_ci OpBranch %15 2414fd4e5da5Sopenharmony_ci %15 = OpLabel 2415fd4e5da5Sopenharmony_ci OpBranch %13 2416fd4e5da5Sopenharmony_ci %14 = OpLabel 2417fd4e5da5Sopenharmony_ci OpReturn 2418fd4e5da5Sopenharmony_ci OpFunctionEnd 2419fd4e5da5Sopenharmony_ci )"; 2420fd4e5da5Sopenharmony_ci 2421fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 2422fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption); 2423fd4e5da5Sopenharmony_ci const auto ops = StructuredLoopToSelectionReductionOpportunityFinder() 2424fd4e5da5Sopenharmony_ci .GetAvailableOpportunities(context.get(), 0); 2425fd4e5da5Sopenharmony_ci ASSERT_EQ(1, ops.size()); 2426fd4e5da5Sopenharmony_ci 2427fd4e5da5Sopenharmony_ci ASSERT_TRUE(ops[0]->PreconditionHolds()); 2428fd4e5da5Sopenharmony_ci ops[0]->TryToApply(); 2429fd4e5da5Sopenharmony_ci 2430fd4e5da5Sopenharmony_ci CheckValid(env, context.get()); 2431fd4e5da5Sopenharmony_ci 2432fd4e5da5Sopenharmony_ci std::string expected = R"( 2433fd4e5da5Sopenharmony_ci OpCapability Shader 2434fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 2435fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 2436fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %2 "main" 2437fd4e5da5Sopenharmony_ci OpExecutionMode %2 OriginUpperLeft 2438fd4e5da5Sopenharmony_ci OpSource ESSL 310 2439fd4e5da5Sopenharmony_ci %3 = OpString "somefile" 2440fd4e5da5Sopenharmony_ci %4 = OpTypeVoid 2441fd4e5da5Sopenharmony_ci %5 = OpTypeFunction %4 2442fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 2443fd4e5da5Sopenharmony_ci %7 = OpConstant %6 10 2444fd4e5da5Sopenharmony_ci %8 = OpConstant %6 20 2445fd4e5da5Sopenharmony_ci %9 = OpConstant %6 30 2446fd4e5da5Sopenharmony_ci %10 = OpTypeBool 2447fd4e5da5Sopenharmony_ci %11 = OpConstantTrue %10 2448fd4e5da5Sopenharmony_ci %24 = OpUndef %6 2449fd4e5da5Sopenharmony_ci %2 = OpFunction %4 None %5 2450fd4e5da5Sopenharmony_ci %12 = OpLabel 2451fd4e5da5Sopenharmony_ci OpBranch %13 2452fd4e5da5Sopenharmony_ci %13 = OpLabel 2453fd4e5da5Sopenharmony_ci OpSelectionMerge %14 None 2454fd4e5da5Sopenharmony_ci OpBranchConditional %11 %16 %14 2455fd4e5da5Sopenharmony_ci %16 = OpLabel 2456fd4e5da5Sopenharmony_ci OpSelectionMerge %17 None 2457fd4e5da5Sopenharmony_ci OpBranchConditional %11 %18 %19 2458fd4e5da5Sopenharmony_ci %18 = OpLabel 2459fd4e5da5Sopenharmony_ci %20 = OpIAdd %6 %7 %8 2460fd4e5da5Sopenharmony_ci %21 = OpIAdd %6 %7 %9 2461fd4e5da5Sopenharmony_ci OpBranch %17 2462fd4e5da5Sopenharmony_ci %19 = OpLabel 2463fd4e5da5Sopenharmony_ci OpBranch %17 2464fd4e5da5Sopenharmony_ci %17 = OpLabel 2465fd4e5da5Sopenharmony_ci %22 = OpPhi %6 %20 %18 %24 %19 2466fd4e5da5Sopenharmony_ci OpLine %3 0 0 2467fd4e5da5Sopenharmony_ci %23 = OpPhi %6 %21 %18 %24 %19 2468fd4e5da5Sopenharmony_ci OpBranch %14 2469fd4e5da5Sopenharmony_ci %15 = OpLabel 2470fd4e5da5Sopenharmony_ci OpBranch %13 2471fd4e5da5Sopenharmony_ci %14 = OpLabel 2472fd4e5da5Sopenharmony_ci OpReturn 2473fd4e5da5Sopenharmony_ci OpFunctionEnd 2474fd4e5da5Sopenharmony_ci )"; 2475fd4e5da5Sopenharmony_ci CheckEqual(env, expected, context.get()); 2476fd4e5da5Sopenharmony_ci} 2477fd4e5da5Sopenharmony_ci 2478fd4e5da5Sopenharmony_ciTEST(StructuredLoopToSelectionReductionPassTest, 2479fd4e5da5Sopenharmony_ci SelectionMergeIsContinueTarget) { 2480fd4e5da5Sopenharmony_ci // Example where a loop's continue target is also the target of a selection. 2481fd4e5da5Sopenharmony_ci // In this scenario we cautiously do not apply the transformation. 2482fd4e5da5Sopenharmony_ci std::string shader = R"( 2483fd4e5da5Sopenharmony_ci OpCapability Shader 2484fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 2485fd4e5da5Sopenharmony_ci OpEntryPoint Vertex %1 "main" 2486fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 2487fd4e5da5Sopenharmony_ci %3 = OpTypeBool 2488fd4e5da5Sopenharmony_ci %4 = OpTypeFunction %2 2489fd4e5da5Sopenharmony_ci %1 = OpFunction %2 None %4 2490fd4e5da5Sopenharmony_ci %5 = OpLabel 2491fd4e5da5Sopenharmony_ci %6 = OpUndef %3 2492fd4e5da5Sopenharmony_ci OpBranch %7 2493fd4e5da5Sopenharmony_ci %7 = OpLabel 2494fd4e5da5Sopenharmony_ci %8 = OpPhi %3 %6 %5 %9 %10 2495fd4e5da5Sopenharmony_ci OpLoopMerge %11 %10 None 2496fd4e5da5Sopenharmony_ci OpBranch %12 2497fd4e5da5Sopenharmony_ci %12 = OpLabel 2498fd4e5da5Sopenharmony_ci %13 = OpUndef %3 2499fd4e5da5Sopenharmony_ci OpSelectionMerge %10 None 2500fd4e5da5Sopenharmony_ci OpBranchConditional %13 %14 %10 2501fd4e5da5Sopenharmony_ci %14 = OpLabel 2502fd4e5da5Sopenharmony_ci OpBranch %10 2503fd4e5da5Sopenharmony_ci %10 = OpLabel 2504fd4e5da5Sopenharmony_ci %9 = OpUndef %3 2505fd4e5da5Sopenharmony_ci OpBranchConditional %9 %7 %11 2506fd4e5da5Sopenharmony_ci %11 = OpLabel 2507fd4e5da5Sopenharmony_ci OpReturn 2508fd4e5da5Sopenharmony_ci OpFunctionEnd 2509fd4e5da5Sopenharmony_ci )"; 2510fd4e5da5Sopenharmony_ci 2511fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 2512fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption); 2513fd4e5da5Sopenharmony_ci const auto ops = StructuredLoopToSelectionReductionOpportunityFinder() 2514fd4e5da5Sopenharmony_ci .GetAvailableOpportunities(context.get(), 0); 2515fd4e5da5Sopenharmony_ci 2516fd4e5da5Sopenharmony_ci // There should be no opportunities. 2517fd4e5da5Sopenharmony_ci ASSERT_EQ(0, ops.size()); 2518fd4e5da5Sopenharmony_ci} 2519fd4e5da5Sopenharmony_ci 2520fd4e5da5Sopenharmony_ciTEST(StructuredLoopToSelectionReductionPassTest, 2521fd4e5da5Sopenharmony_ci SwitchSelectionMergeIsContinueTarget) { 2522fd4e5da5Sopenharmony_ci // Another example where a loop's continue target is also the target of a 2523fd4e5da5Sopenharmony_ci // selection; this time a selection associated with an OpSwitch. We 2524fd4e5da5Sopenharmony_ci // cautiously do not apply the transformation. 2525fd4e5da5Sopenharmony_ci std::string shader = R"( 2526fd4e5da5Sopenharmony_ci OpCapability Shader 2527fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 2528fd4e5da5Sopenharmony_ci OpEntryPoint Vertex %1 "main" 2529fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 2530fd4e5da5Sopenharmony_ci %3 = OpTypeBool 2531fd4e5da5Sopenharmony_ci %5 = OpTypeInt 32 1 2532fd4e5da5Sopenharmony_ci %4 = OpTypeFunction %2 2533fd4e5da5Sopenharmony_ci %6 = OpConstant %5 2 2534fd4e5da5Sopenharmony_ci %7 = OpConstantTrue %3 2535fd4e5da5Sopenharmony_ci %1 = OpFunction %2 None %4 2536fd4e5da5Sopenharmony_ci %8 = OpLabel 2537fd4e5da5Sopenharmony_ci OpBranch %9 2538fd4e5da5Sopenharmony_ci %9 = OpLabel 2539fd4e5da5Sopenharmony_ci OpLoopMerge %14 %15 None 2540fd4e5da5Sopenharmony_ci OpBranchConditional %7 %10 %14 2541fd4e5da5Sopenharmony_ci %10 = OpLabel 2542fd4e5da5Sopenharmony_ci OpSelectionMerge %15 None 2543fd4e5da5Sopenharmony_ci OpSwitch %6 %12 1 %11 2 %11 3 %15 2544fd4e5da5Sopenharmony_ci %11 = OpLabel 2545fd4e5da5Sopenharmony_ci OpBranch %12 2546fd4e5da5Sopenharmony_ci %12 = OpLabel 2547fd4e5da5Sopenharmony_ci OpBranch %15 2548fd4e5da5Sopenharmony_ci %15 = OpLabel 2549fd4e5da5Sopenharmony_ci OpBranch %9 2550fd4e5da5Sopenharmony_ci %14 = OpLabel 2551fd4e5da5Sopenharmony_ci OpReturn 2552fd4e5da5Sopenharmony_ci OpFunctionEnd 2553fd4e5da5Sopenharmony_ci )"; 2554fd4e5da5Sopenharmony_ci 2555fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 2556fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption); 2557fd4e5da5Sopenharmony_ci const auto ops = StructuredLoopToSelectionReductionOpportunityFinder() 2558fd4e5da5Sopenharmony_ci .GetAvailableOpportunities(context.get(), 0); 2559fd4e5da5Sopenharmony_ci 2560fd4e5da5Sopenharmony_ci // There should be no opportunities. 2561fd4e5da5Sopenharmony_ci ASSERT_EQ(0, ops.size()); 2562fd4e5da5Sopenharmony_ci} 2563fd4e5da5Sopenharmony_ci 2564fd4e5da5Sopenharmony_ciTEST(StructuredLoopToSelectionReductionPassTest, ContinueTargetIsSwitchTarget) { 2565fd4e5da5Sopenharmony_ci std::string shader = R"( 2566fd4e5da5Sopenharmony_ci OpCapability Shader 2567fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 2568fd4e5da5Sopenharmony_ci OpEntryPoint Vertex %1 "main" 2569fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 2570fd4e5da5Sopenharmony_ci %3 = OpTypeBool 2571fd4e5da5Sopenharmony_ci %5 = OpTypeInt 32 1 2572fd4e5da5Sopenharmony_ci %4 = OpTypeFunction %2 2573fd4e5da5Sopenharmony_ci %6 = OpConstant %5 2 2574fd4e5da5Sopenharmony_ci %7 = OpConstantTrue %3 2575fd4e5da5Sopenharmony_ci %1 = OpFunction %2 None %4 2576fd4e5da5Sopenharmony_ci %8 = OpLabel 2577fd4e5da5Sopenharmony_ci OpBranch %9 2578fd4e5da5Sopenharmony_ci %9 = OpLabel 2579fd4e5da5Sopenharmony_ci OpLoopMerge %14 %12 None 2580fd4e5da5Sopenharmony_ci OpBranchConditional %7 %10 %14 2581fd4e5da5Sopenharmony_ci %10 = OpLabel 2582fd4e5da5Sopenharmony_ci OpSelectionMerge %15 None 2583fd4e5da5Sopenharmony_ci OpSwitch %6 %12 1 %11 2 %11 3 %15 2584fd4e5da5Sopenharmony_ci %11 = OpLabel 2585fd4e5da5Sopenharmony_ci OpBranch %12 2586fd4e5da5Sopenharmony_ci %12 = OpLabel 2587fd4e5da5Sopenharmony_ci OpBranch %9 2588fd4e5da5Sopenharmony_ci %15 = OpLabel 2589fd4e5da5Sopenharmony_ci OpBranch %14 2590fd4e5da5Sopenharmony_ci %14 = OpLabel 2591fd4e5da5Sopenharmony_ci OpReturn 2592fd4e5da5Sopenharmony_ci OpFunctionEnd 2593fd4e5da5Sopenharmony_ci )"; 2594fd4e5da5Sopenharmony_ci 2595fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 2596fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption); 2597fd4e5da5Sopenharmony_ci const auto ops = StructuredLoopToSelectionReductionOpportunityFinder() 2598fd4e5da5Sopenharmony_ci .GetAvailableOpportunities(context.get(), 0); 2599fd4e5da5Sopenharmony_ci 2600fd4e5da5Sopenharmony_ci ASSERT_EQ(1, ops.size()); 2601fd4e5da5Sopenharmony_ci ASSERT_TRUE(ops[0]->PreconditionHolds()); 2602fd4e5da5Sopenharmony_ci ops[0]->TryToApply(); 2603fd4e5da5Sopenharmony_ci 2604fd4e5da5Sopenharmony_ci CheckValid(env, context.get()); 2605fd4e5da5Sopenharmony_ci 2606fd4e5da5Sopenharmony_ci std::string expected = R"( 2607fd4e5da5Sopenharmony_ci OpCapability Shader 2608fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 2609fd4e5da5Sopenharmony_ci OpEntryPoint Vertex %1 "main" 2610fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 2611fd4e5da5Sopenharmony_ci %3 = OpTypeBool 2612fd4e5da5Sopenharmony_ci %5 = OpTypeInt 32 1 2613fd4e5da5Sopenharmony_ci %4 = OpTypeFunction %2 2614fd4e5da5Sopenharmony_ci %6 = OpConstant %5 2 2615fd4e5da5Sopenharmony_ci %7 = OpConstantTrue %3 2616fd4e5da5Sopenharmony_ci %1 = OpFunction %2 None %4 2617fd4e5da5Sopenharmony_ci %8 = OpLabel 2618fd4e5da5Sopenharmony_ci OpBranch %9 2619fd4e5da5Sopenharmony_ci %9 = OpLabel 2620fd4e5da5Sopenharmony_ci OpSelectionMerge %14 None 2621fd4e5da5Sopenharmony_ci OpBranchConditional %7 %10 %14 2622fd4e5da5Sopenharmony_ci %10 = OpLabel 2623fd4e5da5Sopenharmony_ci OpSelectionMerge %15 None 2624fd4e5da5Sopenharmony_ci OpSwitch %6 %15 1 %11 2 %11 3 %15 2625fd4e5da5Sopenharmony_ci %11 = OpLabel 2626fd4e5da5Sopenharmony_ci OpBranch %15 2627fd4e5da5Sopenharmony_ci %12 = OpLabel 2628fd4e5da5Sopenharmony_ci OpBranch %9 2629fd4e5da5Sopenharmony_ci %15 = OpLabel 2630fd4e5da5Sopenharmony_ci OpBranch %14 2631fd4e5da5Sopenharmony_ci %14 = OpLabel 2632fd4e5da5Sopenharmony_ci OpReturn 2633fd4e5da5Sopenharmony_ci OpFunctionEnd 2634fd4e5da5Sopenharmony_ci )"; 2635fd4e5da5Sopenharmony_ci CheckEqual(env, expected, context.get()); 2636fd4e5da5Sopenharmony_ci} 2637fd4e5da5Sopenharmony_ci 2638fd4e5da5Sopenharmony_ciTEST(StructuredLoopToSelectionReductionPassTest, 2639fd4e5da5Sopenharmony_ci MultipleSwitchTargetsAreContinueTarget) { 2640fd4e5da5Sopenharmony_ci std::string shader = R"( 2641fd4e5da5Sopenharmony_ci OpCapability Shader 2642fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 2643fd4e5da5Sopenharmony_ci OpEntryPoint Vertex %1 "main" 2644fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 2645fd4e5da5Sopenharmony_ci %3 = OpTypeBool 2646fd4e5da5Sopenharmony_ci %5 = OpTypeInt 32 1 2647fd4e5da5Sopenharmony_ci %4 = OpTypeFunction %2 2648fd4e5da5Sopenharmony_ci %6 = OpConstant %5 2 2649fd4e5da5Sopenharmony_ci %7 = OpConstantTrue %3 2650fd4e5da5Sopenharmony_ci %1 = OpFunction %2 None %4 2651fd4e5da5Sopenharmony_ci %8 = OpLabel 2652fd4e5da5Sopenharmony_ci OpBranch %9 2653fd4e5da5Sopenharmony_ci %9 = OpLabel 2654fd4e5da5Sopenharmony_ci OpLoopMerge %14 %12 None 2655fd4e5da5Sopenharmony_ci OpBranchConditional %7 %10 %14 2656fd4e5da5Sopenharmony_ci %10 = OpLabel 2657fd4e5da5Sopenharmony_ci OpSelectionMerge %15 None 2658fd4e5da5Sopenharmony_ci OpSwitch %6 %11 1 %12 2 %12 3 %15 2659fd4e5da5Sopenharmony_ci %11 = OpLabel 2660fd4e5da5Sopenharmony_ci OpBranch %12 2661fd4e5da5Sopenharmony_ci %12 = OpLabel 2662fd4e5da5Sopenharmony_ci OpBranch %9 2663fd4e5da5Sopenharmony_ci %15 = OpLabel 2664fd4e5da5Sopenharmony_ci OpBranch %14 2665fd4e5da5Sopenharmony_ci %14 = OpLabel 2666fd4e5da5Sopenharmony_ci OpReturn 2667fd4e5da5Sopenharmony_ci OpFunctionEnd 2668fd4e5da5Sopenharmony_ci )"; 2669fd4e5da5Sopenharmony_ci 2670fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 2671fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption); 2672fd4e5da5Sopenharmony_ci const auto ops = StructuredLoopToSelectionReductionOpportunityFinder() 2673fd4e5da5Sopenharmony_ci .GetAvailableOpportunities(context.get(), 0); 2674fd4e5da5Sopenharmony_ci 2675fd4e5da5Sopenharmony_ci ASSERT_EQ(1, ops.size()); 2676fd4e5da5Sopenharmony_ci ASSERT_TRUE(ops[0]->PreconditionHolds()); 2677fd4e5da5Sopenharmony_ci ops[0]->TryToApply(); 2678fd4e5da5Sopenharmony_ci 2679fd4e5da5Sopenharmony_ci CheckValid(env, context.get()); 2680fd4e5da5Sopenharmony_ci 2681fd4e5da5Sopenharmony_ci std::string expected = R"( 2682fd4e5da5Sopenharmony_ci OpCapability Shader 2683fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 2684fd4e5da5Sopenharmony_ci OpEntryPoint Vertex %1 "main" 2685fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 2686fd4e5da5Sopenharmony_ci %3 = OpTypeBool 2687fd4e5da5Sopenharmony_ci %5 = OpTypeInt 32 1 2688fd4e5da5Sopenharmony_ci %4 = OpTypeFunction %2 2689fd4e5da5Sopenharmony_ci %6 = OpConstant %5 2 2690fd4e5da5Sopenharmony_ci %7 = OpConstantTrue %3 2691fd4e5da5Sopenharmony_ci %1 = OpFunction %2 None %4 2692fd4e5da5Sopenharmony_ci %8 = OpLabel 2693fd4e5da5Sopenharmony_ci OpBranch %9 2694fd4e5da5Sopenharmony_ci %9 = OpLabel 2695fd4e5da5Sopenharmony_ci OpSelectionMerge %14 None 2696fd4e5da5Sopenharmony_ci OpBranchConditional %7 %10 %14 2697fd4e5da5Sopenharmony_ci %10 = OpLabel 2698fd4e5da5Sopenharmony_ci OpSelectionMerge %15 None 2699fd4e5da5Sopenharmony_ci OpSwitch %6 %11 1 %15 2 %15 3 %15 2700fd4e5da5Sopenharmony_ci %11 = OpLabel 2701fd4e5da5Sopenharmony_ci OpBranch %15 2702fd4e5da5Sopenharmony_ci %12 = OpLabel 2703fd4e5da5Sopenharmony_ci OpBranch %9 2704fd4e5da5Sopenharmony_ci %15 = OpLabel 2705fd4e5da5Sopenharmony_ci OpBranch %14 2706fd4e5da5Sopenharmony_ci %14 = OpLabel 2707fd4e5da5Sopenharmony_ci OpReturn 2708fd4e5da5Sopenharmony_ci OpFunctionEnd 2709fd4e5da5Sopenharmony_ci )"; 2710fd4e5da5Sopenharmony_ci CheckEqual(env, expected, context.get()); 2711fd4e5da5Sopenharmony_ci} 2712fd4e5da5Sopenharmony_ci 2713fd4e5da5Sopenharmony_ciTEST(StructuredLoopToSelectionReductionPassTest, LoopBranchesStraightToMerge) { 2714fd4e5da5Sopenharmony_ci std::string shader = R"( 2715fd4e5da5Sopenharmony_ci OpCapability Shader 2716fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 2717fd4e5da5Sopenharmony_ci OpEntryPoint Vertex %1 "main" 2718fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 2719fd4e5da5Sopenharmony_ci %4 = OpTypeFunction %2 2720fd4e5da5Sopenharmony_ci %1 = OpFunction %2 None %4 2721fd4e5da5Sopenharmony_ci %8 = OpLabel 2722fd4e5da5Sopenharmony_ci OpBranch %9 2723fd4e5da5Sopenharmony_ci %9 = OpLabel 2724fd4e5da5Sopenharmony_ci OpLoopMerge %14 %12 None 2725fd4e5da5Sopenharmony_ci OpBranch %14 2726fd4e5da5Sopenharmony_ci %12 = OpLabel 2727fd4e5da5Sopenharmony_ci OpBranch %9 2728fd4e5da5Sopenharmony_ci %14 = OpLabel 2729fd4e5da5Sopenharmony_ci OpReturn 2730fd4e5da5Sopenharmony_ci OpFunctionEnd 2731fd4e5da5Sopenharmony_ci )"; 2732fd4e5da5Sopenharmony_ci 2733fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 2734fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption); 2735fd4e5da5Sopenharmony_ci const auto ops = StructuredLoopToSelectionReductionOpportunityFinder() 2736fd4e5da5Sopenharmony_ci .GetAvailableOpportunities(context.get(), 0); 2737fd4e5da5Sopenharmony_ci 2738fd4e5da5Sopenharmony_ci ASSERT_EQ(1, ops.size()); 2739fd4e5da5Sopenharmony_ci ASSERT_TRUE(ops[0]->PreconditionHolds()); 2740fd4e5da5Sopenharmony_ci ops[0]->TryToApply(); 2741fd4e5da5Sopenharmony_ci 2742fd4e5da5Sopenharmony_ci CheckValid(env, context.get()); 2743fd4e5da5Sopenharmony_ci 2744fd4e5da5Sopenharmony_ci std::string expected = R"( 2745fd4e5da5Sopenharmony_ci OpCapability Shader 2746fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 2747fd4e5da5Sopenharmony_ci OpEntryPoint Vertex %1 "main" 2748fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 2749fd4e5da5Sopenharmony_ci %4 = OpTypeFunction %2 2750fd4e5da5Sopenharmony_ci %15 = OpTypeBool 2751fd4e5da5Sopenharmony_ci %16 = OpConstantTrue %15 2752fd4e5da5Sopenharmony_ci %1 = OpFunction %2 None %4 2753fd4e5da5Sopenharmony_ci %8 = OpLabel 2754fd4e5da5Sopenharmony_ci OpBranch %9 2755fd4e5da5Sopenharmony_ci %9 = OpLabel 2756fd4e5da5Sopenharmony_ci OpSelectionMerge %14 None 2757fd4e5da5Sopenharmony_ci OpBranchConditional %16 %14 %14 2758fd4e5da5Sopenharmony_ci %12 = OpLabel 2759fd4e5da5Sopenharmony_ci OpBranch %9 2760fd4e5da5Sopenharmony_ci %14 = OpLabel 2761fd4e5da5Sopenharmony_ci OpReturn 2762fd4e5da5Sopenharmony_ci OpFunctionEnd 2763fd4e5da5Sopenharmony_ci )"; 2764fd4e5da5Sopenharmony_ci CheckEqual(env, expected, context.get()); 2765fd4e5da5Sopenharmony_ci} 2766fd4e5da5Sopenharmony_ci 2767fd4e5da5Sopenharmony_ciTEST(StructuredLoopToSelectionReductionPassTest, 2768fd4e5da5Sopenharmony_ci LoopConditionallyJumpsToMergeOrContinue) { 2769fd4e5da5Sopenharmony_ci std::string shader = R"( 2770fd4e5da5Sopenharmony_ci OpCapability Shader 2771fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 2772fd4e5da5Sopenharmony_ci OpEntryPoint Vertex %1 "main" 2773fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 2774fd4e5da5Sopenharmony_ci %3 = OpTypeBool 2775fd4e5da5Sopenharmony_ci %4 = OpTypeFunction %2 2776fd4e5da5Sopenharmony_ci %7 = OpConstantTrue %3 2777fd4e5da5Sopenharmony_ci %1 = OpFunction %2 None %4 2778fd4e5da5Sopenharmony_ci %8 = OpLabel 2779fd4e5da5Sopenharmony_ci OpBranch %9 2780fd4e5da5Sopenharmony_ci %9 = OpLabel 2781fd4e5da5Sopenharmony_ci OpLoopMerge %14 %12 None 2782fd4e5da5Sopenharmony_ci OpBranchConditional %7 %14 %12 2783fd4e5da5Sopenharmony_ci %12 = OpLabel 2784fd4e5da5Sopenharmony_ci OpBranch %9 2785fd4e5da5Sopenharmony_ci %14 = OpLabel 2786fd4e5da5Sopenharmony_ci OpReturn 2787fd4e5da5Sopenharmony_ci OpFunctionEnd 2788fd4e5da5Sopenharmony_ci )"; 2789fd4e5da5Sopenharmony_ci 2790fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 2791fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption); 2792fd4e5da5Sopenharmony_ci const auto ops = StructuredLoopToSelectionReductionOpportunityFinder() 2793fd4e5da5Sopenharmony_ci .GetAvailableOpportunities(context.get(), 0); 2794fd4e5da5Sopenharmony_ci 2795fd4e5da5Sopenharmony_ci ASSERT_EQ(1, ops.size()); 2796fd4e5da5Sopenharmony_ci ASSERT_TRUE(ops[0]->PreconditionHolds()); 2797fd4e5da5Sopenharmony_ci ops[0]->TryToApply(); 2798fd4e5da5Sopenharmony_ci 2799fd4e5da5Sopenharmony_ci CheckValid(env, context.get()); 2800fd4e5da5Sopenharmony_ci 2801fd4e5da5Sopenharmony_ci std::string expected = R"( 2802fd4e5da5Sopenharmony_ci OpCapability Shader 2803fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 2804fd4e5da5Sopenharmony_ci OpEntryPoint Vertex %1 "main" 2805fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 2806fd4e5da5Sopenharmony_ci %3 = OpTypeBool 2807fd4e5da5Sopenharmony_ci %4 = OpTypeFunction %2 2808fd4e5da5Sopenharmony_ci %7 = OpConstantTrue %3 2809fd4e5da5Sopenharmony_ci %1 = OpFunction %2 None %4 2810fd4e5da5Sopenharmony_ci %8 = OpLabel 2811fd4e5da5Sopenharmony_ci OpBranch %9 2812fd4e5da5Sopenharmony_ci %9 = OpLabel 2813fd4e5da5Sopenharmony_ci OpSelectionMerge %14 None 2814fd4e5da5Sopenharmony_ci OpBranchConditional %7 %14 %14 2815fd4e5da5Sopenharmony_ci %12 = OpLabel 2816fd4e5da5Sopenharmony_ci OpBranch %9 2817fd4e5da5Sopenharmony_ci %14 = OpLabel 2818fd4e5da5Sopenharmony_ci OpReturn 2819fd4e5da5Sopenharmony_ci OpFunctionEnd 2820fd4e5da5Sopenharmony_ci )"; 2821fd4e5da5Sopenharmony_ci CheckEqual(env, expected, context.get()); 2822fd4e5da5Sopenharmony_ci} 2823fd4e5da5Sopenharmony_ci 2824fd4e5da5Sopenharmony_ciTEST(StructuredLoopToSelectionReductionPassTest, MultipleAccessChains) { 2825fd4e5da5Sopenharmony_ci std::string shader = R"( 2826fd4e5da5Sopenharmony_ci OpCapability Shader 2827fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 2828fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 2829fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 2830fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 2831fd4e5da5Sopenharmony_ci OpSource ESSL 310 2832fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 2833fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 2834fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 2835fd4e5da5Sopenharmony_ci %7 = OpTypeStruct %6 2836fd4e5da5Sopenharmony_ci %8 = OpTypeStruct %7 2837fd4e5da5Sopenharmony_ci %9 = OpTypePointer Function %8 2838fd4e5da5Sopenharmony_ci %11 = OpConstant %6 3 2839fd4e5da5Sopenharmony_ci %12 = OpConstantComposite %7 %11 2840fd4e5da5Sopenharmony_ci %13 = OpConstantComposite %8 %12 2841fd4e5da5Sopenharmony_ci %14 = OpTypePointer Function %7 2842fd4e5da5Sopenharmony_ci %16 = OpConstant %6 0 2843fd4e5da5Sopenharmony_ci %19 = OpTypePointer Function %6 2844fd4e5da5Sopenharmony_ci %15 = OpTypeBool 2845fd4e5da5Sopenharmony_ci %18 = OpConstantTrue %15 2846fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 2847fd4e5da5Sopenharmony_ci %5 = OpLabel 2848fd4e5da5Sopenharmony_ci %10 = OpVariable %9 Function 2849fd4e5da5Sopenharmony_ci %20 = OpVariable %19 Function 2850fd4e5da5Sopenharmony_ci OpStore %10 %13 2851fd4e5da5Sopenharmony_ci OpBranch %23 2852fd4e5da5Sopenharmony_ci %23 = OpLabel 2853fd4e5da5Sopenharmony_ci OpLoopMerge %25 %26 None 2854fd4e5da5Sopenharmony_ci OpBranch %27 2855fd4e5da5Sopenharmony_ci %27 = OpLabel 2856fd4e5da5Sopenharmony_ci OpSelectionMerge %28 None 2857fd4e5da5Sopenharmony_ci OpBranchConditional %18 %29 %25 2858fd4e5da5Sopenharmony_ci %29 = OpLabel 2859fd4e5da5Sopenharmony_ci %17 = OpAccessChain %14 %10 %16 2860fd4e5da5Sopenharmony_ci OpBranch %28 2861fd4e5da5Sopenharmony_ci %28 = OpLabel 2862fd4e5da5Sopenharmony_ci %21 = OpAccessChain %19 %17 %16 2863fd4e5da5Sopenharmony_ci %22 = OpLoad %6 %21 2864fd4e5da5Sopenharmony_ci %24 = OpAccessChain %19 %10 %16 %16 2865fd4e5da5Sopenharmony_ci OpStore %24 %22 2866fd4e5da5Sopenharmony_ci OpBranch %25 2867fd4e5da5Sopenharmony_ci %26 = OpLabel 2868fd4e5da5Sopenharmony_ci OpBranch %23 2869fd4e5da5Sopenharmony_ci %25 = OpLabel 2870fd4e5da5Sopenharmony_ci OpReturn 2871fd4e5da5Sopenharmony_ci OpFunctionEnd 2872fd4e5da5Sopenharmony_ci )"; 2873fd4e5da5Sopenharmony_ci 2874fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 2875fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption); 2876fd4e5da5Sopenharmony_ci const auto ops = StructuredLoopToSelectionReductionOpportunityFinder() 2877fd4e5da5Sopenharmony_ci .GetAvailableOpportunities(context.get(), 0); 2878fd4e5da5Sopenharmony_ci 2879fd4e5da5Sopenharmony_ci ASSERT_EQ(1, ops.size()); 2880fd4e5da5Sopenharmony_ci ASSERT_TRUE(ops[0]->PreconditionHolds()); 2881fd4e5da5Sopenharmony_ci ops[0]->TryToApply(); 2882fd4e5da5Sopenharmony_ci 2883fd4e5da5Sopenharmony_ci CheckValid(env, context.get()); 2884fd4e5da5Sopenharmony_ci 2885fd4e5da5Sopenharmony_ci std::string expected = R"( 2886fd4e5da5Sopenharmony_ci OpCapability Shader 2887fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 2888fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 2889fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 2890fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 2891fd4e5da5Sopenharmony_ci OpSource ESSL 310 2892fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 2893fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 2894fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 2895fd4e5da5Sopenharmony_ci %7 = OpTypeStruct %6 2896fd4e5da5Sopenharmony_ci %8 = OpTypeStruct %7 2897fd4e5da5Sopenharmony_ci %9 = OpTypePointer Function %8 2898fd4e5da5Sopenharmony_ci %11 = OpConstant %6 3 2899fd4e5da5Sopenharmony_ci %12 = OpConstantComposite %7 %11 2900fd4e5da5Sopenharmony_ci %13 = OpConstantComposite %8 %12 2901fd4e5da5Sopenharmony_ci %14 = OpTypePointer Function %7 2902fd4e5da5Sopenharmony_ci %16 = OpConstant %6 0 2903fd4e5da5Sopenharmony_ci %19 = OpTypePointer Function %6 2904fd4e5da5Sopenharmony_ci %15 = OpTypeBool 2905fd4e5da5Sopenharmony_ci %18 = OpConstantTrue %15 2906fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 2907fd4e5da5Sopenharmony_ci %5 = OpLabel 2908fd4e5da5Sopenharmony_ci %10 = OpVariable %9 Function 2909fd4e5da5Sopenharmony_ci %20 = OpVariable %19 Function 2910fd4e5da5Sopenharmony_ci %30 = OpVariable %14 Function 2911fd4e5da5Sopenharmony_ci OpStore %10 %13 2912fd4e5da5Sopenharmony_ci OpBranch %23 2913fd4e5da5Sopenharmony_ci %23 = OpLabel 2914fd4e5da5Sopenharmony_ci OpSelectionMerge %25 None 2915fd4e5da5Sopenharmony_ci OpBranchConditional %18 %27 %25 2916fd4e5da5Sopenharmony_ci %27 = OpLabel 2917fd4e5da5Sopenharmony_ci OpSelectionMerge %28 None 2918fd4e5da5Sopenharmony_ci OpBranchConditional %18 %29 %28 2919fd4e5da5Sopenharmony_ci %29 = OpLabel 2920fd4e5da5Sopenharmony_ci %17 = OpAccessChain %14 %10 %16 2921fd4e5da5Sopenharmony_ci OpBranch %28 2922fd4e5da5Sopenharmony_ci %28 = OpLabel 2923fd4e5da5Sopenharmony_ci %21 = OpAccessChain %19 %30 %16 2924fd4e5da5Sopenharmony_ci %22 = OpLoad %6 %21 2925fd4e5da5Sopenharmony_ci %24 = OpAccessChain %19 %10 %16 %16 2926fd4e5da5Sopenharmony_ci OpStore %24 %22 2927fd4e5da5Sopenharmony_ci OpBranch %25 2928fd4e5da5Sopenharmony_ci %26 = OpLabel 2929fd4e5da5Sopenharmony_ci OpBranch %23 2930fd4e5da5Sopenharmony_ci %25 = OpLabel 2931fd4e5da5Sopenharmony_ci OpReturn 2932fd4e5da5Sopenharmony_ci OpFunctionEnd 2933fd4e5da5Sopenharmony_ci )"; 2934fd4e5da5Sopenharmony_ci CheckEqual(env, expected, context.get()); 2935fd4e5da5Sopenharmony_ci} 2936fd4e5da5Sopenharmony_ci 2937fd4e5da5Sopenharmony_ciTEST(StructuredLoopToSelectionReductionPassTest, 2938fd4e5da5Sopenharmony_ci UnreachableInnerLoopContinueBranchingToOuterLoopMerge) { 2939fd4e5da5Sopenharmony_ci std::string shader = R"( 2940fd4e5da5Sopenharmony_ci OpCapability Shader 2941fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 2942fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 2943fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %2 "main" 2944fd4e5da5Sopenharmony_ci OpExecutionMode %2 OriginUpperLeft 2945fd4e5da5Sopenharmony_ci OpSource ESSL 310 2946fd4e5da5Sopenharmony_ci %3 = OpTypeVoid 2947fd4e5da5Sopenharmony_ci %4 = OpTypeFunction %3 2948fd4e5da5Sopenharmony_ci %5 = OpTypeBool 2949fd4e5da5Sopenharmony_ci %6 = OpConstantTrue %5 2950fd4e5da5Sopenharmony_ci %2 = OpFunction %3 None %4 2951fd4e5da5Sopenharmony_ci %7 = OpLabel 2952fd4e5da5Sopenharmony_ci OpBranch %8 2953fd4e5da5Sopenharmony_ci %8 = OpLabel 2954fd4e5da5Sopenharmony_ci OpLoopMerge %9 %10 None 2955fd4e5da5Sopenharmony_ci OpBranch %11 2956fd4e5da5Sopenharmony_ci %11 = OpLabel 2957fd4e5da5Sopenharmony_ci OpLoopMerge %12 %13 None 2958fd4e5da5Sopenharmony_ci OpBranch %12 2959fd4e5da5Sopenharmony_ci %13 = OpLabel 2960fd4e5da5Sopenharmony_ci OpBranch %11 2961fd4e5da5Sopenharmony_ci %12 = OpLabel 2962fd4e5da5Sopenharmony_ci OpBranch %10 2963fd4e5da5Sopenharmony_ci %10 = OpLabel 2964fd4e5da5Sopenharmony_ci OpBranchConditional %6 %9 %8 2965fd4e5da5Sopenharmony_ci %9 = OpLabel 2966fd4e5da5Sopenharmony_ci OpReturn 2967fd4e5da5Sopenharmony_ci OpFunctionEnd 2968fd4e5da5Sopenharmony_ci )"; 2969fd4e5da5Sopenharmony_ci 2970fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 2971fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption); 2972fd4e5da5Sopenharmony_ci const auto ops = StructuredLoopToSelectionReductionOpportunityFinder() 2973fd4e5da5Sopenharmony_ci .GetAvailableOpportunities(context.get(), 0); 2974fd4e5da5Sopenharmony_ci 2975fd4e5da5Sopenharmony_ci ASSERT_EQ(2, ops.size()); 2976fd4e5da5Sopenharmony_ci ASSERT_TRUE(ops[0]->PreconditionHolds()); 2977fd4e5da5Sopenharmony_ci ops[0]->TryToApply(); 2978fd4e5da5Sopenharmony_ci 2979fd4e5da5Sopenharmony_ci CheckValid(env, context.get()); 2980fd4e5da5Sopenharmony_ci 2981fd4e5da5Sopenharmony_ci std::string after_op_0 = R"( 2982fd4e5da5Sopenharmony_ci OpCapability Shader 2983fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 2984fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 2985fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %2 "main" 2986fd4e5da5Sopenharmony_ci OpExecutionMode %2 OriginUpperLeft 2987fd4e5da5Sopenharmony_ci OpSource ESSL 310 2988fd4e5da5Sopenharmony_ci %3 = OpTypeVoid 2989fd4e5da5Sopenharmony_ci %4 = OpTypeFunction %3 2990fd4e5da5Sopenharmony_ci %5 = OpTypeBool 2991fd4e5da5Sopenharmony_ci %6 = OpConstantTrue %5 2992fd4e5da5Sopenharmony_ci %2 = OpFunction %3 None %4 2993fd4e5da5Sopenharmony_ci %7 = OpLabel 2994fd4e5da5Sopenharmony_ci OpBranch %8 2995fd4e5da5Sopenharmony_ci %8 = OpLabel 2996fd4e5da5Sopenharmony_ci OpSelectionMerge %9 None 2997fd4e5da5Sopenharmony_ci OpBranchConditional %6 %11 %9 2998fd4e5da5Sopenharmony_ci %11 = OpLabel 2999fd4e5da5Sopenharmony_ci OpLoopMerge %12 %13 None 3000fd4e5da5Sopenharmony_ci OpBranch %12 3001fd4e5da5Sopenharmony_ci %13 = OpLabel 3002fd4e5da5Sopenharmony_ci OpBranch %11 3003fd4e5da5Sopenharmony_ci %12 = OpLabel 3004fd4e5da5Sopenharmony_ci OpBranch %9 3005fd4e5da5Sopenharmony_ci %10 = OpLabel 3006fd4e5da5Sopenharmony_ci OpBranchConditional %6 %9 %8 3007fd4e5da5Sopenharmony_ci %9 = OpLabel 3008fd4e5da5Sopenharmony_ci OpReturn 3009fd4e5da5Sopenharmony_ci OpFunctionEnd 3010fd4e5da5Sopenharmony_ci )"; 3011fd4e5da5Sopenharmony_ci CheckEqual(env, after_op_0, context.get()); 3012fd4e5da5Sopenharmony_ci 3013fd4e5da5Sopenharmony_ci ASSERT_TRUE(ops[1]->PreconditionHolds()); 3014fd4e5da5Sopenharmony_ci ops[1]->TryToApply(); 3015fd4e5da5Sopenharmony_ci 3016fd4e5da5Sopenharmony_ci CheckValid(env, context.get()); 3017fd4e5da5Sopenharmony_ci 3018fd4e5da5Sopenharmony_ci std::string after_op_1 = R"( 3019fd4e5da5Sopenharmony_ci OpCapability Shader 3020fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 3021fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 3022fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %2 "main" 3023fd4e5da5Sopenharmony_ci OpExecutionMode %2 OriginUpperLeft 3024fd4e5da5Sopenharmony_ci OpSource ESSL 310 3025fd4e5da5Sopenharmony_ci %3 = OpTypeVoid 3026fd4e5da5Sopenharmony_ci %4 = OpTypeFunction %3 3027fd4e5da5Sopenharmony_ci %5 = OpTypeBool 3028fd4e5da5Sopenharmony_ci %6 = OpConstantTrue %5 3029fd4e5da5Sopenharmony_ci %2 = OpFunction %3 None %4 3030fd4e5da5Sopenharmony_ci %7 = OpLabel 3031fd4e5da5Sopenharmony_ci OpBranch %8 3032fd4e5da5Sopenharmony_ci %8 = OpLabel 3033fd4e5da5Sopenharmony_ci OpSelectionMerge %9 None 3034fd4e5da5Sopenharmony_ci OpBranchConditional %6 %11 %9 3035fd4e5da5Sopenharmony_ci %11 = OpLabel 3036fd4e5da5Sopenharmony_ci OpSelectionMerge %12 None 3037fd4e5da5Sopenharmony_ci OpBranchConditional %6 %12 %12 3038fd4e5da5Sopenharmony_ci %13 = OpLabel 3039fd4e5da5Sopenharmony_ci OpBranch %11 3040fd4e5da5Sopenharmony_ci %12 = OpLabel 3041fd4e5da5Sopenharmony_ci OpBranch %9 3042fd4e5da5Sopenharmony_ci %10 = OpLabel 3043fd4e5da5Sopenharmony_ci OpBranchConditional %6 %9 %8 3044fd4e5da5Sopenharmony_ci %9 = OpLabel 3045fd4e5da5Sopenharmony_ci OpReturn 3046fd4e5da5Sopenharmony_ci OpFunctionEnd 3047fd4e5da5Sopenharmony_ci )"; 3048fd4e5da5Sopenharmony_ci CheckEqual(env, after_op_1, context.get()); 3049fd4e5da5Sopenharmony_ci} 3050fd4e5da5Sopenharmony_ci 3051fd4e5da5Sopenharmony_ciTEST(StructuredLoopToSelectionReductionPassTest, 3052fd4e5da5Sopenharmony_ci UnreachableInnerLoopContinueBranchingToOuterLoopMerge2) { 3053fd4e5da5Sopenharmony_ci // In this test, the unreachable continue is composed of multiple blocks. 3054fd4e5da5Sopenharmony_ci std::string shader = R"( 3055fd4e5da5Sopenharmony_ci OpCapability Shader 3056fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 3057fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 3058fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %2 "main" 3059fd4e5da5Sopenharmony_ci OpExecutionMode %2 OriginUpperLeft 3060fd4e5da5Sopenharmony_ci OpSource ESSL 310 3061fd4e5da5Sopenharmony_ci %3 = OpTypeVoid 3062fd4e5da5Sopenharmony_ci %4 = OpTypeFunction %3 3063fd4e5da5Sopenharmony_ci %5 = OpTypeBool 3064fd4e5da5Sopenharmony_ci %6 = OpConstantTrue %5 3065fd4e5da5Sopenharmony_ci %2 = OpFunction %3 None %4 3066fd4e5da5Sopenharmony_ci %7 = OpLabel 3067fd4e5da5Sopenharmony_ci OpBranch %8 3068fd4e5da5Sopenharmony_ci %8 = OpLabel 3069fd4e5da5Sopenharmony_ci OpLoopMerge %9 %10 None 3070fd4e5da5Sopenharmony_ci OpBranch %11 3071fd4e5da5Sopenharmony_ci %11 = OpLabel 3072fd4e5da5Sopenharmony_ci OpLoopMerge %12 %13 None 3073fd4e5da5Sopenharmony_ci OpBranch %12 3074fd4e5da5Sopenharmony_ci %13 = OpLabel 3075fd4e5da5Sopenharmony_ci OpBranch %14 3076fd4e5da5Sopenharmony_ci %14 = OpLabel 3077fd4e5da5Sopenharmony_ci OpBranch %11 3078fd4e5da5Sopenharmony_ci %12 = OpLabel 3079fd4e5da5Sopenharmony_ci OpBranch %10 3080fd4e5da5Sopenharmony_ci %10 = OpLabel 3081fd4e5da5Sopenharmony_ci OpBranchConditional %6 %9 %8 3082fd4e5da5Sopenharmony_ci %9 = OpLabel 3083fd4e5da5Sopenharmony_ci OpReturn 3084fd4e5da5Sopenharmony_ci OpFunctionEnd 3085fd4e5da5Sopenharmony_ci )"; 3086fd4e5da5Sopenharmony_ci 3087fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 3088fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption); 3089fd4e5da5Sopenharmony_ci const auto ops = StructuredLoopToSelectionReductionOpportunityFinder() 3090fd4e5da5Sopenharmony_ci .GetAvailableOpportunities(context.get(), 0); 3091fd4e5da5Sopenharmony_ci 3092fd4e5da5Sopenharmony_ci ASSERT_EQ(2, ops.size()); 3093fd4e5da5Sopenharmony_ci ASSERT_TRUE(ops[0]->PreconditionHolds()); 3094fd4e5da5Sopenharmony_ci ops[0]->TryToApply(); 3095fd4e5da5Sopenharmony_ci 3096fd4e5da5Sopenharmony_ci CheckValid(env, context.get()); 3097fd4e5da5Sopenharmony_ci 3098fd4e5da5Sopenharmony_ci std::string after_op_0 = R"( 3099fd4e5da5Sopenharmony_ci OpCapability Shader 3100fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 3101fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 3102fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %2 "main" 3103fd4e5da5Sopenharmony_ci OpExecutionMode %2 OriginUpperLeft 3104fd4e5da5Sopenharmony_ci OpSource ESSL 310 3105fd4e5da5Sopenharmony_ci %3 = OpTypeVoid 3106fd4e5da5Sopenharmony_ci %4 = OpTypeFunction %3 3107fd4e5da5Sopenharmony_ci %5 = OpTypeBool 3108fd4e5da5Sopenharmony_ci %6 = OpConstantTrue %5 3109fd4e5da5Sopenharmony_ci %2 = OpFunction %3 None %4 3110fd4e5da5Sopenharmony_ci %7 = OpLabel 3111fd4e5da5Sopenharmony_ci OpBranch %8 3112fd4e5da5Sopenharmony_ci %8 = OpLabel 3113fd4e5da5Sopenharmony_ci OpSelectionMerge %9 None 3114fd4e5da5Sopenharmony_ci OpBranchConditional %6 %11 %9 3115fd4e5da5Sopenharmony_ci %11 = OpLabel 3116fd4e5da5Sopenharmony_ci OpLoopMerge %12 %13 None 3117fd4e5da5Sopenharmony_ci OpBranch %12 3118fd4e5da5Sopenharmony_ci %13 = OpLabel 3119fd4e5da5Sopenharmony_ci OpBranch %14 3120fd4e5da5Sopenharmony_ci %14 = OpLabel 3121fd4e5da5Sopenharmony_ci OpBranch %11 3122fd4e5da5Sopenharmony_ci %12 = OpLabel 3123fd4e5da5Sopenharmony_ci OpBranch %9 3124fd4e5da5Sopenharmony_ci %10 = OpLabel 3125fd4e5da5Sopenharmony_ci OpBranchConditional %6 %9 %8 3126fd4e5da5Sopenharmony_ci %9 = OpLabel 3127fd4e5da5Sopenharmony_ci OpReturn 3128fd4e5da5Sopenharmony_ci OpFunctionEnd 3129fd4e5da5Sopenharmony_ci )"; 3130fd4e5da5Sopenharmony_ci CheckEqual(env, after_op_0, context.get()); 3131fd4e5da5Sopenharmony_ci 3132fd4e5da5Sopenharmony_ci ASSERT_TRUE(ops[1]->PreconditionHolds()); 3133fd4e5da5Sopenharmony_ci ops[1]->TryToApply(); 3134fd4e5da5Sopenharmony_ci 3135fd4e5da5Sopenharmony_ci CheckValid(env, context.get()); 3136fd4e5da5Sopenharmony_ci 3137fd4e5da5Sopenharmony_ci std::string after_op_1 = R"( 3138fd4e5da5Sopenharmony_ci OpCapability Shader 3139fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 3140fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 3141fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %2 "main" 3142fd4e5da5Sopenharmony_ci OpExecutionMode %2 OriginUpperLeft 3143fd4e5da5Sopenharmony_ci OpSource ESSL 310 3144fd4e5da5Sopenharmony_ci %3 = OpTypeVoid 3145fd4e5da5Sopenharmony_ci %4 = OpTypeFunction %3 3146fd4e5da5Sopenharmony_ci %5 = OpTypeBool 3147fd4e5da5Sopenharmony_ci %6 = OpConstantTrue %5 3148fd4e5da5Sopenharmony_ci %2 = OpFunction %3 None %4 3149fd4e5da5Sopenharmony_ci %7 = OpLabel 3150fd4e5da5Sopenharmony_ci OpBranch %8 3151fd4e5da5Sopenharmony_ci %8 = OpLabel 3152fd4e5da5Sopenharmony_ci OpSelectionMerge %9 None 3153fd4e5da5Sopenharmony_ci OpBranchConditional %6 %11 %9 3154fd4e5da5Sopenharmony_ci %11 = OpLabel 3155fd4e5da5Sopenharmony_ci OpSelectionMerge %12 None 3156fd4e5da5Sopenharmony_ci OpBranchConditional %6 %12 %12 3157fd4e5da5Sopenharmony_ci %13 = OpLabel 3158fd4e5da5Sopenharmony_ci OpBranch %14 3159fd4e5da5Sopenharmony_ci %14 = OpLabel 3160fd4e5da5Sopenharmony_ci OpBranch %11 3161fd4e5da5Sopenharmony_ci %12 = OpLabel 3162fd4e5da5Sopenharmony_ci OpBranch %9 3163fd4e5da5Sopenharmony_ci %10 = OpLabel 3164fd4e5da5Sopenharmony_ci OpBranchConditional %6 %9 %8 3165fd4e5da5Sopenharmony_ci %9 = OpLabel 3166fd4e5da5Sopenharmony_ci OpReturn 3167fd4e5da5Sopenharmony_ci OpFunctionEnd 3168fd4e5da5Sopenharmony_ci )"; 3169fd4e5da5Sopenharmony_ci CheckEqual(env, after_op_1, context.get()); 3170fd4e5da5Sopenharmony_ci} 3171fd4e5da5Sopenharmony_ci 3172fd4e5da5Sopenharmony_ciTEST(StructuredLoopToSelectionReductionPassTest, 3173fd4e5da5Sopenharmony_ci InnerLoopHeaderBranchesToOuterLoopMerge) { 3174fd4e5da5Sopenharmony_ci std::string shader = R"( 3175fd4e5da5Sopenharmony_ci OpCapability Shader 3176fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 3177fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 3178fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %2 "main" 3179fd4e5da5Sopenharmony_ci OpExecutionMode %2 OriginUpperLeft 3180fd4e5da5Sopenharmony_ci OpSource ESSL 310 3181fd4e5da5Sopenharmony_ci %3 = OpTypeVoid 3182fd4e5da5Sopenharmony_ci %4 = OpTypeFunction %3 3183fd4e5da5Sopenharmony_ci %5 = OpTypeBool 3184fd4e5da5Sopenharmony_ci %6 = OpConstantTrue %5 3185fd4e5da5Sopenharmony_ci %2 = OpFunction %3 None %4 3186fd4e5da5Sopenharmony_ci %7 = OpLabel 3187fd4e5da5Sopenharmony_ci OpBranch %8 3188fd4e5da5Sopenharmony_ci %8 = OpLabel 3189fd4e5da5Sopenharmony_ci OpLoopMerge %9 %10 None 3190fd4e5da5Sopenharmony_ci OpBranch %11 3191fd4e5da5Sopenharmony_ci %11 = OpLabel 3192fd4e5da5Sopenharmony_ci OpLoopMerge %12 %13 None 3193fd4e5da5Sopenharmony_ci OpBranchConditional %6 %9 %13 3194fd4e5da5Sopenharmony_ci %13 = OpLabel 3195fd4e5da5Sopenharmony_ci OpBranchConditional %6 %11 %12 3196fd4e5da5Sopenharmony_ci %12 = OpLabel 3197fd4e5da5Sopenharmony_ci OpBranch %10 3198fd4e5da5Sopenharmony_ci %10 = OpLabel 3199fd4e5da5Sopenharmony_ci OpBranchConditional %6 %9 %8 3200fd4e5da5Sopenharmony_ci %9 = OpLabel 3201fd4e5da5Sopenharmony_ci OpReturn 3202fd4e5da5Sopenharmony_ci OpFunctionEnd 3203fd4e5da5Sopenharmony_ci )"; 3204fd4e5da5Sopenharmony_ci 3205fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 3206fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption); 3207fd4e5da5Sopenharmony_ci auto ops = StructuredLoopToSelectionReductionOpportunityFinder() 3208fd4e5da5Sopenharmony_ci .GetAvailableOpportunities(context.get(), 0); 3209fd4e5da5Sopenharmony_ci 3210fd4e5da5Sopenharmony_ci // We cannot transform the inner loop due to its header jumping straight to 3211fd4e5da5Sopenharmony_ci // the outer loop merge (the inner loop's merge does not post-dominate its 3212fd4e5da5Sopenharmony_ci // header). 3213fd4e5da5Sopenharmony_ci ASSERT_EQ(1, ops.size()); 3214fd4e5da5Sopenharmony_ci ASSERT_TRUE(ops[0]->PreconditionHolds()); 3215fd4e5da5Sopenharmony_ci ops[0]->TryToApply(); 3216fd4e5da5Sopenharmony_ci 3217fd4e5da5Sopenharmony_ci CheckValid(env, context.get()); 3218fd4e5da5Sopenharmony_ci 3219fd4e5da5Sopenharmony_ci std::string after_op_0 = R"( 3220fd4e5da5Sopenharmony_ci OpCapability Shader 3221fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 3222fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 3223fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %2 "main" 3224fd4e5da5Sopenharmony_ci OpExecutionMode %2 OriginUpperLeft 3225fd4e5da5Sopenharmony_ci OpSource ESSL 310 3226fd4e5da5Sopenharmony_ci %3 = OpTypeVoid 3227fd4e5da5Sopenharmony_ci %4 = OpTypeFunction %3 3228fd4e5da5Sopenharmony_ci %5 = OpTypeBool 3229fd4e5da5Sopenharmony_ci %6 = OpConstantTrue %5 3230fd4e5da5Sopenharmony_ci %2 = OpFunction %3 None %4 3231fd4e5da5Sopenharmony_ci %7 = OpLabel 3232fd4e5da5Sopenharmony_ci OpBranch %8 3233fd4e5da5Sopenharmony_ci %8 = OpLabel 3234fd4e5da5Sopenharmony_ci OpSelectionMerge %9 None 3235fd4e5da5Sopenharmony_ci OpBranchConditional %6 %11 %9 3236fd4e5da5Sopenharmony_ci %11 = OpLabel 3237fd4e5da5Sopenharmony_ci OpLoopMerge %12 %13 None 3238fd4e5da5Sopenharmony_ci OpBranchConditional %6 %12 %13 3239fd4e5da5Sopenharmony_ci %13 = OpLabel 3240fd4e5da5Sopenharmony_ci OpBranchConditional %6 %11 %12 3241fd4e5da5Sopenharmony_ci %12 = OpLabel 3242fd4e5da5Sopenharmony_ci OpBranch %9 3243fd4e5da5Sopenharmony_ci %10 = OpLabel 3244fd4e5da5Sopenharmony_ci OpBranchConditional %6 %9 %8 3245fd4e5da5Sopenharmony_ci %9 = OpLabel 3246fd4e5da5Sopenharmony_ci OpReturn 3247fd4e5da5Sopenharmony_ci OpFunctionEnd 3248fd4e5da5Sopenharmony_ci )"; 3249fd4e5da5Sopenharmony_ci CheckEqual(env, after_op_0, context.get()); 3250fd4e5da5Sopenharmony_ci 3251fd4e5da5Sopenharmony_ci // Now look again for more opportunities. 3252fd4e5da5Sopenharmony_ci ops = StructuredLoopToSelectionReductionOpportunityFinder() 3253fd4e5da5Sopenharmony_ci .GetAvailableOpportunities(context.get(), 0); 3254fd4e5da5Sopenharmony_ci 3255fd4e5da5Sopenharmony_ci // What was the inner loop should now be transformable, as the jump to the 3256fd4e5da5Sopenharmony_ci // outer loop's merge has been redirected. 3257fd4e5da5Sopenharmony_ci ASSERT_EQ(1, ops.size()); 3258fd4e5da5Sopenharmony_ci ASSERT_TRUE(ops[0]->PreconditionHolds()); 3259fd4e5da5Sopenharmony_ci ops[0]->TryToApply(); 3260fd4e5da5Sopenharmony_ci 3261fd4e5da5Sopenharmony_ci CheckValid(env, context.get()); 3262fd4e5da5Sopenharmony_ci 3263fd4e5da5Sopenharmony_ci std::string after_another_op_0 = R"( 3264fd4e5da5Sopenharmony_ci OpCapability Shader 3265fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 3266fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 3267fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %2 "main" 3268fd4e5da5Sopenharmony_ci OpExecutionMode %2 OriginUpperLeft 3269fd4e5da5Sopenharmony_ci OpSource ESSL 310 3270fd4e5da5Sopenharmony_ci %3 = OpTypeVoid 3271fd4e5da5Sopenharmony_ci %4 = OpTypeFunction %3 3272fd4e5da5Sopenharmony_ci %5 = OpTypeBool 3273fd4e5da5Sopenharmony_ci %6 = OpConstantTrue %5 3274fd4e5da5Sopenharmony_ci %2 = OpFunction %3 None %4 3275fd4e5da5Sopenharmony_ci %7 = OpLabel 3276fd4e5da5Sopenharmony_ci OpBranch %8 3277fd4e5da5Sopenharmony_ci %8 = OpLabel 3278fd4e5da5Sopenharmony_ci OpSelectionMerge %9 None 3279fd4e5da5Sopenharmony_ci OpBranchConditional %6 %11 %9 3280fd4e5da5Sopenharmony_ci %11 = OpLabel 3281fd4e5da5Sopenharmony_ci OpSelectionMerge %12 None 3282fd4e5da5Sopenharmony_ci OpBranchConditional %6 %12 %12 3283fd4e5da5Sopenharmony_ci %13 = OpLabel 3284fd4e5da5Sopenharmony_ci OpBranchConditional %6 %11 %12 3285fd4e5da5Sopenharmony_ci %12 = OpLabel 3286fd4e5da5Sopenharmony_ci OpBranch %9 3287fd4e5da5Sopenharmony_ci %10 = OpLabel 3288fd4e5da5Sopenharmony_ci OpBranchConditional %6 %9 %8 3289fd4e5da5Sopenharmony_ci %9 = OpLabel 3290fd4e5da5Sopenharmony_ci OpReturn 3291fd4e5da5Sopenharmony_ci OpFunctionEnd 3292fd4e5da5Sopenharmony_ci )"; 3293fd4e5da5Sopenharmony_ci CheckEqual(env, after_another_op_0, context.get()); 3294fd4e5da5Sopenharmony_ci} 3295fd4e5da5Sopenharmony_ci 3296fd4e5da5Sopenharmony_ciTEST(StructuredLoopToSelectionReductionPassTest, LongAccessChains) { 3297fd4e5da5Sopenharmony_ci std::string shader = R"( 3298fd4e5da5Sopenharmony_ci OpCapability Shader 3299fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 3300fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 3301fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %2 "main" 3302fd4e5da5Sopenharmony_ci OpExecutionMode %2 OriginUpperLeft 3303fd4e5da5Sopenharmony_ci OpSource ESSL 310 3304fd4e5da5Sopenharmony_ci %3 = OpTypeVoid 3305fd4e5da5Sopenharmony_ci %4 = OpTypeFunction %3 3306fd4e5da5Sopenharmony_ci %5 = OpTypeInt 32 1 3307fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 0 3308fd4e5da5Sopenharmony_ci %7 = OpConstant %6 5 3309fd4e5da5Sopenharmony_ci %8 = OpTypeArray %5 %7 3310fd4e5da5Sopenharmony_ci %9 = OpTypeStruct %8 3311fd4e5da5Sopenharmony_ci %10 = OpTypeStruct %9 %9 3312fd4e5da5Sopenharmony_ci %11 = OpConstant %6 2 3313fd4e5da5Sopenharmony_ci %12 = OpTypeArray %10 %11 3314fd4e5da5Sopenharmony_ci %13 = OpTypeStruct %12 3315fd4e5da5Sopenharmony_ci %14 = OpTypePointer Function %13 3316fd4e5da5Sopenharmony_ci %15 = OpConstant %5 0 3317fd4e5da5Sopenharmony_ci %16 = OpConstant %5 1 3318fd4e5da5Sopenharmony_ci %17 = OpConstant %5 2 3319fd4e5da5Sopenharmony_ci %18 = OpConstant %5 3 3320fd4e5da5Sopenharmony_ci %19 = OpConstant %5 4 3321fd4e5da5Sopenharmony_ci %20 = OpConstantComposite %8 %15 %16 %17 %18 %19 3322fd4e5da5Sopenharmony_ci %21 = OpConstantComposite %9 %20 3323fd4e5da5Sopenharmony_ci %22 = OpConstant %5 5 3324fd4e5da5Sopenharmony_ci %23 = OpConstant %5 6 3325fd4e5da5Sopenharmony_ci %24 = OpConstant %5 7 3326fd4e5da5Sopenharmony_ci %25 = OpConstant %5 8 3327fd4e5da5Sopenharmony_ci %26 = OpConstant %5 9 3328fd4e5da5Sopenharmony_ci %27 = OpConstantComposite %8 %22 %23 %24 %25 %26 3329fd4e5da5Sopenharmony_ci %28 = OpConstantComposite %9 %27 3330fd4e5da5Sopenharmony_ci %29 = OpConstantComposite %10 %21 %28 3331fd4e5da5Sopenharmony_ci %30 = OpConstant %5 10 3332fd4e5da5Sopenharmony_ci %31 = OpConstant %5 11 3333fd4e5da5Sopenharmony_ci %32 = OpConstant %5 12 3334fd4e5da5Sopenharmony_ci %33 = OpConstant %5 13 3335fd4e5da5Sopenharmony_ci %34 = OpConstant %5 14 3336fd4e5da5Sopenharmony_ci %35 = OpConstantComposite %8 %30 %31 %32 %33 %34 3337fd4e5da5Sopenharmony_ci %36 = OpConstantComposite %9 %35 3338fd4e5da5Sopenharmony_ci %37 = OpConstant %5 15 3339fd4e5da5Sopenharmony_ci %38 = OpConstant %5 16 3340fd4e5da5Sopenharmony_ci %39 = OpConstant %5 17 3341fd4e5da5Sopenharmony_ci %40 = OpConstant %5 18 3342fd4e5da5Sopenharmony_ci %41 = OpConstant %5 19 3343fd4e5da5Sopenharmony_ci %42 = OpConstantComposite %8 %37 %38 %39 %40 %41 3344fd4e5da5Sopenharmony_ci %43 = OpConstantComposite %9 %42 3345fd4e5da5Sopenharmony_ci %44 = OpConstantComposite %10 %36 %43 3346fd4e5da5Sopenharmony_ci %45 = OpConstantComposite %12 %29 %44 3347fd4e5da5Sopenharmony_ci %46 = OpConstantComposite %13 %45 3348fd4e5da5Sopenharmony_ci %47 = OpTypePointer Function %12 3349fd4e5da5Sopenharmony_ci %48 = OpTypePointer Function %10 3350fd4e5da5Sopenharmony_ci %49 = OpTypePointer Function %9 3351fd4e5da5Sopenharmony_ci %50 = OpTypePointer Function %8 3352fd4e5da5Sopenharmony_ci %51 = OpTypePointer Function %5 3353fd4e5da5Sopenharmony_ci %52 = OpTypeBool 3354fd4e5da5Sopenharmony_ci %53 = OpConstantTrue %52 3355fd4e5da5Sopenharmony_ci %2 = OpFunction %3 None %4 3356fd4e5da5Sopenharmony_ci %54 = OpLabel 3357fd4e5da5Sopenharmony_ci %55 = OpVariable %14 Function 3358fd4e5da5Sopenharmony_ci OpStore %55 %46 3359fd4e5da5Sopenharmony_ci OpBranch %56 3360fd4e5da5Sopenharmony_ci %56 = OpLabel 3361fd4e5da5Sopenharmony_ci OpLoopMerge %57 %58 None 3362fd4e5da5Sopenharmony_ci OpBranchConditional %53 %57 %59 3363fd4e5da5Sopenharmony_ci %59 = OpLabel 3364fd4e5da5Sopenharmony_ci OpSelectionMerge %60 None 3365fd4e5da5Sopenharmony_ci OpBranchConditional %53 %61 %57 3366fd4e5da5Sopenharmony_ci %61 = OpLabel 3367fd4e5da5Sopenharmony_ci %62 = OpAccessChain %47 %55 %15 3368fd4e5da5Sopenharmony_ci OpBranch %63 3369fd4e5da5Sopenharmony_ci %63 = OpLabel 3370fd4e5da5Sopenharmony_ci OpSelectionMerge %64 None 3371fd4e5da5Sopenharmony_ci OpBranchConditional %53 %65 %57 3372fd4e5da5Sopenharmony_ci %65 = OpLabel 3373fd4e5da5Sopenharmony_ci %66 = OpAccessChain %48 %62 %16 3374fd4e5da5Sopenharmony_ci OpBranch %67 3375fd4e5da5Sopenharmony_ci %67 = OpLabel 3376fd4e5da5Sopenharmony_ci OpSelectionMerge %68 None 3377fd4e5da5Sopenharmony_ci OpBranchConditional %53 %69 %57 3378fd4e5da5Sopenharmony_ci %69 = OpLabel 3379fd4e5da5Sopenharmony_ci %70 = OpAccessChain %49 %66 %16 3380fd4e5da5Sopenharmony_ci OpBranch %71 3381fd4e5da5Sopenharmony_ci %71 = OpLabel 3382fd4e5da5Sopenharmony_ci OpSelectionMerge %72 None 3383fd4e5da5Sopenharmony_ci OpBranchConditional %53 %73 %57 3384fd4e5da5Sopenharmony_ci %73 = OpLabel 3385fd4e5da5Sopenharmony_ci %74 = OpAccessChain %50 %70 %15 3386fd4e5da5Sopenharmony_ci OpBranch %75 3387fd4e5da5Sopenharmony_ci %75 = OpLabel 3388fd4e5da5Sopenharmony_ci OpSelectionMerge %76 None 3389fd4e5da5Sopenharmony_ci OpBranchConditional %53 %77 %57 3390fd4e5da5Sopenharmony_ci %77 = OpLabel 3391fd4e5da5Sopenharmony_ci %78 = OpAccessChain %51 %74 %17 3392fd4e5da5Sopenharmony_ci OpBranch %79 3393fd4e5da5Sopenharmony_ci %79 = OpLabel 3394fd4e5da5Sopenharmony_ci OpSelectionMerge %80 None 3395fd4e5da5Sopenharmony_ci OpBranchConditional %53 %81 %57 3396fd4e5da5Sopenharmony_ci %81 = OpLabel 3397fd4e5da5Sopenharmony_ci %82 = OpLoad %5 %78 3398fd4e5da5Sopenharmony_ci OpBranch %80 3399fd4e5da5Sopenharmony_ci %80 = OpLabel 3400fd4e5da5Sopenharmony_ci OpBranch %76 3401fd4e5da5Sopenharmony_ci %76 = OpLabel 3402fd4e5da5Sopenharmony_ci OpBranch %72 3403fd4e5da5Sopenharmony_ci %72 = OpLabel 3404fd4e5da5Sopenharmony_ci OpBranch %68 3405fd4e5da5Sopenharmony_ci %68 = OpLabel 3406fd4e5da5Sopenharmony_ci OpBranch %64 3407fd4e5da5Sopenharmony_ci %64 = OpLabel 3408fd4e5da5Sopenharmony_ci OpBranch %60 3409fd4e5da5Sopenharmony_ci %60 = OpLabel 3410fd4e5da5Sopenharmony_ci OpBranch %58 3411fd4e5da5Sopenharmony_ci %58 = OpLabel 3412fd4e5da5Sopenharmony_ci OpBranch %56 3413fd4e5da5Sopenharmony_ci %57 = OpLabel 3414fd4e5da5Sopenharmony_ci OpReturn 3415fd4e5da5Sopenharmony_ci OpFunctionEnd 3416fd4e5da5Sopenharmony_ci )"; 3417fd4e5da5Sopenharmony_ci 3418fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 3419fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption); 3420fd4e5da5Sopenharmony_ci auto ops = StructuredLoopToSelectionReductionOpportunityFinder() 3421fd4e5da5Sopenharmony_ci .GetAvailableOpportunities(context.get(), 0); 3422fd4e5da5Sopenharmony_ci 3423fd4e5da5Sopenharmony_ci ASSERT_EQ(1, ops.size()); 3424fd4e5da5Sopenharmony_ci ASSERT_TRUE(ops[0]->PreconditionHolds()); 3425fd4e5da5Sopenharmony_ci ops[0]->TryToApply(); 3426fd4e5da5Sopenharmony_ci 3427fd4e5da5Sopenharmony_ci CheckValid(env, context.get()); 3428fd4e5da5Sopenharmony_ci 3429fd4e5da5Sopenharmony_ci // TODO(2183): When we have a more general solution for handling access 3430fd4e5da5Sopenharmony_ci // chains, write an expected result for this test. 3431fd4e5da5Sopenharmony_ci // std::string expected = R"( 3432fd4e5da5Sopenharmony_ci // Expected text for transformed shader 3433fd4e5da5Sopenharmony_ci //)"; 3434fd4e5da5Sopenharmony_ci // CheckEqual(env, expected, context.get()); 3435fd4e5da5Sopenharmony_ci} 3436fd4e5da5Sopenharmony_ci 3437fd4e5da5Sopenharmony_ciTEST(StructuredLoopToSelectionReductionPassTest, LoopyShaderWithOpDecorate) { 3438fd4e5da5Sopenharmony_ci // A shader containing a function that contains a loop and some definitions 3439fd4e5da5Sopenharmony_ci // that are "used" in OpDecorate instructions (outside the function). These 3440fd4e5da5Sopenharmony_ci // "uses" were causing segfaults because we try to calculate their dominance 3441fd4e5da5Sopenharmony_ci // information, which doesn't make sense. 3442fd4e5da5Sopenharmony_ci 3443fd4e5da5Sopenharmony_ci std::string shader = R"( 3444fd4e5da5Sopenharmony_ci OpCapability Shader 3445fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 3446fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 3447fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" %9 3448fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 3449fd4e5da5Sopenharmony_ci OpSource ESSL 310 3450fd4e5da5Sopenharmony_ci OpName %4 "main" 3451fd4e5da5Sopenharmony_ci OpName %9 "_GLF_color" 3452fd4e5da5Sopenharmony_ci OpName %14 "buf0" 3453fd4e5da5Sopenharmony_ci OpMemberName %14 0 "a" 3454fd4e5da5Sopenharmony_ci OpName %16 "" 3455fd4e5da5Sopenharmony_ci OpDecorate %9 RelaxedPrecision 3456fd4e5da5Sopenharmony_ci OpDecorate %9 Location 0 3457fd4e5da5Sopenharmony_ci OpMemberDecorate %14 0 RelaxedPrecision 3458fd4e5da5Sopenharmony_ci OpMemberDecorate %14 0 Offset 0 3459fd4e5da5Sopenharmony_ci OpDecorate %14 Block 3460fd4e5da5Sopenharmony_ci OpDecorate %16 DescriptorSet 0 3461fd4e5da5Sopenharmony_ci OpDecorate %16 Binding 0 3462fd4e5da5Sopenharmony_ci OpDecorate %21 RelaxedPrecision 3463fd4e5da5Sopenharmony_ci OpDecorate %35 RelaxedPrecision 3464fd4e5da5Sopenharmony_ci OpDecorate %36 RelaxedPrecision 3465fd4e5da5Sopenharmony_ci OpDecorate %39 RelaxedPrecision 3466fd4e5da5Sopenharmony_ci OpDecorate %40 RelaxedPrecision 3467fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 3468fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 3469fd4e5da5Sopenharmony_ci %6 = OpTypeFloat 32 3470fd4e5da5Sopenharmony_ci %7 = OpTypeVector %6 4 3471fd4e5da5Sopenharmony_ci %8 = OpTypePointer Output %7 3472fd4e5da5Sopenharmony_ci %9 = OpVariable %8 Output 3473fd4e5da5Sopenharmony_ci %10 = OpConstant %6 1 3474fd4e5da5Sopenharmony_ci %11 = OpConstantComposite %7 %10 %10 %10 %10 3475fd4e5da5Sopenharmony_ci %14 = OpTypeStruct %6 3476fd4e5da5Sopenharmony_ci %15 = OpTypePointer Uniform %14 3477fd4e5da5Sopenharmony_ci %16 = OpVariable %15 Uniform 3478fd4e5da5Sopenharmony_ci %17 = OpTypeInt 32 1 3479fd4e5da5Sopenharmony_ci %18 = OpConstant %17 0 3480fd4e5da5Sopenharmony_ci %19 = OpTypePointer Uniform %6 3481fd4e5da5Sopenharmony_ci %28 = OpConstant %6 2 3482fd4e5da5Sopenharmony_ci %29 = OpTypeBool 3483fd4e5da5Sopenharmony_ci %31 = OpTypeInt 32 0 3484fd4e5da5Sopenharmony_ci %32 = OpConstant %31 0 3485fd4e5da5Sopenharmony_ci %33 = OpTypePointer Output %6 3486fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 3487fd4e5da5Sopenharmony_ci %5 = OpLabel 3488fd4e5da5Sopenharmony_ci OpStore %9 %11 3489fd4e5da5Sopenharmony_ci %20 = OpAccessChain %19 %16 %18 3490fd4e5da5Sopenharmony_ci %21 = OpLoad %6 %20 3491fd4e5da5Sopenharmony_ci OpBranch %22 3492fd4e5da5Sopenharmony_ci %22 = OpLabel 3493fd4e5da5Sopenharmony_ci %40 = OpPhi %6 %21 %5 %39 %23 3494fd4e5da5Sopenharmony_ci %30 = OpFOrdLessThan %29 %40 %28 3495fd4e5da5Sopenharmony_ci OpLoopMerge %24 %23 None 3496fd4e5da5Sopenharmony_ci OpBranchConditional %30 %23 %24 3497fd4e5da5Sopenharmony_ci %23 = OpLabel 3498fd4e5da5Sopenharmony_ci %34 = OpAccessChain %33 %9 %32 3499fd4e5da5Sopenharmony_ci %35 = OpLoad %6 %34 3500fd4e5da5Sopenharmony_ci %36 = OpFAdd %6 %35 %10 3501fd4e5da5Sopenharmony_ci OpStore %34 %36 3502fd4e5da5Sopenharmony_ci %39 = OpFAdd %6 %40 %10 3503fd4e5da5Sopenharmony_ci OpBranch %22 3504fd4e5da5Sopenharmony_ci %24 = OpLabel 3505fd4e5da5Sopenharmony_ci OpReturn 3506fd4e5da5Sopenharmony_ci OpFunctionEnd 3507fd4e5da5Sopenharmony_ci )"; 3508fd4e5da5Sopenharmony_ci 3509fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 3510fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption); 3511fd4e5da5Sopenharmony_ci const auto ops = StructuredLoopToSelectionReductionOpportunityFinder() 3512fd4e5da5Sopenharmony_ci .GetAvailableOpportunities(context.get(), 0); 3513fd4e5da5Sopenharmony_ci ASSERT_EQ(1, ops.size()); 3514fd4e5da5Sopenharmony_ci 3515fd4e5da5Sopenharmony_ci ASSERT_TRUE(ops[0]->PreconditionHolds()); 3516fd4e5da5Sopenharmony_ci ops[0]->TryToApply(); 3517fd4e5da5Sopenharmony_ci CheckValid(env, context.get()); 3518fd4e5da5Sopenharmony_ci 3519fd4e5da5Sopenharmony_ci std::string after_op_0 = R"( 3520fd4e5da5Sopenharmony_ci OpCapability Shader 3521fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 3522fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 3523fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" %9 3524fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 3525fd4e5da5Sopenharmony_ci OpSource ESSL 310 3526fd4e5da5Sopenharmony_ci OpName %4 "main" 3527fd4e5da5Sopenharmony_ci OpName %9 "_GLF_color" 3528fd4e5da5Sopenharmony_ci OpName %14 "buf0" 3529fd4e5da5Sopenharmony_ci OpMemberName %14 0 "a" 3530fd4e5da5Sopenharmony_ci OpName %16 "" 3531fd4e5da5Sopenharmony_ci OpDecorate %9 RelaxedPrecision 3532fd4e5da5Sopenharmony_ci OpDecorate %9 Location 0 3533fd4e5da5Sopenharmony_ci OpMemberDecorate %14 0 RelaxedPrecision 3534fd4e5da5Sopenharmony_ci OpMemberDecorate %14 0 Offset 0 3535fd4e5da5Sopenharmony_ci OpDecorate %14 Block 3536fd4e5da5Sopenharmony_ci OpDecorate %16 DescriptorSet 0 3537fd4e5da5Sopenharmony_ci OpDecorate %16 Binding 0 3538fd4e5da5Sopenharmony_ci OpDecorate %21 RelaxedPrecision 3539fd4e5da5Sopenharmony_ci OpDecorate %35 RelaxedPrecision 3540fd4e5da5Sopenharmony_ci OpDecorate %36 RelaxedPrecision 3541fd4e5da5Sopenharmony_ci OpDecorate %39 RelaxedPrecision 3542fd4e5da5Sopenharmony_ci OpDecorate %40 RelaxedPrecision 3543fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 3544fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 3545fd4e5da5Sopenharmony_ci %6 = OpTypeFloat 32 3546fd4e5da5Sopenharmony_ci %7 = OpTypeVector %6 4 3547fd4e5da5Sopenharmony_ci %8 = OpTypePointer Output %7 3548fd4e5da5Sopenharmony_ci %9 = OpVariable %8 Output 3549fd4e5da5Sopenharmony_ci %10 = OpConstant %6 1 3550fd4e5da5Sopenharmony_ci %11 = OpConstantComposite %7 %10 %10 %10 %10 3551fd4e5da5Sopenharmony_ci %14 = OpTypeStruct %6 3552fd4e5da5Sopenharmony_ci %15 = OpTypePointer Uniform %14 3553fd4e5da5Sopenharmony_ci %16 = OpVariable %15 Uniform 3554fd4e5da5Sopenharmony_ci %17 = OpTypeInt 32 1 3555fd4e5da5Sopenharmony_ci %18 = OpConstant %17 0 3556fd4e5da5Sopenharmony_ci %19 = OpTypePointer Uniform %6 3557fd4e5da5Sopenharmony_ci %28 = OpConstant %6 2 3558fd4e5da5Sopenharmony_ci %29 = OpTypeBool 3559fd4e5da5Sopenharmony_ci %31 = OpTypeInt 32 0 3560fd4e5da5Sopenharmony_ci %32 = OpConstant %31 0 3561fd4e5da5Sopenharmony_ci %33 = OpTypePointer Output %6 3562fd4e5da5Sopenharmony_ci %41 = OpUndef %6 ; Added 3563fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 3564fd4e5da5Sopenharmony_ci %5 = OpLabel 3565fd4e5da5Sopenharmony_ci OpStore %9 %11 3566fd4e5da5Sopenharmony_ci %20 = OpAccessChain %19 %16 %18 3567fd4e5da5Sopenharmony_ci %21 = OpLoad %6 %20 3568fd4e5da5Sopenharmony_ci OpBranch %22 3569fd4e5da5Sopenharmony_ci %22 = OpLabel 3570fd4e5da5Sopenharmony_ci %40 = OpPhi %6 %21 %5 %41 %23 ; Changed 3571fd4e5da5Sopenharmony_ci %30 = OpFOrdLessThan %29 %40 %28 3572fd4e5da5Sopenharmony_ci OpSelectionMerge %24 None ; Changed 3573fd4e5da5Sopenharmony_ci OpBranchConditional %30 %24 %24 3574fd4e5da5Sopenharmony_ci %23 = OpLabel 3575fd4e5da5Sopenharmony_ci %34 = OpAccessChain %33 %9 %32 3576fd4e5da5Sopenharmony_ci %35 = OpLoad %6 %34 3577fd4e5da5Sopenharmony_ci %36 = OpFAdd %6 %35 %10 3578fd4e5da5Sopenharmony_ci OpStore %34 %36 3579fd4e5da5Sopenharmony_ci %39 = OpFAdd %6 %41 %10 ; Changed 3580fd4e5da5Sopenharmony_ci OpBranch %22 3581fd4e5da5Sopenharmony_ci %24 = OpLabel 3582fd4e5da5Sopenharmony_ci OpReturn 3583fd4e5da5Sopenharmony_ci OpFunctionEnd 3584fd4e5da5Sopenharmony_ci )"; 3585fd4e5da5Sopenharmony_ci CheckEqual(env, after_op_0, context.get()); 3586fd4e5da5Sopenharmony_ci} 3587fd4e5da5Sopenharmony_ci 3588fd4e5da5Sopenharmony_ciTEST(StructuredLoopToSelectionReductionPassTest, 3589fd4e5da5Sopenharmony_ci LoopWithCombinedHeaderAndContinue) { 3590fd4e5da5Sopenharmony_ci // A shader containing a loop where the header is also the continue target. 3591fd4e5da5Sopenharmony_ci // For now, we don't simplify such loops. 3592fd4e5da5Sopenharmony_ci 3593fd4e5da5Sopenharmony_ci std::string shader = R"( 3594fd4e5da5Sopenharmony_ci OpCapability Shader 3595fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 3596fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 3597fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 3598fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 3599fd4e5da5Sopenharmony_ci OpSource ESSL 310 3600fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 3601fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 3602fd4e5da5Sopenharmony_ci %6 = OpTypeBool 3603fd4e5da5Sopenharmony_ci %30 = OpConstantFalse %6 3604fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 3605fd4e5da5Sopenharmony_ci %5 = OpLabel 3606fd4e5da5Sopenharmony_ci OpBranch %10 3607fd4e5da5Sopenharmony_ci %10 = OpLabel ; loop header and continue target 3608fd4e5da5Sopenharmony_ci OpLoopMerge %12 %10 None 3609fd4e5da5Sopenharmony_ci OpBranchConditional %30 %10 %12 3610fd4e5da5Sopenharmony_ci %12 = OpLabel 3611fd4e5da5Sopenharmony_ci OpReturn 3612fd4e5da5Sopenharmony_ci OpFunctionEnd 3613fd4e5da5Sopenharmony_ci )"; 3614fd4e5da5Sopenharmony_ci 3615fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 3616fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption); 3617fd4e5da5Sopenharmony_ci const auto ops = StructuredLoopToSelectionReductionOpportunityFinder() 3618fd4e5da5Sopenharmony_ci .GetAvailableOpportunities(context.get(), 0); 3619fd4e5da5Sopenharmony_ci ASSERT_EQ(0, ops.size()); 3620fd4e5da5Sopenharmony_ci} 3621fd4e5da5Sopenharmony_ci 3622fd4e5da5Sopenharmony_ci} // namespace 3623fd4e5da5Sopenharmony_ci} // namespace reduce 3624fd4e5da5Sopenharmony_ci} // namespace spvtools 3625