• 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', '--legalize-vector-shuffle',
77      '--split-invalid-unreachable', '--generate-webgpu-initializers',
78      '--decompose-initialized-variables', '--graphics-robust-access',
79      '--wrap-opkill', '--amd-ext-to-khr'
80  ]
81  expected_passes = [
82      'wrap-opkill',
83      'ccp',
84      'cfg-cleanup',
85      'combine-access-chains',
86      'compact-ids',
87      'convert-local-access-chains',
88      'copy-propagate-arrays',
89      'eliminate-dead-branches',
90      'eliminate-dead-code-aggressive',
91      'eliminate-dead-const',
92      'eliminate-dead-functions',
93      'eliminate-dead-inserts',
94      'eliminate-dead-variables',
95      # --eliminate-insert-extract runs the simplify-instructions pass.
96      'simplify-instructions',
97      'ssa-rewrite',
98      'eliminate-local-single-block',
99      'eliminate-local-single-store',
100      'flatten-decorations',
101      'fold-spec-const-op-composite',
102      'freeze-spec-const',
103      'if-conversion',
104      'inline-entry-points-exhaustive',
105      'loop-fission',
106      'loop-fusion',
107      'loop-unroll',
108      'loop-unroll',
109      'loop-peeling',
110      'merge-blocks',
111      'merge-return',
112      'loop-unswitch',
113      'private-to-local',
114      'reduce-load-size',
115      'redundancy-elimination',
116      'remove-duplicates',
117      'replace-invalid-opcode',
118      'ssa-rewrite',
119      'scalar-replacement=100',
120      'scalar-replacement=42',
121      'strength-reduction',
122      'strip-debug',
123      'strip-reflect',
124      'vector-dce',
125      'workaround-1209',
126      'unify-const',
127      'legalize-vector-shuffle',
128      'split-invalid-unreachable',
129      'generate-webgpu-initializers',
130      'decompose-initialized-variables',
131      'graphics-robust-access',
132      'wrap-opkill',
133      'amd-ext-to-khr'
134  ]
135  shader = placeholder.FileSPIRVShader(empty_main_assembly(), '.spvasm')
136  output = placeholder.TempFileName('output.spv')
137  spirv_args = [shader, '-o', output, '--print-all'] + flags
138  expected_object_filenames = (output)
139
140
141@inside_spirv_testsuite('SpirvOptFlags')
142class TestPerformanceOptimizationPasses(expect.ValidObjectFile1_5,
143                                        expect.ExecutedListOfPasses):
144  """Tests that spirv-opt schedules all the passes triggered by -O."""
145
146  flags = ['-O']
147  expected_passes = [
148      'wrap-opkill',
149      'eliminate-dead-branches',
150      'merge-return',
151      'inline-entry-points-exhaustive',
152      'eliminate-dead-code-aggressive',
153      'private-to-local',
154      'eliminate-local-single-block',
155      'eliminate-local-single-store',
156      'eliminate-dead-code-aggressive',
157      'scalar-replacement=100',
158      'convert-local-access-chains',
159      'eliminate-local-single-block',
160      'eliminate-local-single-store',
161      'eliminate-dead-code-aggressive',
162      'ssa-rewrite',
163      'eliminate-dead-code-aggressive',
164      'ccp',
165      'eliminate-dead-code-aggressive',
166      'redundancy-elimination',
167      'combine-access-chains',
168      'simplify-instructions',
169      'vector-dce',
170      'eliminate-dead-inserts',
171      'eliminate-dead-branches',
172      'simplify-instructions',
173      'if-conversion',
174      'copy-propagate-arrays',
175      'reduce-load-size',
176      'eliminate-dead-code-aggressive',
177      'merge-blocks',
178      'redundancy-elimination',
179      'eliminate-dead-branches',
180      'merge-blocks',
181      'simplify-instructions',
182  ]
183  shader = placeholder.FileSPIRVShader(empty_main_assembly(), '.spvasm')
184  output = placeholder.TempFileName('output.spv')
185  spirv_args = [shader, '-o', output, '--print-all'] + flags
186  expected_object_filenames = (output)
187
188
189@inside_spirv_testsuite('SpirvOptFlags')
190class TestSizeOptimizationPasses(expect.ValidObjectFile1_5,
191                                 expect.ExecutedListOfPasses):
192  """Tests that spirv-opt schedules all the passes triggered by -Os."""
193
194  flags = ['-Os']
195  expected_passes = [
196      'wrap-opkill',
197      'eliminate-dead-branches',
198      'merge-return',
199      'inline-entry-points-exhaustive',
200      'eliminate-dead-functions',
201      'private-to-local',
202      'scalar-replacement=0',
203      'ssa-rewrite',
204      'ccp',
205      'loop-unroll',
206      'eliminate-dead-branches',
207      'simplify-instructions',
208      'scalar-replacement=0',
209      'eliminate-local-single-store',
210      'if-conversion',
211      'simplify-instructions',
212      'eliminate-dead-code-aggressive',
213      'eliminate-dead-branches',
214      'merge-blocks',
215      'convert-local-access-chains',
216      'eliminate-local-single-block',
217      'eliminate-dead-code-aggressive',
218      'copy-propagate-arrays',
219      'vector-dce',
220      'eliminate-dead-inserts',
221      'eliminate-dead-members',
222      'eliminate-local-single-store',
223      'merge-blocks',
224      'ssa-rewrite',
225      'redundancy-elimination',
226      'simplify-instructions',
227      'eliminate-dead-code-aggressive',
228      'cfg-cleanup',
229  ]
230  shader = placeholder.FileSPIRVShader(empty_main_assembly(), '.spvasm')
231  output = placeholder.TempFileName('output.spv')
232  spirv_args = [shader, '-o', output, '--print-all'] + flags
233  expected_object_filenames = (output)
234
235
236@inside_spirv_testsuite('SpirvOptFlags')
237class TestLegalizationPasses(expect.ValidObjectFile1_5,
238                             expect.ExecutedListOfPasses):
239  """Tests that spirv-opt schedules all the passes triggered by --legalize-hlsl.
240  """
241
242  flags = ['--legalize-hlsl']
243  expected_passes = [
244      'wrap-opkill',
245      'eliminate-dead-branches',
246      'merge-return',
247      'inline-entry-points-exhaustive',
248      'eliminate-dead-functions',
249      'private-to-local',
250      'fix-storage-class',
251      'eliminate-local-single-block',
252      'eliminate-local-single-store',
253      'eliminate-dead-code-aggressive',
254      'scalar-replacement=0',
255      'eliminate-local-single-block',
256      'eliminate-local-single-store',
257      'eliminate-dead-code-aggressive',
258      'ssa-rewrite',
259      'eliminate-dead-code-aggressive',
260      'ccp',
261      'loop-unroll',
262      'eliminate-dead-branches',
263      'simplify-instructions',
264      'eliminate-dead-code-aggressive',
265      'copy-propagate-arrays',
266      'vector-dce',
267      'eliminate-dead-inserts',
268      'reduce-load-size',
269      'eliminate-dead-code-aggressive',
270  ]
271  shader = placeholder.FileSPIRVShader(empty_main_assembly(), '.spvasm')
272  output = placeholder.TempFileName('output.spv')
273  spirv_args = [shader, '-o', output, '--print-all'] + flags
274  expected_object_filenames = (output)
275
276
277@inside_spirv_testsuite('SpirvOptFlags')
278class TestScalarReplacementArgsNegative(expect.ErrorMessageSubstr):
279  """Tests invalid arguments to --scalar-replacement."""
280
281  spirv_args = ['--scalar-replacement=-10']
282  expected_error_substr = 'must have no arguments or a non-negative integer argument'
283
284
285@inside_spirv_testsuite('SpirvOptFlags')
286class TestScalarReplacementArgsInvalidNumber(expect.ErrorMessageSubstr):
287  """Tests invalid arguments to --scalar-replacement."""
288
289  spirv_args = ['--scalar-replacement=a10f']
290  expected_error_substr = 'must have no arguments or a non-negative integer argument'
291
292
293@inside_spirv_testsuite('SpirvOptFlags')
294class TestLoopFissionArgsNegative(expect.ErrorMessageSubstr):
295  """Tests invalid arguments to --loop-fission."""
296
297  spirv_args = ['--loop-fission=-10']
298  expected_error_substr = 'must have a positive integer argument'
299
300
301@inside_spirv_testsuite('SpirvOptFlags')
302class TestLoopFissionArgsInvalidNumber(expect.ErrorMessageSubstr):
303  """Tests invalid arguments to --loop-fission."""
304
305  spirv_args = ['--loop-fission=a10f']
306  expected_error_substr = 'must have a positive integer argument'
307
308
309@inside_spirv_testsuite('SpirvOptFlags')
310class TestLoopFusionArgsNegative(expect.ErrorMessageSubstr):
311  """Tests invalid arguments to --loop-fusion."""
312
313  spirv_args = ['--loop-fusion=-10']
314  expected_error_substr = 'must have a positive integer argument'
315
316
317@inside_spirv_testsuite('SpirvOptFlags')
318class TestLoopFusionArgsInvalidNumber(expect.ErrorMessageSubstr):
319  """Tests invalid arguments to --loop-fusion."""
320
321  spirv_args = ['--loop-fusion=a10f']
322  expected_error_substr = 'must have a positive integer argument'
323
324
325@inside_spirv_testsuite('SpirvOptFlags')
326class TestLoopUnrollPartialArgsNegative(expect.ErrorMessageSubstr):
327  """Tests invalid arguments to --loop-unroll-partial."""
328
329  spirv_args = ['--loop-unroll-partial=-10']
330  expected_error_substr = 'must have a positive integer argument'
331
332
333@inside_spirv_testsuite('SpirvOptFlags')
334class TestLoopUnrollPartialArgsInvalidNumber(expect.ErrorMessageSubstr):
335  """Tests invalid arguments to --loop-unroll-partial."""
336
337  spirv_args = ['--loop-unroll-partial=a10f']
338  expected_error_substr = 'must have a positive integer argument'
339
340
341@inside_spirv_testsuite('SpirvOptFlags')
342class TestLoopPeelingThresholdArgsNegative(expect.ErrorMessageSubstr):
343  """Tests invalid arguments to --loop-peeling-threshold."""
344
345  spirv_args = ['--loop-peeling-threshold=-10']
346  expected_error_substr = 'must have a positive integer argument'
347
348
349@inside_spirv_testsuite('SpirvOptFlags')
350class TestLoopPeelingThresholdArgsInvalidNumber(expect.ErrorMessageSubstr):
351  """Tests invalid arguments to --loop-peeling-threshold."""
352
353  spirv_args = ['--loop-peeling-threshold=a10f']
354  expected_error_substr = 'must have a positive integer argument'
355
356@inside_spirv_testsuite('SpirvOptFlags')
357class TestWebGPUToVulkanThenVulkanToWebGPUIsInvalid(expect.ReturnCodeIsNonZero, expect.ErrorMessageSubstr):
358  """Tests Vulkan->WebGPU flag cannot be used after WebGPU->Vulkan flag."""
359
360  spirv_args = ['--webgpu-to-vulkan', '--vulkan-to-webgpu']
361  expected_error_substr = 'Cannot use both'
362
363@inside_spirv_testsuite('SpirvOptFlags')
364class TestVulkanToWebGPUThenWebGPUToVulkanIsInvalid(expect.ReturnCodeIsNonZero, expect.ErrorMessageSubstr):
365  """Tests WebGPU->Vulkan flag cannot be used after Vulkan->WebGPU flag."""
366
367  spirv_args = ['--vulkan-to-webgpu', '--webgpu-to-vulkan']
368  expected_error_substr = 'Cannot use both'
369
370@inside_spirv_testsuite('SpirvOptFlags')
371class TestTargetEnvThenVulkanToWebGPUIsInvalid(expect.ReturnCodeIsNonZero, expect.ErrorMessageSubstr):
372  """Tests Vulkan->WebGPU flag cannot be used after target env flag."""
373
374  spirv_args = ['--target-env=opengl4.0', '--vulkan-to-webgpu']
375  expected_error_substr = 'defines the target environment'
376
377@inside_spirv_testsuite('SpirvOptFlags')
378class TestVulkanToWebGPUThenTargetEnvIsInvalid(expect.ReturnCodeIsNonZero, expect.ErrorMessageSubstr):
379  """Tests target env flag cannot be used after Vulkan->WebGPU flag."""
380
381  spirv_args = ['--vulkan-to-webgpu', '--target-env=opengl4.0']
382  expected_error_substr = 'defines the target environment'
383
384@inside_spirv_testsuite('SpirvOptFlags')
385class TestTargetEnvThenWebGPUToVulkanIsInvalid(expect.ReturnCodeIsNonZero, expect.ErrorMessageSubstr):
386  """Tests WebGPU->Vulkan flag cannot be used after target env flag."""
387
388  spirv_args = ['--target-env=opengl4.0', '--webgpu-to-vulkan']
389  expected_error_substr = 'defines the target environment'
390
391@inside_spirv_testsuite('SpirvOptFlags')
392class TestWebGPUToVulkanThenTargetEnvIsInvalid(expect.ReturnCodeIsNonZero, expect.ErrorMessageSubstr):
393  """Tests target env flag cannot be used after WebGPU->Vulkan flag."""
394
395  spirv_args = ['--webgpu-to-vulkan', '--target-env=opengl4.0']
396  expected_error_substr = 'defines the target environment'
397