• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright (c) 2018 Google LLC
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
15import placeholder
16import expect
17import re
18
19from spirv_test_framework import inside_spirv_testsuite
20
21
22def empty_main_assembly():
23  return """
24         OpCapability Shader
25         OpMemoryModel Logical GLSL450
26         OpEntryPoint Vertex %4 "main"
27         OpName %4 "main"
28    %2 = OpTypeVoid
29    %3 = OpTypeFunction %2
30    %4 = OpFunction %2 None %3
31    %5 = OpLabel
32         OpReturn
33         OpFunctionEnd"""
34
35
36@inside_spirv_testsuite('SpirvOptBase')
37class TestAssemblyFileAsOnlyParameter(expect.ValidObjectFile1_5):
38  """Tests that spirv-opt accepts a SPIR-V object file."""
39
40  shader = placeholder.FileSPIRVShader(empty_main_assembly(), '.spvasm')
41  output = placeholder.TempFileName('output.spv')
42  spirv_args = [shader, '-o', output]
43  expected_object_filenames = (output)
44
45
46@inside_spirv_testsuite('SpirvOptFlags')
47class TestHelpFlag(expect.ReturnCodeIsZero, expect.StdoutMatch):
48  """Test the --help flag."""
49
50  spirv_args = ['--help']
51  expected_stdout = re.compile(r'.*The SPIR-V binary is read from <input>')
52
53
54@inside_spirv_testsuite('SpirvOptFlags')
55class TestValidPassFlags(expect.ValidObjectFile1_5,
56                         expect.ExecutedListOfPasses):
57  """Tests that spirv-opt accepts all valid optimization flags."""
58
59  flags = [
60      '--wrap-opkill', '--ccp', '--cfg-cleanup', '--combine-access-chains', '--compact-ids',
61      '--convert-local-access-chains', '--copy-propagate-arrays',
62      '--eliminate-dead-branches',
63      '--eliminate-dead-code-aggressive', '--eliminate-dead-const',
64      '--eliminate-dead-functions', '--eliminate-dead-inserts',
65      '--eliminate-dead-variables', '--eliminate-insert-extract',
66      '--eliminate-local-multi-store', '--eliminate-local-single-block',
67      '--eliminate-local-single-store', '--flatten-decorations',
68      '--fold-spec-const-op-composite', '--freeze-spec-const',
69      '--if-conversion', '--inline-entry-points-exhaustive', '--loop-fission',
70      '20', '--loop-fusion', '5', '--loop-unroll', '--loop-unroll-partial', '3',
71      '--loop-peeling', '--merge-blocks', '--merge-return', '--loop-unswitch',
72      '--private-to-local', '--reduce-load-size', '--redundancy-elimination',
73      '--remove-duplicates', '--replace-invalid-opcode', '--ssa-rewrite',
74      '--scalar-replacement', '--scalar-replacement=42', '--strength-reduction',
75      '--strip-debug', '--strip-reflect', '--vector-dce', '--workaround-1209',
76      '--unify-const'
77  ]
78  expected_passes = [
79      'wrap-opkill',
80      'ccp',
81      'cfg-cleanup',
82      'combine-access-chains',
83      'compact-ids',
84      'convert-local-access-chains',
85      'copy-propagate-arrays',
86      'eliminate-dead-branches',
87      'eliminate-dead-code-aggressive',
88      'eliminate-dead-const',
89      'eliminate-dead-functions',
90      'eliminate-dead-inserts',
91      'eliminate-dead-variables',
92      # --eliminate-insert-extract runs the simplify-instructions pass.
93      'simplify-instructions',
94      'ssa-rewrite',
95      'eliminate-local-single-block',
96      'eliminate-local-single-store',
97      'flatten-decorations',
98      'fold-spec-const-op-composite',
99      'freeze-spec-const',
100      'if-conversion',
101      'inline-entry-points-exhaustive',
102      'loop-fission',
103      'loop-fusion',
104      'loop-unroll',
105      'loop-unroll',
106      'loop-peeling',
107      'merge-blocks',
108      'merge-return',
109      'loop-unswitch',
110      'private-to-local',
111      'reduce-load-size',
112      'redundancy-elimination',
113      'remove-duplicates',
114      'replace-invalid-opcode',
115      'ssa-rewrite',
116      'scalar-replacement=100',
117      'scalar-replacement=42',
118      'strength-reduction',
119      'strip-debug',
120      'strip-reflect',
121      'vector-dce',
122      'workaround-1209',
123      'unify-const'
124  ]
125  shader = placeholder.FileSPIRVShader(empty_main_assembly(), '.spvasm')
126  output = placeholder.TempFileName('output.spv')
127  spirv_args = [shader, '-o', output, '--print-all'] + flags
128  expected_object_filenames = (output)
129
130
131@inside_spirv_testsuite('SpirvOptFlags')
132class TestPerformanceOptimizationPasses(expect.ValidObjectFile1_5,
133                                        expect.ExecutedListOfPasses):
134  """Tests that spirv-opt schedules all the passes triggered by -O."""
135
136  flags = ['-O']
137  expected_passes = [
138      'wrap-opkill',
139      'eliminate-dead-branches',
140      'merge-return',
141      'inline-entry-points-exhaustive',
142      'eliminate-dead-code-aggressive',
143      'private-to-local',
144      'eliminate-local-single-block',
145      'eliminate-local-single-store',
146      'eliminate-dead-code-aggressive',
147      'scalar-replacement=100',
148      'convert-local-access-chains',
149      'eliminate-local-single-block',
150      'eliminate-local-single-store',
151      'eliminate-dead-code-aggressive',
152      'ssa-rewrite',
153      'eliminate-dead-code-aggressive',
154      'ccp',
155      'eliminate-dead-code-aggressive',
156      'redundancy-elimination',
157      'combine-access-chains',
158      'simplify-instructions',
159      'vector-dce',
160      'eliminate-dead-inserts',
161      'eliminate-dead-branches',
162      'simplify-instructions',
163      'if-conversion',
164      'copy-propagate-arrays',
165      'reduce-load-size',
166      'eliminate-dead-code-aggressive',
167      'merge-blocks',
168      'redundancy-elimination',
169      'eliminate-dead-branches',
170      'merge-blocks',
171      'simplify-instructions',
172  ]
173  shader = placeholder.FileSPIRVShader(empty_main_assembly(), '.spvasm')
174  output = placeholder.TempFileName('output.spv')
175  spirv_args = [shader, '-o', output, '--print-all'] + flags
176  expected_object_filenames = (output)
177
178
179@inside_spirv_testsuite('SpirvOptFlags')
180class TestSizeOptimizationPasses(expect.ValidObjectFile1_5,
181                                 expect.ExecutedListOfPasses):
182  """Tests that spirv-opt schedules all the passes triggered by -Os."""
183
184  flags = ['-Os']
185  expected_passes = [
186      'wrap-opkill',
187      'eliminate-dead-branches',
188      'merge-return',
189      'inline-entry-points-exhaustive',
190      'eliminate-dead-functions',
191      'private-to-local',
192      'scalar-replacement=0',
193      'ssa-rewrite',
194      'ccp',
195      'loop-unroll',
196      'eliminate-dead-branches',
197      'simplify-instructions',
198      'scalar-replacement=0',
199      'eliminate-local-single-store',
200      'if-conversion',
201      'simplify-instructions',
202      'eliminate-dead-code-aggressive',
203      'eliminate-dead-branches',
204      'merge-blocks',
205      'convert-local-access-chains',
206      'eliminate-local-single-block',
207      'eliminate-dead-code-aggressive',
208      'copy-propagate-arrays',
209      'vector-dce',
210      'eliminate-dead-inserts',
211      'eliminate-dead-members',
212      'eliminate-local-single-store',
213      'merge-blocks',
214      'ssa-rewrite',
215      'redundancy-elimination',
216      'simplify-instructions',
217      'eliminate-dead-code-aggressive',
218      'cfg-cleanup',
219  ]
220  shader = placeholder.FileSPIRVShader(empty_main_assembly(), '.spvasm')
221  output = placeholder.TempFileName('output.spv')
222  spirv_args = [shader, '-o', output, '--print-all'] + flags
223  expected_object_filenames = (output)
224
225
226@inside_spirv_testsuite('SpirvOptFlags')
227class TestLegalizationPasses(expect.ValidObjectFile1_5,
228                             expect.ExecutedListOfPasses):
229  """Tests that spirv-opt schedules all the passes triggered by --legalize-hlsl.
230  """
231
232  flags = ['--legalize-hlsl']
233  expected_passes = [
234      'wrap-opkill',
235      'eliminate-dead-branches',
236      'merge-return',
237      'inline-entry-points-exhaustive',
238      'eliminate-dead-functions',
239      'private-to-local',
240      'fix-storage-class',
241      'eliminate-local-single-block',
242      'eliminate-local-single-store',
243      'eliminate-dead-code-aggressive',
244      'scalar-replacement=0',
245      'eliminate-local-single-block',
246      'eliminate-local-single-store',
247      'eliminate-dead-code-aggressive',
248      'ssa-rewrite',
249      'eliminate-dead-code-aggressive',
250      'ccp',
251      'loop-unroll',
252      'eliminate-dead-branches',
253      'simplify-instructions',
254      'eliminate-dead-code-aggressive',
255      'copy-propagate-arrays',
256      'vector-dce',
257      'eliminate-dead-inserts',
258      'reduce-load-size',
259      'eliminate-dead-code-aggressive',
260  ]
261  shader = placeholder.FileSPIRVShader(empty_main_assembly(), '.spvasm')
262  output = placeholder.TempFileName('output.spv')
263  spirv_args = [shader, '-o', output, '--print-all'] + flags
264  expected_object_filenames = (output)
265
266
267@inside_spirv_testsuite('SpirvOptFlags')
268class TestScalarReplacementArgsNegative(expect.ErrorMessageSubstr):
269  """Tests invalid arguments to --scalar-replacement."""
270
271  spirv_args = ['--scalar-replacement=-10']
272  expected_error_substr = 'must have no arguments or a non-negative integer argument'
273
274
275@inside_spirv_testsuite('SpirvOptFlags')
276class TestScalarReplacementArgsInvalidNumber(expect.ErrorMessageSubstr):
277  """Tests invalid arguments to --scalar-replacement."""
278
279  spirv_args = ['--scalar-replacement=a10f']
280  expected_error_substr = 'must have no arguments or a non-negative integer argument'
281
282
283@inside_spirv_testsuite('SpirvOptFlags')
284class TestLoopFissionArgsNegative(expect.ErrorMessageSubstr):
285  """Tests invalid arguments to --loop-fission."""
286
287  spirv_args = ['--loop-fission=-10']
288  expected_error_substr = 'must have a positive integer argument'
289
290
291@inside_spirv_testsuite('SpirvOptFlags')
292class TestLoopFissionArgsInvalidNumber(expect.ErrorMessageSubstr):
293  """Tests invalid arguments to --loop-fission."""
294
295  spirv_args = ['--loop-fission=a10f']
296  expected_error_substr = 'must have a positive integer argument'
297
298
299@inside_spirv_testsuite('SpirvOptFlags')
300class TestLoopFusionArgsNegative(expect.ErrorMessageSubstr):
301  """Tests invalid arguments to --loop-fusion."""
302
303  spirv_args = ['--loop-fusion=-10']
304  expected_error_substr = 'must have a positive integer argument'
305
306
307@inside_spirv_testsuite('SpirvOptFlags')
308class TestLoopFusionArgsInvalidNumber(expect.ErrorMessageSubstr):
309  """Tests invalid arguments to --loop-fusion."""
310
311  spirv_args = ['--loop-fusion=a10f']
312  expected_error_substr = 'must have a positive integer argument'
313
314
315@inside_spirv_testsuite('SpirvOptFlags')
316class TestLoopUnrollPartialArgsNegative(expect.ErrorMessageSubstr):
317  """Tests invalid arguments to --loop-unroll-partial."""
318
319  spirv_args = ['--loop-unroll-partial=-10']
320  expected_error_substr = 'must have a positive integer argument'
321
322
323@inside_spirv_testsuite('SpirvOptFlags')
324class TestLoopUnrollPartialArgsInvalidNumber(expect.ErrorMessageSubstr):
325  """Tests invalid arguments to --loop-unroll-partial."""
326
327  spirv_args = ['--loop-unroll-partial=a10f']
328  expected_error_substr = 'must have a positive integer argument'
329
330
331@inside_spirv_testsuite('SpirvOptFlags')
332class TestLoopPeelingThresholdArgsNegative(expect.ErrorMessageSubstr):
333  """Tests invalid arguments to --loop-peeling-threshold."""
334
335  spirv_args = ['--loop-peeling-threshold=-10']
336  expected_error_substr = 'must have a positive integer argument'
337
338
339@inside_spirv_testsuite('SpirvOptFlags')
340class TestLoopPeelingThresholdArgsInvalidNumber(expect.ErrorMessageSubstr):
341  """Tests invalid arguments to --loop-peeling-threshold."""
342
343  spirv_args = ['--loop-peeling-threshold=a10f']
344  expected_error_substr = 'must have a positive integer argument'
345
346@inside_spirv_testsuite('SpirvOptFlags')
347class TestWebGPUToVulkanThenVulkanToWebGPUIsInvalid(expect.ReturnCodeIsNonZero, expect.ErrorMessageSubstr):
348  """Tests Vulkan->WebGPU flag cannot be used after WebGPU->Vulkan flag."""
349
350  spirv_args = ['--webgpu-to-vulkan', '--vulkan-to-webgpu']
351  expected_error_substr = 'Cannot use both'
352
353@inside_spirv_testsuite('SpirvOptFlags')
354class TestVulkanToWebGPUThenWebGPUToVulkanIsInvalid(expect.ReturnCodeIsNonZero, expect.ErrorMessageSubstr):
355  """Tests WebGPU->Vulkan flag cannot be used after Vulkan->WebGPU flag."""
356
357  spirv_args = ['--vulkan-to-webgpu', '--webgpu-to-vulkan']
358  expected_error_substr = 'Cannot use both'
359
360@inside_spirv_testsuite('SpirvOptFlags')
361class TestTargetEnvThenVulkanToWebGPUIsInvalid(expect.ReturnCodeIsNonZero, expect.ErrorMessageSubstr):
362  """Tests Vulkan->WebGPU flag cannot be used after target env flag."""
363
364  spirv_args = ['--target-env=opengl4.0', '--vulkan-to-webgpu']
365  expected_error_substr = 'defines the target environment'
366
367@inside_spirv_testsuite('SpirvOptFlags')
368class TestVulkanToWebGPUThenTargetEnvIsInvalid(expect.ReturnCodeIsNonZero, expect.ErrorMessageSubstr):
369  """Tests target env flag cannot be used after Vulkan->WebGPU flag."""
370
371  spirv_args = ['--vulkan-to-webgpu', '--target-env=opengl4.0']
372  expected_error_substr = 'defines the target environment'
373
374@inside_spirv_testsuite('SpirvOptFlags')
375class TestTargetEnvThenWebGPUToVulkanIsInvalid(expect.ReturnCodeIsNonZero, expect.ErrorMessageSubstr):
376  """Tests WebGPU->Vulkan flag cannot be used after target env flag."""
377
378  spirv_args = ['--target-env=opengl4.0', '--webgpu-to-vulkan']
379  expected_error_substr = 'defines the target environment'
380
381@inside_spirv_testsuite('SpirvOptFlags')
382class TestWebGPUToVulkanThenTargetEnvIsInvalid(expect.ReturnCodeIsNonZero, expect.ErrorMessageSubstr):
383  """Tests target env flag cannot be used after WebGPU->Vulkan flag."""
384
385  spirv_args = ['--webgpu-to-vulkan', '--target-env=opengl4.0']
386  expected_error_substr = 'defines the target environment'
387