• 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_3):
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_3,
56                         expect.ExecutedListOfPasses):
57  """Tests that spirv-opt accepts all valid optimization flags."""
58
59  flags = [
60      '--ccp', '--cfg-cleanup', '--combine-access-chains', '--compact-ids',
61      '--convert-local-access-chains', '--copy-propagate-arrays',
62      '--eliminate-common-uniform', '--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      'ccp',
80      'cfg-cleanup',
81      'combine-access-chains',
82      'compact-ids',
83      'convert-local-access-chains',
84      'copy-propagate-arrays',
85      'eliminate-common-uniform',
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      'eliminate-local-multi-store',
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_3,
133                                        expect.ExecutedListOfPasses):
134  """Tests that spirv-opt schedules all the passes triggered by -O."""
135
136  flags = ['-O']
137  expected_passes = [
138      'eliminate-dead-branches',
139      'merge-return',
140      'inline-entry-points-exhaustive',
141      'eliminate-dead-code-aggressive',
142      'private-to-local',
143      'eliminate-local-single-block',
144      'eliminate-local-single-store',
145      'eliminate-dead-code-aggressive',
146      'scalar-replacement=100',
147      'convert-local-access-chains',
148      'eliminate-local-single-block',
149      'eliminate-local-single-store',
150      'eliminate-dead-code-aggressive',
151      'eliminate-local-multi-store',
152      'eliminate-dead-code-aggressive',
153      'ccp',
154      'eliminate-dead-code-aggressive',
155      'redundancy-elimination',
156      'combine-access-chains',
157      'simplify-instructions',
158      'vector-dce',
159      'eliminate-dead-inserts',
160      'eliminate-dead-branches',
161      'simplify-instructions',
162      'if-conversion',
163      'copy-propagate-arrays',
164      'reduce-load-size',
165      'eliminate-dead-code-aggressive',
166      'merge-blocks',
167      'redundancy-elimination',
168      'eliminate-dead-branches',
169      'merge-blocks',
170      'simplify-instructions',
171  ]
172  shader = placeholder.FileSPIRVShader(empty_main_assembly(), '.spvasm')
173  output = placeholder.TempFileName('output.spv')
174  spirv_args = [shader, '-o', output, '--print-all'] + flags
175  expected_object_filenames = (output)
176
177
178@inside_spirv_testsuite('SpirvOptFlags')
179class TestSizeOptimizationPasses(expect.ValidObjectFile1_3,
180                                 expect.ExecutedListOfPasses):
181  """Tests that spirv-opt schedules all the passes triggered by -Os."""
182
183  flags = ['-Os']
184  expected_passes = [
185      'eliminate-dead-branches',
186      'merge-return',
187      'inline-entry-points-exhaustive',
188      'eliminate-dead-code-aggressive',
189      'private-to-local',
190      'scalar-replacement=100',
191      'convert-local-access-chains',
192      'eliminate-local-single-block',
193      'eliminate-local-single-store',
194      'eliminate-dead-code-aggressive',
195      'simplify-instructions',
196      'eliminate-dead-inserts',
197      'eliminate-local-multi-store',
198      'eliminate-dead-code-aggressive',
199      'ccp',
200      'eliminate-dead-code-aggressive',
201      'eliminate-dead-branches',
202      'if-conversion',
203      'eliminate-dead-code-aggressive',
204      'merge-blocks',
205      'simplify-instructions',
206      'eliminate-dead-inserts',
207      'redundancy-elimination',
208      'cfg-cleanup',
209      'eliminate-dead-code-aggressive',
210  ]
211  shader = placeholder.FileSPIRVShader(empty_main_assembly(), '.spvasm')
212  output = placeholder.TempFileName('output.spv')
213  spirv_args = [shader, '-o', output, '--print-all'] + flags
214  expected_object_filenames = (output)
215
216
217@inside_spirv_testsuite('SpirvOptFlags')
218class TestLegalizationPasses(expect.ValidObjectFile1_3,
219                             expect.ExecutedListOfPasses):
220  """Tests that spirv-opt schedules all the passes triggered by --legalize-hlsl.
221  """
222
223  flags = ['--legalize-hlsl']
224  expected_passes = [
225      'eliminate-dead-branches',
226      'merge-return',
227      'inline-entry-points-exhaustive',
228      'eliminate-dead-functions',
229      'private-to-local',
230      'eliminate-local-single-block',
231      'eliminate-local-single-store',
232      'eliminate-dead-code-aggressive',
233      'scalar-replacement=0',
234      'eliminate-local-single-block',
235      'eliminate-local-single-store',
236      'eliminate-dead-code-aggressive',
237      'eliminate-local-multi-store',
238      'eliminate-dead-code-aggressive',
239      'ccp',
240      'loop-unroll',
241      'eliminate-dead-branches',
242      'simplify-instructions',
243      'eliminate-dead-code-aggressive',
244      'copy-propagate-arrays',
245      'vector-dce',
246      'eliminate-dead-inserts',
247      'reduce-load-size',
248      'eliminate-dead-code-aggressive',
249  ]
250  shader = placeholder.FileSPIRVShader(empty_main_assembly(), '.spvasm')
251  output = placeholder.TempFileName('output.spv')
252  spirv_args = [shader, '-o', output, '--print-all'] + flags
253  expected_object_filenames = (output)
254
255
256@inside_spirv_testsuite('SpirvOptFlags')
257class TestScalarReplacementArgsNegative(expect.ErrorMessageSubstr):
258  """Tests invalid arguments to --scalar-replacement."""
259
260  spirv_args = ['--scalar-replacement=-10']
261  expected_error_substr = 'must have no arguments or a non-negative integer argument'
262
263
264@inside_spirv_testsuite('SpirvOptFlags')
265class TestScalarReplacementArgsInvalidNumber(expect.ErrorMessageSubstr):
266  """Tests invalid arguments to --scalar-replacement."""
267
268  spirv_args = ['--scalar-replacement=a10f']
269  expected_error_substr = 'must have no arguments or a non-negative integer argument'
270
271
272@inside_spirv_testsuite('SpirvOptFlags')
273class TestLoopFissionArgsNegative(expect.ErrorMessageSubstr):
274  """Tests invalid arguments to --loop-fission."""
275
276  spirv_args = ['--loop-fission=-10']
277  expected_error_substr = 'must have a positive integer argument'
278
279
280@inside_spirv_testsuite('SpirvOptFlags')
281class TestLoopFissionArgsInvalidNumber(expect.ErrorMessageSubstr):
282  """Tests invalid arguments to --loop-fission."""
283
284  spirv_args = ['--loop-fission=a10f']
285  expected_error_substr = 'must have a positive integer argument'
286
287
288@inside_spirv_testsuite('SpirvOptFlags')
289class TestLoopFusionArgsNegative(expect.ErrorMessageSubstr):
290  """Tests invalid arguments to --loop-fusion."""
291
292  spirv_args = ['--loop-fusion=-10']
293  expected_error_substr = 'must have a positive integer argument'
294
295
296@inside_spirv_testsuite('SpirvOptFlags')
297class TestLoopFusionArgsInvalidNumber(expect.ErrorMessageSubstr):
298  """Tests invalid arguments to --loop-fusion."""
299
300  spirv_args = ['--loop-fusion=a10f']
301  expected_error_substr = 'must have a positive integer argument'
302
303
304@inside_spirv_testsuite('SpirvOptFlags')
305class TestLoopUnrollPartialArgsNegative(expect.ErrorMessageSubstr):
306  """Tests invalid arguments to --loop-unroll-partial."""
307
308  spirv_args = ['--loop-unroll-partial=-10']
309  expected_error_substr = 'must have a positive integer argument'
310
311
312@inside_spirv_testsuite('SpirvOptFlags')
313class TestLoopUnrollPartialArgsInvalidNumber(expect.ErrorMessageSubstr):
314  """Tests invalid arguments to --loop-unroll-partial."""
315
316  spirv_args = ['--loop-unroll-partial=a10f']
317  expected_error_substr = 'must have a positive integer argument'
318
319
320@inside_spirv_testsuite('SpirvOptFlags')
321class TestLoopPeelingThresholdArgsNegative(expect.ErrorMessageSubstr):
322  """Tests invalid arguments to --loop-peeling-threshold."""
323
324  spirv_args = ['--loop-peeling-threshold=-10']
325  expected_error_substr = 'must have a positive integer argument'
326
327
328@inside_spirv_testsuite('SpirvOptFlags')
329class TestLoopPeelingThresholdArgsInvalidNumber(expect.ErrorMessageSubstr):
330  """Tests invalid arguments to --loop-peeling-threshold."""
331
332  spirv_args = ['--loop-peeling-threshold=a10f']
333  expected_error_substr = 'must have a positive integer argument'
334