1fd4e5da5Sopenharmony_ci// Copyright (c) 2021 Alastair F. Donaldson 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_construct_to_block_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(StructuredConstructToBlockReductionPassTest, SimpleTest) { 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 320 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 %10 = OpTypeBool 39fd4e5da5Sopenharmony_ci %11 = OpConstantTrue %10 40fd4e5da5Sopenharmony_ci %19 = OpConstant %6 3 41fd4e5da5Sopenharmony_ci %29 = OpConstant %6 1 42fd4e5da5Sopenharmony_ci %31 = OpConstant %6 2 43fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 44fd4e5da5Sopenharmony_ci %5 = OpLabel 45fd4e5da5Sopenharmony_ci %8 = OpVariable %7 Function 46fd4e5da5Sopenharmony_ci OpStore %8 %9 47fd4e5da5Sopenharmony_ci OpSelectionMerge %13 None 48fd4e5da5Sopenharmony_ci OpBranchConditional %11 %12 %13 49fd4e5da5Sopenharmony_ci %12 = OpLabel 50fd4e5da5Sopenharmony_ci OpBranch %13 51fd4e5da5Sopenharmony_ci %13 = OpLabel 52fd4e5da5Sopenharmony_ci OpBranch %14 53fd4e5da5Sopenharmony_ci %14 = OpLabel 54fd4e5da5Sopenharmony_ci OpLoopMerge %16 %17 None 55fd4e5da5Sopenharmony_ci OpBranch %15 56fd4e5da5Sopenharmony_ci %15 = OpLabel 57fd4e5da5Sopenharmony_ci %18 = OpLoad %6 %8 58fd4e5da5Sopenharmony_ci %20 = OpSGreaterThan %10 %18 %19 59fd4e5da5Sopenharmony_ci OpSelectionMerge %22 None 60fd4e5da5Sopenharmony_ci OpBranchConditional %20 %21 %22 61fd4e5da5Sopenharmony_ci %21 = OpLabel 62fd4e5da5Sopenharmony_ci OpBranch %16 63fd4e5da5Sopenharmony_ci %22 = OpLabel 64fd4e5da5Sopenharmony_ci OpBranch %17 65fd4e5da5Sopenharmony_ci %17 = OpLabel 66fd4e5da5Sopenharmony_ci OpBranch %14 67fd4e5da5Sopenharmony_ci %16 = OpLabel 68fd4e5da5Sopenharmony_ci %24 = OpLoad %6 %8 69fd4e5da5Sopenharmony_ci OpSelectionMerge %28 None 70fd4e5da5Sopenharmony_ci OpSwitch %24 %27 1 %25 2 %26 71fd4e5da5Sopenharmony_ci %27 = OpLabel 72fd4e5da5Sopenharmony_ci OpStore %8 %19 73fd4e5da5Sopenharmony_ci OpBranch %28 74fd4e5da5Sopenharmony_ci %25 = OpLabel 75fd4e5da5Sopenharmony_ci OpStore %8 %29 76fd4e5da5Sopenharmony_ci OpBranch %28 77fd4e5da5Sopenharmony_ci %26 = OpLabel 78fd4e5da5Sopenharmony_ci OpStore %8 %31 79fd4e5da5Sopenharmony_ci OpBranch %28 80fd4e5da5Sopenharmony_ci %28 = OpLabel 81fd4e5da5Sopenharmony_ci OpReturn 82fd4e5da5Sopenharmony_ci OpFunctionEnd 83fd4e5da5Sopenharmony_ci )"; 84fd4e5da5Sopenharmony_ci 85fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 86fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption); 87fd4e5da5Sopenharmony_ci const auto ops = StructuredConstructToBlockReductionOpportunityFinder() 88fd4e5da5Sopenharmony_ci .GetAvailableOpportunities(context.get(), 0); 89fd4e5da5Sopenharmony_ci ASSERT_EQ(3, ops.size()); 90fd4e5da5Sopenharmony_ci 91fd4e5da5Sopenharmony_ci ASSERT_TRUE(ops[0]->PreconditionHolds()); 92fd4e5da5Sopenharmony_ci ops[0]->TryToApply(); 93fd4e5da5Sopenharmony_ci CheckValid(env, context.get()); 94fd4e5da5Sopenharmony_ci 95fd4e5da5Sopenharmony_ci ASSERT_TRUE(ops[1]->PreconditionHolds()); 96fd4e5da5Sopenharmony_ci ops[1]->TryToApply(); 97fd4e5da5Sopenharmony_ci CheckValid(env, context.get()); 98fd4e5da5Sopenharmony_ci 99fd4e5da5Sopenharmony_ci ASSERT_TRUE(ops[2]->PreconditionHolds()); 100fd4e5da5Sopenharmony_ci ops[2]->TryToApply(); 101fd4e5da5Sopenharmony_ci CheckValid(env, context.get()); 102fd4e5da5Sopenharmony_ci 103fd4e5da5Sopenharmony_ci std::string expected = R"( 104fd4e5da5Sopenharmony_ci OpCapability Shader 105fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 106fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 107fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 108fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 109fd4e5da5Sopenharmony_ci OpSource ESSL 320 110fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 111fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 112fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 113fd4e5da5Sopenharmony_ci %7 = OpTypePointer Function %6 114fd4e5da5Sopenharmony_ci %9 = OpConstant %6 0 115fd4e5da5Sopenharmony_ci %10 = OpTypeBool 116fd4e5da5Sopenharmony_ci %11 = OpConstantTrue %10 117fd4e5da5Sopenharmony_ci %19 = OpConstant %6 3 118fd4e5da5Sopenharmony_ci %29 = OpConstant %6 1 119fd4e5da5Sopenharmony_ci %31 = OpConstant %6 2 120fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 121fd4e5da5Sopenharmony_ci %5 = OpLabel 122fd4e5da5Sopenharmony_ci %8 = OpVariable %7 Function 123fd4e5da5Sopenharmony_ci OpStore %8 %9 124fd4e5da5Sopenharmony_ci OpBranch %13 125fd4e5da5Sopenharmony_ci %13 = OpLabel 126fd4e5da5Sopenharmony_ci OpBranch %14 127fd4e5da5Sopenharmony_ci %14 = OpLabel 128fd4e5da5Sopenharmony_ci OpBranch %16 129fd4e5da5Sopenharmony_ci %16 = OpLabel 130fd4e5da5Sopenharmony_ci %24 = OpLoad %6 %8 131fd4e5da5Sopenharmony_ci OpBranch %28 132fd4e5da5Sopenharmony_ci %28 = OpLabel 133fd4e5da5Sopenharmony_ci OpReturn 134fd4e5da5Sopenharmony_ci OpFunctionEnd 135fd4e5da5Sopenharmony_ci )"; 136fd4e5da5Sopenharmony_ci CheckEqual(env, expected, context.get()); 137fd4e5da5Sopenharmony_ci} 138fd4e5da5Sopenharmony_ci 139fd4e5da5Sopenharmony_ciTEST(StructuredConstructToBlockReductionPassTest, CannotBeRemovedDueToUses) { 140fd4e5da5Sopenharmony_ci std::string shader = R"( 141fd4e5da5Sopenharmony_ci OpCapability Shader 142fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 143fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 144fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 145fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 146fd4e5da5Sopenharmony_ci OpSource ESSL 320 147fd4e5da5Sopenharmony_ci OpName %100 "temp" 148fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 149fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 150fd4e5da5Sopenharmony_ci %6 = OpTypeInt 32 1 151fd4e5da5Sopenharmony_ci %7 = OpTypePointer Function %6 152fd4e5da5Sopenharmony_ci %9 = OpConstant %6 0 153fd4e5da5Sopenharmony_ci %10 = OpTypeBool 154fd4e5da5Sopenharmony_ci %11 = OpConstantTrue %10 155fd4e5da5Sopenharmony_ci %19 = OpConstant %6 3 156fd4e5da5Sopenharmony_ci %29 = OpConstant %6 1 157fd4e5da5Sopenharmony_ci %31 = OpConstant %6 2 158fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 159fd4e5da5Sopenharmony_ci %5 = OpLabel 160fd4e5da5Sopenharmony_ci %8 = OpVariable %7 Function 161fd4e5da5Sopenharmony_ci OpStore %8 %9 162fd4e5da5Sopenharmony_ci OpSelectionMerge %13 None 163fd4e5da5Sopenharmony_ci OpBranchConditional %11 %12 %13 164fd4e5da5Sopenharmony_ci %12 = OpLabel 165fd4e5da5Sopenharmony_ci %100 = OpCopyObject %10 %11 166fd4e5da5Sopenharmony_ci OpBranch %13 167fd4e5da5Sopenharmony_ci %13 = OpLabel 168fd4e5da5Sopenharmony_ci OpBranch %14 169fd4e5da5Sopenharmony_ci %14 = OpLabel 170fd4e5da5Sopenharmony_ci OpLoopMerge %16 %17 None 171fd4e5da5Sopenharmony_ci OpBranch %15 172fd4e5da5Sopenharmony_ci %15 = OpLabel 173fd4e5da5Sopenharmony_ci %18 = OpLoad %6 %8 174fd4e5da5Sopenharmony_ci %20 = OpSGreaterThan %10 %18 %19 175fd4e5da5Sopenharmony_ci OpSelectionMerge %22 None 176fd4e5da5Sopenharmony_ci OpBranchConditional %20 %21 %22 177fd4e5da5Sopenharmony_ci %21 = OpLabel 178fd4e5da5Sopenharmony_ci OpBranch %16 179fd4e5da5Sopenharmony_ci %22 = OpLabel 180fd4e5da5Sopenharmony_ci OpBranch %17 181fd4e5da5Sopenharmony_ci %17 = OpLabel 182fd4e5da5Sopenharmony_ci OpBranch %14 183fd4e5da5Sopenharmony_ci %16 = OpLabel 184fd4e5da5Sopenharmony_ci %101 = OpCopyObject %6 %18 185fd4e5da5Sopenharmony_ci %24 = OpLoad %6 %8 186fd4e5da5Sopenharmony_ci OpSelectionMerge %28 None 187fd4e5da5Sopenharmony_ci OpSwitch %24 %27 1 %25 2 %26 188fd4e5da5Sopenharmony_ci %27 = OpLabel 189fd4e5da5Sopenharmony_ci OpStore %8 %19 190fd4e5da5Sopenharmony_ci %102 = OpCopyObject %10 %11 191fd4e5da5Sopenharmony_ci OpBranch %28 192fd4e5da5Sopenharmony_ci %25 = OpLabel 193fd4e5da5Sopenharmony_ci OpStore %8 %29 194fd4e5da5Sopenharmony_ci OpBranch %28 195fd4e5da5Sopenharmony_ci %26 = OpLabel 196fd4e5da5Sopenharmony_ci OpStore %8 %31 197fd4e5da5Sopenharmony_ci OpBranch %28 198fd4e5da5Sopenharmony_ci %28 = OpLabel 199fd4e5da5Sopenharmony_ci %103 = OpPhi %10 %102 %27 %11 %25 %11 %26 200fd4e5da5Sopenharmony_ci OpReturn 201fd4e5da5Sopenharmony_ci OpFunctionEnd 202fd4e5da5Sopenharmony_ci )"; 203fd4e5da5Sopenharmony_ci 204fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 205fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption); 206fd4e5da5Sopenharmony_ci const auto ops = StructuredConstructToBlockReductionOpportunityFinder() 207fd4e5da5Sopenharmony_ci .GetAvailableOpportunities(context.get(), 0); 208fd4e5da5Sopenharmony_ci ASSERT_TRUE(ops.empty()); 209fd4e5da5Sopenharmony_ci} 210fd4e5da5Sopenharmony_ci 211fd4e5da5Sopenharmony_ciTEST(StructuredConstructToBlockReductionPassTest, 212fd4e5da5Sopenharmony_ci CannotBeRemovedDueToOpPhiAtMerge) { 213fd4e5da5Sopenharmony_ci std::string shader = R"( 214fd4e5da5Sopenharmony_ci OpCapability Shader 215fd4e5da5Sopenharmony_ci %1 = OpExtInstImport "GLSL.std.450" 216fd4e5da5Sopenharmony_ci OpMemoryModel Logical GLSL450 217fd4e5da5Sopenharmony_ci OpEntryPoint Fragment %4 "main" 218fd4e5da5Sopenharmony_ci OpExecutionMode %4 OriginUpperLeft 219fd4e5da5Sopenharmony_ci OpSource ESSL 320 220fd4e5da5Sopenharmony_ci %2 = OpTypeVoid 221fd4e5da5Sopenharmony_ci %3 = OpTypeFunction %2 222fd4e5da5Sopenharmony_ci %10 = OpTypeBool 223fd4e5da5Sopenharmony_ci %11 = OpConstantTrue %10 224fd4e5da5Sopenharmony_ci %4 = OpFunction %2 None %3 225fd4e5da5Sopenharmony_ci %5 = OpLabel 226fd4e5da5Sopenharmony_ci OpSelectionMerge %13 None 227fd4e5da5Sopenharmony_ci OpBranchConditional %11 %12 %13 228fd4e5da5Sopenharmony_ci %12 = OpLabel 229fd4e5da5Sopenharmony_ci OpBranch %13 230fd4e5da5Sopenharmony_ci %13 = OpLabel 231fd4e5da5Sopenharmony_ci %101 = OpPhi %10 %11 %5 %11 %12 232fd4e5da5Sopenharmony_ci OpReturn 233fd4e5da5Sopenharmony_ci OpFunctionEnd 234fd4e5da5Sopenharmony_ci )"; 235fd4e5da5Sopenharmony_ci 236fd4e5da5Sopenharmony_ci const auto env = SPV_ENV_UNIVERSAL_1_3; 237fd4e5da5Sopenharmony_ci const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption); 238fd4e5da5Sopenharmony_ci const auto ops = StructuredConstructToBlockReductionOpportunityFinder() 239fd4e5da5Sopenharmony_ci .GetAvailableOpportunities(context.get(), 0); 240fd4e5da5Sopenharmony_ci ASSERT_TRUE(ops.empty()); 241fd4e5da5Sopenharmony_ci} 242fd4e5da5Sopenharmony_ci 243fd4e5da5Sopenharmony_ci} // namespace 244fd4e5da5Sopenharmony_ci} // namespace reduce 245fd4e5da5Sopenharmony_ci} // namespace spvtools 246