1// Copyright (c) 2021 Alastair F. Donaldson 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15#include "source/reduce/structured_construct_to_block_reduction_opportunity_finder.h" 16 17#include "source/opt/build_module.h" 18#include "source/reduce/reduction_opportunity.h" 19#include "test/reduce/reduce_test_util.h" 20 21namespace spvtools { 22namespace reduce { 23namespace { 24 25TEST(StructuredConstructToBlockReductionPassTest, SimpleTest) { 26 std::string shader = R"( 27 OpCapability Shader 28 %1 = OpExtInstImport "GLSL.std.450" 29 OpMemoryModel Logical GLSL450 30 OpEntryPoint Fragment %4 "main" 31 OpExecutionMode %4 OriginUpperLeft 32 OpSource ESSL 320 33 %2 = OpTypeVoid 34 %3 = OpTypeFunction %2 35 %6 = OpTypeInt 32 1 36 %7 = OpTypePointer Function %6 37 %9 = OpConstant %6 0 38 %10 = OpTypeBool 39 %11 = OpConstantTrue %10 40 %19 = OpConstant %6 3 41 %29 = OpConstant %6 1 42 %31 = OpConstant %6 2 43 %4 = OpFunction %2 None %3 44 %5 = OpLabel 45 %8 = OpVariable %7 Function 46 OpStore %8 %9 47 OpSelectionMerge %13 None 48 OpBranchConditional %11 %12 %13 49 %12 = OpLabel 50 OpBranch %13 51 %13 = OpLabel 52 OpBranch %14 53 %14 = OpLabel 54 OpLoopMerge %16 %17 None 55 OpBranch %15 56 %15 = OpLabel 57 %18 = OpLoad %6 %8 58 %20 = OpSGreaterThan %10 %18 %19 59 OpSelectionMerge %22 None 60 OpBranchConditional %20 %21 %22 61 %21 = OpLabel 62 OpBranch %16 63 %22 = OpLabel 64 OpBranch %17 65 %17 = OpLabel 66 OpBranch %14 67 %16 = OpLabel 68 %24 = OpLoad %6 %8 69 OpSelectionMerge %28 None 70 OpSwitch %24 %27 1 %25 2 %26 71 %27 = OpLabel 72 OpStore %8 %19 73 OpBranch %28 74 %25 = OpLabel 75 OpStore %8 %29 76 OpBranch %28 77 %26 = OpLabel 78 OpStore %8 %31 79 OpBranch %28 80 %28 = OpLabel 81 OpReturn 82 OpFunctionEnd 83 )"; 84 85 const auto env = SPV_ENV_UNIVERSAL_1_3; 86 const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption); 87 const auto ops = StructuredConstructToBlockReductionOpportunityFinder() 88 .GetAvailableOpportunities(context.get(), 0); 89 ASSERT_EQ(3, ops.size()); 90 91 ASSERT_TRUE(ops[0]->PreconditionHolds()); 92 ops[0]->TryToApply(); 93 CheckValid(env, context.get()); 94 95 ASSERT_TRUE(ops[1]->PreconditionHolds()); 96 ops[1]->TryToApply(); 97 CheckValid(env, context.get()); 98 99 ASSERT_TRUE(ops[2]->PreconditionHolds()); 100 ops[2]->TryToApply(); 101 CheckValid(env, context.get()); 102 103 std::string expected = R"( 104 OpCapability Shader 105 %1 = OpExtInstImport "GLSL.std.450" 106 OpMemoryModel Logical GLSL450 107 OpEntryPoint Fragment %4 "main" 108 OpExecutionMode %4 OriginUpperLeft 109 OpSource ESSL 320 110 %2 = OpTypeVoid 111 %3 = OpTypeFunction %2 112 %6 = OpTypeInt 32 1 113 %7 = OpTypePointer Function %6 114 %9 = OpConstant %6 0 115 %10 = OpTypeBool 116 %11 = OpConstantTrue %10 117 %19 = OpConstant %6 3 118 %29 = OpConstant %6 1 119 %31 = OpConstant %6 2 120 %4 = OpFunction %2 None %3 121 %5 = OpLabel 122 %8 = OpVariable %7 Function 123 OpStore %8 %9 124 OpBranch %13 125 %13 = OpLabel 126 OpBranch %14 127 %14 = OpLabel 128 OpBranch %16 129 %16 = OpLabel 130 %24 = OpLoad %6 %8 131 OpBranch %28 132 %28 = OpLabel 133 OpReturn 134 OpFunctionEnd 135 )"; 136 CheckEqual(env, expected, context.get()); 137} 138 139TEST(StructuredConstructToBlockReductionPassTest, CannotBeRemovedDueToUses) { 140 std::string shader = R"( 141 OpCapability Shader 142 %1 = OpExtInstImport "GLSL.std.450" 143 OpMemoryModel Logical GLSL450 144 OpEntryPoint Fragment %4 "main" 145 OpExecutionMode %4 OriginUpperLeft 146 OpSource ESSL 320 147 OpName %100 "temp" 148 %2 = OpTypeVoid 149 %3 = OpTypeFunction %2 150 %6 = OpTypeInt 32 1 151 %7 = OpTypePointer Function %6 152 %9 = OpConstant %6 0 153 %10 = OpTypeBool 154 %11 = OpConstantTrue %10 155 %19 = OpConstant %6 3 156 %29 = OpConstant %6 1 157 %31 = OpConstant %6 2 158 %4 = OpFunction %2 None %3 159 %5 = OpLabel 160 %8 = OpVariable %7 Function 161 OpStore %8 %9 162 OpSelectionMerge %13 None 163 OpBranchConditional %11 %12 %13 164 %12 = OpLabel 165 %100 = OpCopyObject %10 %11 166 OpBranch %13 167 %13 = OpLabel 168 OpBranch %14 169 %14 = OpLabel 170 OpLoopMerge %16 %17 None 171 OpBranch %15 172 %15 = OpLabel 173 %18 = OpLoad %6 %8 174 %20 = OpSGreaterThan %10 %18 %19 175 OpSelectionMerge %22 None 176 OpBranchConditional %20 %21 %22 177 %21 = OpLabel 178 OpBranch %16 179 %22 = OpLabel 180 OpBranch %17 181 %17 = OpLabel 182 OpBranch %14 183 %16 = OpLabel 184 %101 = OpCopyObject %6 %18 185 %24 = OpLoad %6 %8 186 OpSelectionMerge %28 None 187 OpSwitch %24 %27 1 %25 2 %26 188 %27 = OpLabel 189 OpStore %8 %19 190 %102 = OpCopyObject %10 %11 191 OpBranch %28 192 %25 = OpLabel 193 OpStore %8 %29 194 OpBranch %28 195 %26 = OpLabel 196 OpStore %8 %31 197 OpBranch %28 198 %28 = OpLabel 199 %103 = OpPhi %10 %102 %27 %11 %25 %11 %26 200 OpReturn 201 OpFunctionEnd 202 )"; 203 204 const auto env = SPV_ENV_UNIVERSAL_1_3; 205 const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption); 206 const auto ops = StructuredConstructToBlockReductionOpportunityFinder() 207 .GetAvailableOpportunities(context.get(), 0); 208 ASSERT_TRUE(ops.empty()); 209} 210 211TEST(StructuredConstructToBlockReductionPassTest, 212 CannotBeRemovedDueToOpPhiAtMerge) { 213 std::string shader = R"( 214 OpCapability Shader 215 %1 = OpExtInstImport "GLSL.std.450" 216 OpMemoryModel Logical GLSL450 217 OpEntryPoint Fragment %4 "main" 218 OpExecutionMode %4 OriginUpperLeft 219 OpSource ESSL 320 220 %2 = OpTypeVoid 221 %3 = OpTypeFunction %2 222 %10 = OpTypeBool 223 %11 = OpConstantTrue %10 224 %4 = OpFunction %2 None %3 225 %5 = OpLabel 226 OpSelectionMerge %13 None 227 OpBranchConditional %11 %12 %13 228 %12 = OpLabel 229 OpBranch %13 230 %13 = OpLabel 231 %101 = OpPhi %10 %11 %5 %11 %12 232 OpReturn 233 OpFunctionEnd 234 )"; 235 236 const auto env = SPV_ENV_UNIVERSAL_1_3; 237 const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption); 238 const auto ops = StructuredConstructToBlockReductionOpportunityFinder() 239 .GetAvailableOpportunities(context.get(), 0); 240 ASSERT_TRUE(ops.empty()); 241} 242 243} // namespace 244} // namespace reduce 245} // namespace spvtools 246