• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <string>
16 
17 #include "test/opt/pass_fixture.h"
18 #include "test/opt/pass_utils.h"
19 
20 namespace spvtools {
21 namespace opt {
22 namespace {
23 
24 using CFGCleanupTest = PassTest<::testing::Test>;
25 
TEST_F(CFGCleanupTest,RemoveUnreachableBlocks)26 TEST_F(CFGCleanupTest, RemoveUnreachableBlocks) {
27   const std::string declarations = R"(OpCapability Shader
28 %1 = OpExtInstImport "GLSL.std.450"
29 OpMemoryModel Logical GLSL450
30 OpEntryPoint Fragment %main "main" %inf %outf4
31 OpExecutionMode %main OriginUpperLeft
32 OpSource GLSL 450
33 OpName %main "main"
34 OpName %inf "inf"
35 OpName %outf4 "outf4"
36 OpDecorate %inf Location 0
37 OpDecorate %outf4 Location 0
38 %void = OpTypeVoid
39 %6 = OpTypeFunction %void
40 %float = OpTypeFloat 32
41 %_ptr_Input_float = OpTypePointer Input %float
42 %inf = OpVariable %_ptr_Input_float Input
43 %float_2 = OpConstant %float 2
44 %bool = OpTypeBool
45 %v4float = OpTypeVector %float 4
46 %_ptr_Output_v4float = OpTypePointer Output %v4float
47 %outf4 = OpVariable %_ptr_Output_v4float Output
48 %float_n0_5 = OpConstant %float -0.5
49 )";
50 
51   const std::string body_before = R"(%main = OpFunction %void None %6
52 %14 = OpLabel
53 OpBranch %18
54 %19 = OpLabel
55 %20 = OpLoad %float %inf
56 %21 = OpCompositeConstruct %v4float %20 %20 %20 %20
57 OpStore %outf4 %21
58 OpBranch %17
59 %18 = OpLabel
60 %22 = OpLoad %float %inf
61 %23 = OpFAdd %float %22 %float_n0_5
62 %24 = OpCompositeConstruct %v4float %23 %23 %23 %23
63 OpStore %outf4 %24
64 OpBranch %17
65 %17 = OpLabel
66 OpReturn
67 OpFunctionEnd
68 )";
69 
70   const std::string body_after = R"(%main = OpFunction %void None %6
71 %14 = OpLabel
72 OpBranch %15
73 %15 = OpLabel
74 %20 = OpLoad %float %inf
75 %21 = OpFAdd %float %20 %float_n0_5
76 %22 = OpCompositeConstruct %v4float %21 %21 %21 %21
77 OpStore %outf4 %22
78 OpBranch %19
79 %19 = OpLabel
80 OpReturn
81 OpFunctionEnd
82 )";
83 
84   SinglePassRunAndCheck<CFGCleanupPass>(declarations + body_before,
85                                         declarations + body_after, true, true);
86 }
87 
TEST_F(CFGCleanupTest,RemoveDecorations)88 TEST_F(CFGCleanupTest, RemoveDecorations) {
89   const std::string before = R"(
90                        OpCapability Shader
91                   %1 = OpExtInstImport "GLSL.std.450"
92                        OpMemoryModel Logical GLSL450
93                        OpEntryPoint Fragment %main "main"
94                        OpExecutionMode %main OriginUpperLeft
95                        OpName %main "main"
96                        OpName %x "x"
97                        OpName %dead "dead"
98                        OpDecorate %x RelaxedPrecision
99                        OpDecorate %dead RelaxedPrecision
100                %void = OpTypeVoid
101                   %6 = OpTypeFunction %void
102               %float = OpTypeFloat 32
103 %_ptr_Function_float = OpTypePointer Function %float
104             %float_2 = OpConstant %float 2
105             %float_4 = OpConstant %float 4
106 
107                %main = OpFunction %void None %6
108                  %14 = OpLabel
109                   %x = OpVariable %_ptr_Function_float Function
110                        OpBranch %18
111                  %19 = OpLabel
112                %dead = OpVariable %_ptr_Function_float Function
113                        OpStore %dead %float_2
114                        OpBranch %17
115                  %18 = OpLabel
116                        OpStore %x %float_4
117                        OpBranch %17
118                  %17 = OpLabel
119                        OpReturn
120                        OpFunctionEnd
121 )";
122 
123   const std::string after = R"(OpCapability Shader
124 %1 = OpExtInstImport "GLSL.std.450"
125 OpMemoryModel Logical GLSL450
126 OpEntryPoint Fragment %main "main"
127 OpExecutionMode %main OriginUpperLeft
128 OpName %main "main"
129 OpName %x "x"
130 OpDecorate %x RelaxedPrecision
131 %void = OpTypeVoid
132 %6 = OpTypeFunction %void
133 %float = OpTypeFloat 32
134 %_ptr_Function_float = OpTypePointer Function %float
135 %float_2 = OpConstant %float 2
136 %float_4 = OpConstant %float 4
137 %main = OpFunction %void None %6
138 %11 = OpLabel
139 %x = OpVariable %_ptr_Function_float Function
140 OpBranch %12
141 %12 = OpLabel
142 OpStore %x %float_4
143 OpBranch %14
144 %14 = OpLabel
145 OpReturn
146 OpFunctionEnd
147 )";
148 
149   SinglePassRunAndCheck<CFGCleanupPass>(before, after, true, true);
150 }
151 
TEST_F(CFGCleanupTest,UpdatePhis)152 TEST_F(CFGCleanupTest, UpdatePhis) {
153   const std::string before = R"(
154                OpCapability Shader
155           %1 = OpExtInstImport "GLSL.std.450"
156                OpMemoryModel Logical GLSL450
157                OpEntryPoint Fragment %main "main" %y %outparm
158                OpExecutionMode %main OriginUpperLeft
159                OpName %main "main"
160                OpName %y "y"
161                OpName %outparm "outparm"
162                OpDecorate %y Flat
163                OpDecorate %y Location 0
164                OpDecorate %outparm Location 0
165        %void = OpTypeVoid
166           %3 = OpTypeFunction %void
167         %int = OpTypeInt 32 1
168 %_ptr_Function_int = OpTypePointer Function %int
169 %_ptr_Input_int = OpTypePointer Input %int
170           %y = OpVariable %_ptr_Input_int Input
171      %int_10 = OpConstant %int 10
172        %bool = OpTypeBool
173      %int_42 = OpConstant %int 42
174      %int_23 = OpConstant %int 23
175       %int_5 = OpConstant %int 5
176 %_ptr_Output_int = OpTypePointer Output %int
177     %outparm = OpVariable %_ptr_Output_int Output
178        %main = OpFunction %void None %3
179           %5 = OpLabel
180          %11 = OpLoad %int %y
181                OpBranch %21
182          %16 = OpLabel
183          %20 = OpIAdd %int %11 %int_42
184                OpBranch %17
185          %21 = OpLabel
186          %24 = OpISub %int %11 %int_23
187                OpBranch %17
188          %17 = OpLabel
189          %31 = OpPhi %int %20 %16 %24 %21
190          %27 = OpIAdd %int %31 %int_5
191                OpStore %outparm %27
192                OpReturn
193                OpFunctionEnd
194 )";
195 
196   const std::string after = R"(OpCapability Shader
197 %1 = OpExtInstImport "GLSL.std.450"
198 OpMemoryModel Logical GLSL450
199 OpEntryPoint Fragment %main "main" %y %outparm
200 OpExecutionMode %main OriginUpperLeft
201 OpName %main "main"
202 OpName %y "y"
203 OpName %outparm "outparm"
204 OpDecorate %y Flat
205 OpDecorate %y Location 0
206 OpDecorate %outparm Location 0
207 %void = OpTypeVoid
208 %6 = OpTypeFunction %void
209 %int = OpTypeInt 32 1
210 %_ptr_Function_int = OpTypePointer Function %int
211 %_ptr_Input_int = OpTypePointer Input %int
212 %y = OpVariable %_ptr_Input_int Input
213 %int_10 = OpConstant %int 10
214 %bool = OpTypeBool
215 %int_42 = OpConstant %int 42
216 %int_23 = OpConstant %int 23
217 %int_5 = OpConstant %int 5
218 %_ptr_Output_int = OpTypePointer Output %int
219 %outparm = OpVariable %_ptr_Output_int Output
220 %main = OpFunction %void None %6
221 %16 = OpLabel
222 %17 = OpLoad %int %y
223 OpBranch %18
224 %18 = OpLabel
225 %22 = OpISub %int %17 %int_23
226 OpBranch %21
227 %21 = OpLabel
228 %23 = OpPhi %int %22 %18
229 %24 = OpIAdd %int %23 %int_5
230 OpStore %outparm %24
231 OpReturn
232 OpFunctionEnd
233 )";
234 
235   SinglePassRunAndCheck<CFGCleanupPass>(before, after, true, true);
236 }
237 
TEST_F(CFGCleanupTest,RemoveNamedLabels)238 TEST_F(CFGCleanupTest, RemoveNamedLabels) {
239   const std::string before = R"(
240                OpCapability Shader
241           %1 = OpExtInstImport "GLSL.std.450"
242                OpMemoryModel Logical GLSL450
243                OpEntryPoint Vertex %main "main"
244                OpSource GLSL 430
245                OpName %main "main"
246                OpName %dead "dead"
247        %void = OpTypeVoid
248           %5 = OpTypeFunction %void
249        %main = OpFunction %void None %5
250           %6 = OpLabel
251                OpReturn
252        %dead = OpLabel
253                OpReturn
254                OpFunctionEnd)";
255 
256   const std::string after = R"(OpCapability Shader
257 %1 = OpExtInstImport "GLSL.std.450"
258 OpMemoryModel Logical GLSL450
259 OpEntryPoint Vertex %main "main"
260 OpSource GLSL 430
261 OpName %main "main"
262 %void = OpTypeVoid
263 %5 = OpTypeFunction %void
264 %main = OpFunction %void None %5
265 %6 = OpLabel
266 OpReturn
267 OpFunctionEnd
268 )";
269 
270   SinglePassRunAndCheck<CFGCleanupPass>(before, after, true, true);
271 }
272 
TEST_F(CFGCleanupTest,RemovePhiArgsFromFarBlocks)273 TEST_F(CFGCleanupTest, RemovePhiArgsFromFarBlocks) {
274   const std::string before = R"(
275                OpCapability Shader
276           %1 = OpExtInstImport "GLSL.std.450"
277                OpMemoryModel Logical GLSL450
278                OpEntryPoint Fragment %main "main" %y %outparm
279                OpExecutionMode %main OriginUpperLeft
280                OpName %main "main"
281                OpName %y "y"
282                OpName %outparm "outparm"
283                OpDecorate %y Flat
284                OpDecorate %y Location 0
285                OpDecorate %outparm Location 0
286        %void = OpTypeVoid
287           %3 = OpTypeFunction %void
288         %int = OpTypeInt 32 1
289 %_ptr_Function_int = OpTypePointer Function %int
290 %_ptr_Input_int = OpTypePointer Input %int
291           %y = OpVariable %_ptr_Input_int Input
292      %int_42 = OpConstant %int 42
293 %_ptr_Output_int = OpTypePointer Output %int
294     %outparm = OpVariable %_ptr_Output_int Output
295      %int_14 = OpConstant %int 14
296      %int_15 = OpConstant %int 15
297       %int_5 = OpConstant %int 5
298        %main = OpFunction %void None %3
299           %5 = OpLabel
300                OpBranch %40
301          %41 = OpLabel
302          %11 = OpLoad %int %y
303                OpBranch %40
304          %40 = OpLabel
305          %12 = OpLoad %int %y
306                OpSelectionMerge %16 None
307                OpSwitch %12 %16 10 %13 13 %14 18 %15
308          %13 = OpLabel
309                OpBranch %16
310          %14 = OpLabel
311                OpStore %outparm %int_14
312                OpBranch %16
313          %15 = OpLabel
314                OpStore %outparm %int_15
315                OpBranch %16
316          %16 = OpLabel
317          %30 = OpPhi %int %11 %40 %int_42 %13 %11 %14 %11 %15
318          %28 = OpIAdd %int %30 %int_5
319                OpStore %outparm %28
320                OpReturn
321                OpFunctionEnd)";
322 
323   const std::string after = R"(OpCapability Shader
324 %1 = OpExtInstImport "GLSL.std.450"
325 OpMemoryModel Logical GLSL450
326 OpEntryPoint Fragment %main "main" %y %outparm
327 OpExecutionMode %main OriginUpperLeft
328 OpName %main "main"
329 OpName %y "y"
330 OpName %outparm "outparm"
331 OpDecorate %y Flat
332 OpDecorate %y Location 0
333 OpDecorate %outparm Location 0
334 %void = OpTypeVoid
335 %6 = OpTypeFunction %void
336 %int = OpTypeInt 32 1
337 %_ptr_Function_int = OpTypePointer Function %int
338 %_ptr_Input_int = OpTypePointer Input %int
339 %y = OpVariable %_ptr_Input_int Input
340 %int_42 = OpConstant %int 42
341 %_ptr_Output_int = OpTypePointer Output %int
342 %outparm = OpVariable %_ptr_Output_int Output
343 %int_14 = OpConstant %int 14
344 %int_15 = OpConstant %int 15
345 %int_5 = OpConstant %int 5
346 %26 = OpUndef %int
347 %main = OpFunction %void None %6
348 %15 = OpLabel
349 OpBranch %16
350 %16 = OpLabel
351 %19 = OpLoad %int %y
352 OpSelectionMerge %20 None
353 OpSwitch %19 %20 10 %21 13 %22 18 %23
354 %21 = OpLabel
355 OpBranch %20
356 %22 = OpLabel
357 OpStore %outparm %int_14
358 OpBranch %20
359 %23 = OpLabel
360 OpStore %outparm %int_15
361 OpBranch %20
362 %20 = OpLabel
363 %24 = OpPhi %int %26 %16 %int_42 %21 %26 %22 %26 %23
364 %25 = OpIAdd %int %24 %int_5
365 OpStore %outparm %25
366 OpReturn
367 OpFunctionEnd
368 )";
369 
370   SinglePassRunAndCheck<CFGCleanupPass>(before, after, true, true);
371 }
372 
TEST_F(CFGCleanupTest,RemovePhiConstantArgs)373 TEST_F(CFGCleanupTest, RemovePhiConstantArgs) {
374   const std::string before = R"(
375                OpCapability Shader
376           %1 = OpExtInstImport "GLSL.std.450"
377                OpMemoryModel Logical GLSL450
378                OpEntryPoint Fragment %main "main" %y %outparm
379                OpExecutionMode %main OriginUpperLeft
380                OpName %main "main"
381                OpName %y "y"
382                OpName %outparm "outparm"
383                OpDecorate %y Flat
384                OpDecorate %y Location 0
385                OpDecorate %outparm Location 0
386        %void = OpTypeVoid
387           %3 = OpTypeFunction %void
388         %int = OpTypeInt 32 1
389 %_ptr_Input_int = OpTypePointer Input %int
390           %y = OpVariable %_ptr_Input_int Input
391      %int_10 = OpConstant %int 10
392        %bool = OpTypeBool
393 %_ptr_Function_int = OpTypePointer Function %int
394      %int_23 = OpConstant %int 23
395       %int_5 = OpConstant %int 5
396 %_ptr_Output_int = OpTypePointer Output %int
397     %outparm = OpVariable %_ptr_Output_int Output
398          %24 = OpUndef %int
399        %main = OpFunction %void None %3
400           %5 = OpLabel
401                OpBranch %14
402          %40 = OpLabel
403           %9 = OpLoad %int %y
404          %12 = OpSGreaterThan %bool %9 %int_10
405                OpSelectionMerge %14 None
406                OpBranchConditional %12 %13 %14
407          %13 = OpLabel
408                OpBranch %14
409          %14 = OpLabel
410          %25 = OpPhi %int %24 %5 %int_23 %13
411          %20 = OpIAdd %int %25 %int_5
412                OpStore %outparm %20
413                OpReturn
414                OpFunctionEnd)";
415 
416   const std::string after = R"(OpCapability Shader
417 %1 = OpExtInstImport "GLSL.std.450"
418 OpMemoryModel Logical GLSL450
419 OpEntryPoint Fragment %main "main" %y %outparm
420 OpExecutionMode %main OriginUpperLeft
421 OpName %main "main"
422 OpName %y "y"
423 OpName %outparm "outparm"
424 OpDecorate %y Flat
425 OpDecorate %y Location 0
426 OpDecorate %outparm Location 0
427 %void = OpTypeVoid
428 %6 = OpTypeFunction %void
429 %int = OpTypeInt 32 1
430 %_ptr_Input_int = OpTypePointer Input %int
431 %y = OpVariable %_ptr_Input_int Input
432 %int_10 = OpConstant %int 10
433 %bool = OpTypeBool
434 %_ptr_Function_int = OpTypePointer Function %int
435 %int_23 = OpConstant %int 23
436 %int_5 = OpConstant %int 5
437 %_ptr_Output_int = OpTypePointer Output %int
438 %outparm = OpVariable %_ptr_Output_int Output
439 %15 = OpUndef %int
440 %main = OpFunction %void None %6
441 %16 = OpLabel
442 OpBranch %17
443 %17 = OpLabel
444 %22 = OpPhi %int %15 %16
445 %23 = OpIAdd %int %22 %int_5
446 OpStore %outparm %23
447 OpReturn
448 OpFunctionEnd
449 )";
450 
451   SinglePassRunAndCheck<CFGCleanupPass>(before, after, true, true);
452 }
453 
454 }  // namespace
455 }  // namespace opt
456 }  // namespace spvtools
457