• 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 <algorithm>
16 #include <cstdarg>
17 #include <iostream>
18 #include <sstream>
19 #include <string>
20 #include <unordered_set>
21 
22 #include "gmock/gmock.h"
23 #include "test/opt/assembly_builder.h"
24 #include "test/opt/pass_fixture.h"
25 #include "test/opt/pass_utils.h"
26 
27 namespace spvtools {
28 namespace opt {
29 namespace {
30 
31 using Workaround1209Test = PassTest<::testing::Test>;
32 
TEST_F(Workaround1209Test,RemoveOpUnreachableInLoop)33 TEST_F(Workaround1209Test, RemoveOpUnreachableInLoop) {
34   const std::string text = R"(
35                OpCapability Shader
36           %1 = OpExtInstImport "GLSL.std.450"
37                OpMemoryModel Logical GLSL450
38                OpEntryPoint Vertex %main "main" %texcoord %gl_VertexIndex %_
39                OpSource GLSL 400
40                OpSourceExtension "GL_ARB_separate_shader_objects"
41                OpSourceExtension "GL_ARB_shading_language_420pack"
42                OpName %main "main"
43                OpName %texcoord "texcoord"
44                OpName %buf "buf"
45                OpMemberName %buf 0 "MVP"
46                OpMemberName %buf 1 "position"
47                OpMemberName %buf 2 "attr"
48                OpName %ubuf "ubuf"
49                OpName %gl_VertexIndex "gl_VertexIndex"
50                OpName %gl_PerVertex "gl_PerVertex"
51                OpMemberName %gl_PerVertex 0 "gl_Position"
52                OpName %_ ""
53                OpDecorate %texcoord Location 0
54                OpDecorate %_arr_v4float_uint_72 ArrayStride 16
55                OpDecorate %_arr_v4float_uint_72_0 ArrayStride 16
56                OpMemberDecorate %buf 0 ColMajor
57                OpMemberDecorate %buf 0 Offset 0
58                OpMemberDecorate %buf 0 MatrixStride 16
59                OpMemberDecorate %buf 1 Offset 64
60                OpMemberDecorate %buf 2 Offset 1216
61                OpDecorate %buf Block
62                OpDecorate %ubuf DescriptorSet 0
63                OpDecorate %ubuf Binding 0
64                OpDecorate %gl_VertexIndex BuiltIn VertexIndex
65                OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
66                OpDecorate %gl_PerVertex Block
67        %void = OpTypeVoid
68          %12 = OpTypeFunction %void
69       %float = OpTypeFloat 32
70     %v4float = OpTypeVector %float 4
71 %_ptr_Output_v4float = OpTypePointer Output %v4float
72    %texcoord = OpVariable %_ptr_Output_v4float Output
73 %mat4v4float = OpTypeMatrix %v4float 4
74        %uint = OpTypeInt 32 0
75     %uint_72 = OpConstant %uint 72
76 %_arr_v4float_uint_72 = OpTypeArray %v4float %uint_72
77 %_arr_v4float_uint_72_0 = OpTypeArray %v4float %uint_72
78         %buf = OpTypeStruct %mat4v4float %_arr_v4float_uint_72 %_arr_v4float_uint_72_0
79 %_ptr_Uniform_buf = OpTypePointer Uniform %buf
80        %ubuf = OpVariable %_ptr_Uniform_buf Uniform
81         %int = OpTypeInt 32 1
82       %int_2 = OpConstant %int 2
83 %_ptr_Input_int = OpTypePointer Input %int
84 %gl_VertexIndex = OpVariable %_ptr_Input_int Input
85 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
86 %gl_PerVertex = OpTypeStruct %v4float
87 %_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
88           %_ = OpVariable %_ptr_Output_gl_PerVertex Output
89       %int_0 = OpConstant %int 0
90       %int_1 = OpConstant %int 1
91     %float_1 = OpConstant %float 1
92          %28 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
93        %main = OpFunction %void None %12
94          %29 = OpLabel
95                OpBranch %30
96          %30 = OpLabel
97 ; CHECK: OpLoopMerge [[merge:%[a-zA-Z_\d]+]]
98                OpLoopMerge %31 %32 None
99                OpBranch %33
100          %33 = OpLabel
101 ; CHECK: OpSelectionMerge [[sel_merge:%[a-zA-Z_\d]+]]
102                OpSelectionMerge %34 None
103                OpSwitch %int_1 %35
104          %35 = OpLabel
105          %36 = OpLoad %int %gl_VertexIndex
106          %37 = OpAccessChain %_ptr_Uniform_v4float %ubuf %int_2 %36
107          %38 = OpLoad %v4float %37
108                OpStore %texcoord %38
109          %39 = OpAccessChain %_ptr_Output_v4float %_ %int_0
110                OpStore %39 %28
111                OpBranch %31
112 ; CHECK: [[sel_merge]] = OpLabel
113          %34 = OpLabel
114 ; CHECK-NEXT: OpBranch [[merge]]
115                OpUnreachable
116          %32 = OpLabel
117                OpBranch %30
118          %31 = OpLabel
119                OpReturn
120                OpFunctionEnd)";
121 
122   SinglePassRunAndMatch<Workaround1209>(text, false);
123 }
124 
TEST_F(Workaround1209Test,RemoveOpUnreachableInNestedLoop)125 TEST_F(Workaround1209Test, RemoveOpUnreachableInNestedLoop) {
126   const std::string text = R"(
127                OpCapability Shader
128           %1 = OpExtInstImport "GLSL.std.450"
129                OpMemoryModel Logical GLSL450
130                OpEntryPoint Vertex %2 "main" %3 %4 %5
131                OpSource GLSL 400
132                OpSourceExtension "GL_ARB_separate_shader_objects"
133                OpSourceExtension "GL_ARB_shading_language_420pack"
134                OpName %2 "main"
135                OpName %3 "texcoord"
136                OpName %6 "buf"
137                OpMemberName %6 0 "MVP"
138                OpMemberName %6 1 "position"
139                OpMemberName %6 2 "attr"
140                OpName %7 "ubuf"
141                OpName %4 "gl_VertexIndex"
142                OpName %8 "gl_PerVertex"
143                OpMemberName %8 0 "gl_Position"
144                OpName %5 ""
145                OpDecorate %3 Location 0
146                OpDecorate %9 ArrayStride 16
147                OpDecorate %10 ArrayStride 16
148                OpMemberDecorate %6 0 ColMajor
149                OpMemberDecorate %6 0 Offset 0
150                OpMemberDecorate %6 0 MatrixStride 16
151                OpMemberDecorate %6 1 Offset 64
152                OpMemberDecorate %6 2 Offset 1216
153                OpDecorate %6 Block
154                OpDecorate %7 DescriptorSet 0
155                OpDecorate %7 Binding 0
156                OpDecorate %4 BuiltIn VertexIndex
157                OpMemberDecorate %8 0 BuiltIn Position
158                OpDecorate %8 Block
159          %11 = OpTypeVoid
160          %12 = OpTypeFunction %11
161          %13 = OpTypeFloat 32
162          %14 = OpTypeVector %13 4
163          %15 = OpTypePointer Output %14
164           %3 = OpVariable %15 Output
165          %16 = OpTypeMatrix %14 4
166          %17 = OpTypeInt 32 0
167          %18 = OpConstant %17 72
168           %9 = OpTypeArray %14 %18
169          %10 = OpTypeArray %14 %18
170           %6 = OpTypeStruct %16 %9 %10
171          %19 = OpTypePointer Uniform %6
172           %7 = OpVariable %19 Uniform
173          %20 = OpTypeInt 32 1
174          %21 = OpConstant %20 2
175          %22 = OpTypePointer Input %20
176           %4 = OpVariable %22 Input
177          %23 = OpTypePointer Uniform %14
178           %8 = OpTypeStruct %14
179          %24 = OpTypePointer Output %8
180           %5 = OpVariable %24 Output
181          %25 = OpConstant %20 0
182          %26 = OpConstant %20 1
183          %27 = OpConstant %13 1
184          %28 = OpConstantComposite %14 %27 %27 %27 %27
185           %2 = OpFunction %11 None %12
186          %29 = OpLabel
187                OpBranch %31
188          %31 = OpLabel
189 ; CHECK: OpLoopMerge
190                OpLoopMerge %32 %33 None
191                OpBranch %30
192          %30 = OpLabel
193 ; CHECK: OpLoopMerge [[merge:%[a-zA-Z_\d]+]]
194                OpLoopMerge %34 %35 None
195                OpBranch %36
196          %36 = OpLabel
197 ; CHECK: OpSelectionMerge [[sel_merge:%[a-zA-Z_\d]+]]
198                OpSelectionMerge %37 None
199                OpSwitch %26 %38
200          %38 = OpLabel
201          %39 = OpLoad %20 %4
202          %40 = OpAccessChain %23 %7 %21 %39
203          %41 = OpLoad %14 %40
204                OpStore %3 %41
205          %42 = OpAccessChain %15 %5 %25
206                OpStore %42 %28
207                OpBranch %34
208 ; CHECK: [[sel_merge]] = OpLabel
209          %37 = OpLabel
210 ; CHECK-NEXT: OpBranch [[merge]]
211                OpUnreachable
212          %35 = OpLabel
213                OpBranch %30
214          %34 = OpLabel
215                OpBranch %32
216          %33 = OpLabel
217                OpBranch %31
218          %32 = OpLabel
219                OpReturn
220                OpFunctionEnd)";
221 
222   SinglePassRunAndMatch<Workaround1209>(text, false);
223 }
224 
TEST_F(Workaround1209Test,RemoveOpUnreachableInAdjacentLoops)225 TEST_F(Workaround1209Test, RemoveOpUnreachableInAdjacentLoops) {
226   const std::string text = R"(
227                OpCapability Shader
228           %1 = OpExtInstImport "GLSL.std.450"
229                OpMemoryModel Logical GLSL450
230                OpEntryPoint Vertex %2 "main" %3 %4 %5
231                OpSource GLSL 400
232                OpSourceExtension "GL_ARB_separate_shader_objects"
233                OpSourceExtension "GL_ARB_shading_language_420pack"
234                OpName %2 "main"
235                OpName %3 "texcoord"
236                OpName %6 "buf"
237                OpMemberName %6 0 "MVP"
238                OpMemberName %6 1 "position"
239                OpMemberName %6 2 "attr"
240                OpName %7 "ubuf"
241                OpName %4 "gl_VertexIndex"
242                OpName %8 "gl_PerVertex"
243                OpMemberName %8 0 "gl_Position"
244                OpName %5 ""
245                OpDecorate %3 Location 0
246                OpDecorate %9 ArrayStride 16
247                OpDecorate %10 ArrayStride 16
248                OpMemberDecorate %6 0 ColMajor
249                OpMemberDecorate %6 0 Offset 0
250                OpMemberDecorate %6 0 MatrixStride 16
251                OpMemberDecorate %6 1 Offset 64
252                OpMemberDecorate %6 2 Offset 1216
253                OpDecorate %6 Block
254                OpDecorate %7 DescriptorSet 0
255                OpDecorate %7 Binding 0
256                OpDecorate %4 BuiltIn VertexIndex
257                OpMemberDecorate %8 0 BuiltIn Position
258                OpDecorate %8 Block
259          %11 = OpTypeVoid
260          %12 = OpTypeFunction %11
261          %13 = OpTypeFloat 32
262          %14 = OpTypeVector %13 4
263          %15 = OpTypePointer Output %14
264           %3 = OpVariable %15 Output
265          %16 = OpTypeMatrix %14 4
266          %17 = OpTypeInt 32 0
267          %18 = OpConstant %17 72
268           %9 = OpTypeArray %14 %18
269          %10 = OpTypeArray %14 %18
270           %6 = OpTypeStruct %16 %9 %10
271          %19 = OpTypePointer Uniform %6
272           %7 = OpVariable %19 Uniform
273          %20 = OpTypeInt 32 1
274          %21 = OpConstant %20 2
275          %22 = OpTypePointer Input %20
276           %4 = OpVariable %22 Input
277          %23 = OpTypePointer Uniform %14
278           %8 = OpTypeStruct %14
279          %24 = OpTypePointer Output %8
280           %5 = OpVariable %24 Output
281          %25 = OpConstant %20 0
282          %26 = OpConstant %20 1
283          %27 = OpConstant %13 1
284          %28 = OpConstantComposite %14 %27 %27 %27 %27
285           %2 = OpFunction %11 None %12
286          %29 = OpLabel
287                OpBranch %30
288          %30 = OpLabel
289 ; CHECK: OpLoopMerge [[merge1:%[a-zA-Z_\d]+]]
290                OpLoopMerge %31 %32 None
291                OpBranch %33
292          %33 = OpLabel
293 ; CHECK: OpSelectionMerge [[sel_merge1:%[a-zA-Z_\d]+]]
294                OpSelectionMerge %34 None
295                OpSwitch %26 %35
296          %35 = OpLabel
297          %36 = OpLoad %20 %4
298          %37 = OpAccessChain %23 %7 %21 %36
299          %38 = OpLoad %14 %37
300                OpStore %3 %38
301          %39 = OpAccessChain %15 %5 %25
302                OpStore %39 %28
303                OpBranch %31
304 ; CHECK: [[sel_merge1]] = OpLabel
305          %34 = OpLabel
306 ; CHECK-NEXT: OpBranch [[merge1]]
307                OpUnreachable
308          %32 = OpLabel
309                OpBranch %30
310          %31 = OpLabel
311 ; CHECK: OpLoopMerge [[merge2:%[a-zA-Z_\d]+]]
312                OpLoopMerge %40 %41 None
313                OpBranch %42
314          %42 = OpLabel
315 ; CHECK: OpSelectionMerge [[sel_merge2:%[a-zA-Z_\d]+]]
316                OpSelectionMerge %43 None
317                OpSwitch %26 %44
318          %44 = OpLabel
319          %45 = OpLoad %20 %4
320          %46 = OpAccessChain %23 %7 %21 %45
321          %47 = OpLoad %14 %46
322                OpStore %3 %47
323          %48 = OpAccessChain %15 %5 %25
324                OpStore %48 %28
325                OpBranch %40
326 ; CHECK: [[sel_merge2]] = OpLabel
327          %43 = OpLabel
328 ; CHECK-NEXT: OpBranch [[merge2]]
329                OpUnreachable
330          %41 = OpLabel
331                OpBranch %31
332          %40 = OpLabel
333                OpReturn
334                OpFunctionEnd)";
335 
336   SinglePassRunAndMatch<Workaround1209>(text, false);
337 }
338 
TEST_F(Workaround1209Test,LeaveUnreachableNotInLoop)339 TEST_F(Workaround1209Test, LeaveUnreachableNotInLoop) {
340   const std::string text = R"(
341                OpCapability Shader
342           %1 = OpExtInstImport "GLSL.std.450"
343                OpMemoryModel Logical GLSL450
344                OpEntryPoint Vertex %main "main" %texcoord %gl_VertexIndex %_
345                OpSource GLSL 400
346                OpSourceExtension "GL_ARB_separate_shader_objects"
347                OpSourceExtension "GL_ARB_shading_language_420pack"
348                OpName %main "main"
349                OpName %texcoord "texcoord"
350                OpName %buf "buf"
351                OpMemberName %buf 0 "MVP"
352                OpMemberName %buf 1 "position"
353                OpMemberName %buf 2 "attr"
354                OpName %ubuf "ubuf"
355                OpName %gl_VertexIndex "gl_VertexIndex"
356                OpName %gl_PerVertex "gl_PerVertex"
357                OpMemberName %gl_PerVertex 0 "gl_Position"
358                OpName %_ ""
359                OpDecorate %texcoord Location 0
360                OpDecorate %_arr_v4float_uint_72 ArrayStride 16
361                OpDecorate %_arr_v4float_uint_72_0 ArrayStride 16
362                OpMemberDecorate %buf 0 ColMajor
363                OpMemberDecorate %buf 0 Offset 0
364                OpMemberDecorate %buf 0 MatrixStride 16
365                OpMemberDecorate %buf 1 Offset 64
366                OpMemberDecorate %buf 2 Offset 1216
367                OpDecorate %buf Block
368                OpDecorate %ubuf DescriptorSet 0
369                OpDecorate %ubuf Binding 0
370                OpDecorate %gl_VertexIndex BuiltIn VertexIndex
371                OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
372                OpDecorate %gl_PerVertex Block
373        %void = OpTypeVoid
374          %12 = OpTypeFunction %void
375       %float = OpTypeFloat 32
376     %v4float = OpTypeVector %float 4
377 %_ptr_Output_v4float = OpTypePointer Output %v4float
378    %texcoord = OpVariable %_ptr_Output_v4float Output
379 %mat4v4float = OpTypeMatrix %v4float 4
380        %uint = OpTypeInt 32 0
381     %uint_72 = OpConstant %uint 72
382 %_arr_v4float_uint_72 = OpTypeArray %v4float %uint_72
383 %_arr_v4float_uint_72_0 = OpTypeArray %v4float %uint_72
384         %buf = OpTypeStruct %mat4v4float %_arr_v4float_uint_72 %_arr_v4float_uint_72_0
385 %_ptr_Uniform_buf = OpTypePointer Uniform %buf
386        %ubuf = OpVariable %_ptr_Uniform_buf Uniform
387         %int = OpTypeInt 32 1
388       %int_2 = OpConstant %int 2
389 %_ptr_Input_int = OpTypePointer Input %int
390 %gl_VertexIndex = OpVariable %_ptr_Input_int Input
391 %_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
392 %gl_PerVertex = OpTypeStruct %v4float
393 %_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
394           %_ = OpVariable %_ptr_Output_gl_PerVertex Output
395       %int_0 = OpConstant %int 0
396       %int_1 = OpConstant %int 1
397     %float_1 = OpConstant %float 1
398          %28 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
399        %main = OpFunction %void None %12
400          %29 = OpLabel
401                OpBranch %30
402          %30 = OpLabel
403                OpSelectionMerge %34 None
404                OpSwitch %int_1 %35
405          %35 = OpLabel
406          %36 = OpLoad %int %gl_VertexIndex
407          %37 = OpAccessChain %_ptr_Uniform_v4float %ubuf %int_2 %36
408          %38 = OpLoad %v4float %37
409                OpStore %texcoord %38
410          %39 = OpAccessChain %_ptr_Output_v4float %_ %int_0
411                OpStore %39 %28
412                OpReturn
413          %34 = OpLabel
414 ; CHECK: OpUnreachable
415                OpUnreachable
416                OpFunctionEnd)";
417 
418   SinglePassRunAndMatch<Workaround1209>(text, false);
419 }
420 
421 }  // namespace
422 }  // namespace opt
423 }  // namespace spvtools
424