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
21 namespace spvtools {
22 namespace reduce {
23 namespace {
24
TEST(StructuredConstructToBlockReductionPassTest,SimpleTest)25 TEST(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
TEST(StructuredConstructToBlockReductionPassTest,CannotBeRemovedDueToUses)139 TEST(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
TEST(StructuredConstructToBlockReductionPassTest,CannotBeRemovedDueToOpPhiAtMerge)211 TEST(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