1 // Copyright (c) 2017 Google Inc.
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 <memory>
16 #include <vector>
17
18 #include "gmock/gmock.h"
19 #include "source/opt/dominator_analysis.h"
20 #include "source/opt/pass.h"
21 #include "test/opt/assembly_builder.h"
22 #include "test/opt/function_utils.h"
23 #include "test/opt/pass_fixture.h"
24 #include "test/opt/pass_utils.h"
25
26 namespace spvtools {
27 namespace opt {
28 namespace {
29
30 using ::testing::UnorderedElementsAre;
31 using PassClassTest = PassTest<::testing::Test>;
32
33 /*
34 Generated from the following GLSL
35 #version 440 core
36 layout(location = 0) out vec4 v;
37 layout(location = 1) in vec4 in_val;
38 void main() {
39 for (int i = 0; i < in_val.x; ++i) {
40 for (int j = 0; j < in_val.y; j++) {
41 }
42 }
43 for (int i = 0; i < in_val.x; ++i) {
44 for (int j = 0; j < in_val.y; j++) {
45 }
46 if (in_val.z == in_val.w) {
47 break;
48 }
49 }
50 int i = 0;
51 while (i < in_val.x) {
52 ++i;
53 for (int j = 0; j < 1; j++) {
54 for (int k = 0; k < 1; k++) {
55 }
56 }
57 }
58 i = 0;
59 while (i < in_val.x) {
60 ++i;
61 if (in_val.z == in_val.w) {
62 continue;
63 }
64 for (int j = 0; j < 1; j++) {
65 for (int k = 0; k < 1; k++) {
66 }
67 if (in_val.z == in_val.w) {
68 break;
69 }
70 }
71 }
72 v = vec4(1,1,1,1);
73 }
74 */
TEST_F(PassClassTest, BasicVisitFromEntryPoint)75 TEST_F(PassClassTest, BasicVisitFromEntryPoint) {
76 const std::string text = R"(
77 OpCapability Shader
78 %1 = OpExtInstImport "GLSL.std.450"
79 OpMemoryModel Logical GLSL450
80 OpEntryPoint Fragment %4 "main" %20 %163
81 OpExecutionMode %4 OriginUpperLeft
82 OpSource GLSL 440
83 OpName %4 "main"
84 OpName %8 "i"
85 OpName %20 "in_val"
86 OpName %28 "j"
87 OpName %45 "i"
88 OpName %56 "j"
89 OpName %81 "i"
90 OpName %94 "j"
91 OpName %102 "k"
92 OpName %134 "j"
93 OpName %142 "k"
94 OpName %163 "v"
95 OpDecorate %20 Location 1
96 OpDecorate %163 Location 0
97 %2 = OpTypeVoid
98 %3 = OpTypeFunction %2
99 %6 = OpTypeInt 32 1
100 %7 = OpTypePointer Function %6
101 %9 = OpConstant %6 0
102 %16 = OpTypeFloat 32
103 %18 = OpTypeVector %16 4
104 %19 = OpTypePointer Input %18
105 %20 = OpVariable %19 Input
106 %21 = OpTypeInt 32 0
107 %22 = OpConstant %21 0
108 %23 = OpTypePointer Input %16
109 %26 = OpTypeBool
110 %36 = OpConstant %21 1
111 %41 = OpConstant %6 1
112 %69 = OpConstant %21 2
113 %72 = OpConstant %21 3
114 %162 = OpTypePointer Output %18
115 %163 = OpVariable %162 Output
116 %164 = OpConstant %16 1
117 %165 = OpConstantComposite %18 %164 %164 %164 %164
118 %4 = OpFunction %2 None %3
119 %5 = OpLabel
120 %8 = OpVariable %7 Function
121 %28 = OpVariable %7 Function
122 %45 = OpVariable %7 Function
123 %56 = OpVariable %7 Function
124 %81 = OpVariable %7 Function
125 %94 = OpVariable %7 Function
126 %102 = OpVariable %7 Function
127 %134 = OpVariable %7 Function
128 %142 = OpVariable %7 Function
129 OpStore %8 %9
130 OpBranch %10
131 %10 = OpLabel
132 OpLoopMerge %12 %13 None
133 OpBranch %14
134 %14 = OpLabel
135 %15 = OpLoad %6 %8
136 %17 = OpConvertSToF %16 %15
137 %24 = OpAccessChain %23 %20 %22
138 %25 = OpLoad %16 %24
139 %27 = OpFOrdLessThan %26 %17 %25
140 OpBranchConditional %27 %11 %12
141 %11 = OpLabel
142 OpStore %28 %9
143 OpBranch %29
144 %29 = OpLabel
145 OpLoopMerge %31 %32 None
146 OpBranch %33
147 %33 = OpLabel
148 %34 = OpLoad %6 %28
149 %35 = OpConvertSToF %16 %34
150 %37 = OpAccessChain %23 %20 %36
151 %38 = OpLoad %16 %37
152 %39 = OpFOrdLessThan %26 %35 %38
153 OpBranchConditional %39 %30 %31
154 %30 = OpLabel
155 OpBranch %32
156 %32 = OpLabel
157 %40 = OpLoad %6 %28
158 %42 = OpIAdd %6 %40 %41
159 OpStore %28 %42
160 OpBranch %29
161 %31 = OpLabel
162 OpBranch %13
163 %13 = OpLabel
164 %43 = OpLoad %6 %8
165 %44 = OpIAdd %6 %43 %41
166 OpStore %8 %44
167 OpBranch %10
168 %12 = OpLabel
169 OpStore %45 %9
170 OpBranch %46
171 %46 = OpLabel
172 OpLoopMerge %48 %49 None
173 OpBranch %50
174 %50 = OpLabel
175 %51 = OpLoad %6 %45
176 %52 = OpConvertSToF %16 %51
177 %53 = OpAccessChain %23 %20 %22
178 %54 = OpLoad %16 %53
179 %55 = OpFOrdLessThan %26 %52 %54
180 OpBranchConditional %55 %47 %48
181 %47 = OpLabel
182 OpStore %56 %9
183 OpBranch %57
184 %57 = OpLabel
185 OpLoopMerge %59 %60 None
186 OpBranch %61
187 %61 = OpLabel
188 %62 = OpLoad %6 %56
189 %63 = OpConvertSToF %16 %62
190 %64 = OpAccessChain %23 %20 %36
191 %65 = OpLoad %16 %64
192 %66 = OpFOrdLessThan %26 %63 %65
193 OpBranchConditional %66 %58 %59
194 %58 = OpLabel
195 OpBranch %60
196 %60 = OpLabel
197 %67 = OpLoad %6 %56
198 %68 = OpIAdd %6 %67 %41
199 OpStore %56 %68
200 OpBranch %57
201 %59 = OpLabel
202 %70 = OpAccessChain %23 %20 %69
203 %71 = OpLoad %16 %70
204 %73 = OpAccessChain %23 %20 %72
205 %74 = OpLoad %16 %73
206 %75 = OpFOrdEqual %26 %71 %74
207 OpSelectionMerge %77 None
208 OpBranchConditional %75 %76 %77
209 %76 = OpLabel
210 OpBranch %48
211 %77 = OpLabel
212 OpBranch %49
213 %49 = OpLabel
214 %79 = OpLoad %6 %45
215 %80 = OpIAdd %6 %79 %41
216 OpStore %45 %80
217 OpBranch %46
218 %48 = OpLabel
219 OpStore %81 %9
220 OpBranch %82
221 %82 = OpLabel
222 OpLoopMerge %84 %85 None
223 OpBranch %86
224 %86 = OpLabel
225 %87 = OpLoad %6 %81
226 %88 = OpConvertSToF %16 %87
227 %89 = OpAccessChain %23 %20 %22
228 %90 = OpLoad %16 %89
229 %91 = OpFOrdLessThan %26 %88 %90
230 OpBranchConditional %91 %83 %84
231 %83 = OpLabel
232 %92 = OpLoad %6 %81
233 %93 = OpIAdd %6 %92 %41
234 OpStore %81 %93
235 OpStore %94 %9
236 OpBranch %95
237 %95 = OpLabel
238 OpLoopMerge %97 %98 None
239 OpBranch %99
240 %99 = OpLabel
241 %100 = OpLoad %6 %94
242 %101 = OpSLessThan %26 %100 %41
243 OpBranchConditional %101 %96 %97
244 %96 = OpLabel
245 OpStore %102 %9
246 OpBranch %103
247 %103 = OpLabel
248 OpLoopMerge %105 %106 None
249 OpBranch %107
250 %107 = OpLabel
251 %108 = OpLoad %6 %102
252 %109 = OpSLessThan %26 %108 %41
253 OpBranchConditional %109 %104 %105
254 %104 = OpLabel
255 OpBranch %106
256 %106 = OpLabel
257 %110 = OpLoad %6 %102
258 %111 = OpIAdd %6 %110 %41
259 OpStore %102 %111
260 OpBranch %103
261 %105 = OpLabel
262 OpBranch %98
263 %98 = OpLabel
264 %112 = OpLoad %6 %94
265 %113 = OpIAdd %6 %112 %41
266 OpStore %94 %113
267 OpBranch %95
268 %97 = OpLabel
269 OpBranch %85
270 %85 = OpLabel
271 OpBranch %82
272 %84 = OpLabel
273 OpStore %81 %9
274 OpBranch %114
275 %114 = OpLabel
276 OpLoopMerge %116 %117 None
277 OpBranch %118
278 %118 = OpLabel
279 %119 = OpLoad %6 %81
280 %120 = OpConvertSToF %16 %119
281 %121 = OpAccessChain %23 %20 %22
282 %122 = OpLoad %16 %121
283 %123 = OpFOrdLessThan %26 %120 %122
284 OpBranchConditional %123 %115 %116
285 %115 = OpLabel
286 %124 = OpLoad %6 %81
287 %125 = OpIAdd %6 %124 %41
288 OpStore %81 %125
289 %126 = OpAccessChain %23 %20 %69
290 %127 = OpLoad %16 %126
291 %128 = OpAccessChain %23 %20 %72
292 %129 = OpLoad %16 %128
293 %130 = OpFOrdEqual %26 %127 %129
294 OpSelectionMerge %132 None
295 OpBranchConditional %130 %131 %132
296 %131 = OpLabel
297 OpBranch %117
298 %132 = OpLabel
299 OpStore %134 %9
300 OpBranch %135
301 %135 = OpLabel
302 OpLoopMerge %137 %138 None
303 OpBranch %139
304 %139 = OpLabel
305 %140 = OpLoad %6 %134
306 %141 = OpSLessThan %26 %140 %41
307 OpBranchConditional %141 %136 %137
308 %136 = OpLabel
309 OpStore %142 %9
310 OpBranch %143
311 %143 = OpLabel
312 OpLoopMerge %145 %146 None
313 OpBranch %147
314 %147 = OpLabel
315 %148 = OpLoad %6 %142
316 %149 = OpSLessThan %26 %148 %41
317 OpBranchConditional %149 %144 %145
318 %144 = OpLabel
319 OpBranch %146
320 %146 = OpLabel
321 %150 = OpLoad %6 %142
322 %151 = OpIAdd %6 %150 %41
323 OpStore %142 %151
324 OpBranch %143
325 %145 = OpLabel
326 %152 = OpAccessChain %23 %20 %69
327 %153 = OpLoad %16 %152
328 %154 = OpAccessChain %23 %20 %72
329 %155 = OpLoad %16 %154
330 %156 = OpFOrdEqual %26 %153 %155
331 OpSelectionMerge %158 None
332 OpBranchConditional %156 %157 %158
333 %157 = OpLabel
334 OpBranch %137
335 %158 = OpLabel
336 OpBranch %138
337 %138 = OpLabel
338 %160 = OpLoad %6 %134
339 %161 = OpIAdd %6 %160 %41
340 OpStore %134 %161
341 OpBranch %135
342 %137 = OpLabel
343 OpBranch %117
344 %117 = OpLabel
345 OpBranch %114
346 %116 = OpLabel
347 OpStore %163 %165
348 OpReturn
349 OpFunctionEnd
350 )";
351 // clang-format on
352 std::unique_ptr<IRContext> context =
353 BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
354 SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
355 Module* module = context->module();
356 EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
357 << text << std::endl;
358
359 const Function* f = spvtest::GetFunction(module, 4);
360 DominatorAnalysis* analysis = context->GetDominatorAnalysis(f);
361
362 EXPECT_TRUE(analysis->Dominates(5, 10));
363 EXPECT_TRUE(analysis->Dominates(5, 46));
364 EXPECT_TRUE(analysis->Dominates(5, 82));
365 EXPECT_TRUE(analysis->Dominates(5, 114));
366 EXPECT_TRUE(analysis->Dominates(5, 116));
367
368 EXPECT_TRUE(analysis->Dominates(10, 14));
369 EXPECT_TRUE(analysis->Dominates(10, 11));
370 EXPECT_TRUE(analysis->Dominates(10, 29));
371 EXPECT_TRUE(analysis->Dominates(10, 33));
372 EXPECT_TRUE(analysis->Dominates(10, 30));
373 EXPECT_TRUE(analysis->Dominates(10, 32));
374 EXPECT_TRUE(analysis->Dominates(10, 31));
375 EXPECT_TRUE(analysis->Dominates(10, 13));
376 EXPECT_TRUE(analysis->Dominates(10, 12));
377
378 EXPECT_TRUE(analysis->Dominates(12, 46));
379
380 EXPECT_TRUE(analysis->Dominates(46, 50));
381 EXPECT_TRUE(analysis->Dominates(46, 47));
382 EXPECT_TRUE(analysis->Dominates(46, 57));
383 EXPECT_TRUE(analysis->Dominates(46, 61));
384 EXPECT_TRUE(analysis->Dominates(46, 58));
385 EXPECT_TRUE(analysis->Dominates(46, 60));
386 EXPECT_TRUE(analysis->Dominates(46, 59));
387 EXPECT_TRUE(analysis->Dominates(46, 77));
388 EXPECT_TRUE(analysis->Dominates(46, 49));
389 EXPECT_TRUE(analysis->Dominates(46, 76));
390 EXPECT_TRUE(analysis->Dominates(46, 48));
391
392 EXPECT_TRUE(analysis->Dominates(48, 82));
393
394 EXPECT_TRUE(analysis->Dominates(82, 86));
395 EXPECT_TRUE(analysis->Dominates(82, 83));
396 EXPECT_TRUE(analysis->Dominates(82, 95));
397 EXPECT_TRUE(analysis->Dominates(82, 99));
398 EXPECT_TRUE(analysis->Dominates(82, 96));
399 EXPECT_TRUE(analysis->Dominates(82, 103));
400 EXPECT_TRUE(analysis->Dominates(82, 107));
401 EXPECT_TRUE(analysis->Dominates(82, 104));
402 EXPECT_TRUE(analysis->Dominates(82, 106));
403 EXPECT_TRUE(analysis->Dominates(82, 105));
404 EXPECT_TRUE(analysis->Dominates(82, 98));
405 EXPECT_TRUE(analysis->Dominates(82, 97));
406 EXPECT_TRUE(analysis->Dominates(82, 85));
407 EXPECT_TRUE(analysis->Dominates(82, 84));
408
409 EXPECT_TRUE(analysis->Dominates(84, 114));
410
411 EXPECT_TRUE(analysis->Dominates(114, 118));
412 EXPECT_TRUE(analysis->Dominates(114, 116));
413 EXPECT_TRUE(analysis->Dominates(114, 115));
414 EXPECT_TRUE(analysis->Dominates(114, 132));
415 EXPECT_TRUE(analysis->Dominates(114, 135));
416 EXPECT_TRUE(analysis->Dominates(114, 139));
417 EXPECT_TRUE(analysis->Dominates(114, 136));
418 EXPECT_TRUE(analysis->Dominates(114, 143));
419 EXPECT_TRUE(analysis->Dominates(114, 147));
420 EXPECT_TRUE(analysis->Dominates(114, 144));
421 EXPECT_TRUE(analysis->Dominates(114, 146));
422 EXPECT_TRUE(analysis->Dominates(114, 145));
423 EXPECT_TRUE(analysis->Dominates(114, 158));
424 EXPECT_TRUE(analysis->Dominates(114, 138));
425 EXPECT_TRUE(analysis->Dominates(114, 137));
426 EXPECT_TRUE(analysis->Dominates(114, 131));
427 EXPECT_TRUE(analysis->Dominates(114, 117));
428 }
429
430 } // namespace
431 } // namespace opt
432 } // namespace spvtools
433