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