1 // Copyright (c) 2023 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 "spirv-tools/optimizer.hpp"
16 #include "test/opt/pass_fixture.h"
17 #include "test/opt/pass_utils.h"
18 
19 namespace spvtools {
20 namespace opt {
21 namespace {
22 
23 using TrimCapabilitiesPassTest = PassTest<::testing::Test>;
24 
TEST_F(TrimCapabilitiesPassTest,CheckKnownAliasTransformations)25 TEST_F(TrimCapabilitiesPassTest, CheckKnownAliasTransformations) {
26   // Those are expected changes caused by the test process:
27   //  - SPV is assembled. -> capability goes from text to number.
28   //  - SPV is optimized.
29   //  - SPV is disassembled -> capability goes from number to text.
30   //  - CHECK rule compares both text versions.
31   // Because some capabilities share the same number (aliases), the text
32   // compared with the CHECK rules depends on which alias is the first on the
33   // SPIRV-Headers enum. This could change, and we want to easily distinguish
34   // real failure from alias order change. This test is only here to list known
35   // alias transformations. If this test breaks, it's not a bug in the
36   // optimization pass, but just the SPIRV-Headers enum order that has changed.
37   // If that happens, tests needs to be updated to the correct alias is used in
38   // the CHECK rule.
39   const std::string kTest = R"(
40                OpCapability Linkage
41                OpCapability StorageUniform16
42                OpCapability StorageUniformBufferBlock16
43                OpCapability ShaderViewportIndexLayerNV
44                OpCapability FragmentBarycentricNV
45                OpCapability ShadingRateNV
46                OpCapability ShaderNonUniformEXT
47                OpCapability RuntimeDescriptorArrayEXT
48                OpCapability InputAttachmentArrayDynamicIndexingEXT
49                OpCapability UniformTexelBufferArrayDynamicIndexingEXT
50                OpCapability StorageTexelBufferArrayDynamicIndexingEXT
51                OpCapability UniformBufferArrayNonUniformIndexingEXT
52                OpCapability SampledImageArrayNonUniformIndexingEXT
53                OpCapability StorageBufferArrayNonUniformIndexingEXT
54                OpCapability StorageImageArrayNonUniformIndexingEXT
55                OpCapability InputAttachmentArrayNonUniformIndexingEXT
56                OpCapability UniformTexelBufferArrayNonUniformIndexingEXT
57                OpCapability StorageTexelBufferArrayNonUniformIndexingEXT
58                OpCapability VulkanMemoryModelKHR
59                OpCapability VulkanMemoryModelDeviceScopeKHR
60                OpCapability PhysicalStorageBufferAddressesEXT
61                OpCapability DemoteToHelperInvocationEXT
62                OpCapability DotProductInputAllKHR
63                OpCapability DotProductInput4x8BitKHR
64                OpCapability DotProductInput4x8BitPackedKHR
65                OpCapability DotProductKHR
66                OpCapability ComputeDerivativeGroupQuadsNV
67                OpCapability ComputeDerivativeGroupLinearNV
68 ; CHECK: OpCapability Linkage
69 ; CHECK-NOT: OpCapability StorageUniform16
70 ; CHECK-NOT: OpCapability StorageUniformBufferBlock16
71 ; CHECK-NOT: OpCapability ShaderViewportIndexLayerNV
72 ; CHECK-NOT: OpCapability FragmentBarycentricNV
73 ; CHECK-NOT: OpCapability ShadingRateNV
74 ; CHECK-NOT: OpCapability ShaderNonUniformEXT
75 ; CHECK-NOT: OpCapability RuntimeDescriptorArrayEXT
76 ; CHECK-NOT: OpCapability InputAttachmentArrayDynamicIndexingEXT
77 ; CHECK-NOT: OpCapability UniformTexelBufferArrayDynamicIndexingEXT
78 ; CHECK-NOT: OpCapability StorageTexelBufferArrayDynamicIndexingEXT
79 ; CHECK-NOT: OpCapability UniformBufferArrayNonUniformIndexingEXT
80 ; CHECK-NOT: OpCapability SampledImageArrayNonUniformIndexingEXT
81 ; CHECK-NOT: OpCapability StorageBufferArrayNonUniformIndexingEXT
82 ; CHECK-NOT: OpCapability StorageImageArrayNonUniformIndexingEXT
83 ; CHECK-NOT: OpCapability InputAttachmentArrayNonUniformIndexingEXT
84 ; CHECK-NOT: OpCapability UniformTexelBufferArrayNonUniformIndexingEXT
85 ; CHECK-NOT: OpCapability StorageTexelBufferArrayNonUniformIndexingEXT
86 ; CHECK-NOT: OpCapability VulkanMemoryModelKHR
87 ; CHECK-NOT: OpCapability VulkanMemoryModelDeviceScopeKHR
88 ; CHECK-NOT: OpCapability PhysicalStorageBufferAddressesEXT
89 ; CHECK-NOT: OpCapability DemoteToHelperInvocationEXT
90 ; CHECK-NOT: OpCapability DotProductInputAllKHR
91 ; CHECK-NOT: OpCapability DotProductInput4x8BitKHR
92 ; CHECK-NOT: OpCapability DotProductInput4x8BitPackedKHR
93 ; CHECK-NOT: OpCapability DotProductKHR
94 ; CHECK-NOT: OpCapability ComputeDerivativeGroupQuadsNV
95 ; CHECK-NOT: OpCapability ComputeDerivativeGroupLinearNV
96 ; CHECK: OpCapability UniformAndStorageBuffer16BitAccess
97 ; CHECK: OpCapability StorageBuffer16BitAccess
98 ; CHECK: OpCapability ShaderViewportIndexLayerEXT
99 ; CHECK: OpCapability FragmentBarycentricKHR
100 ; CHECK: OpCapability FragmentDensityEXT
101 ; CHECK: OpCapability ShaderNonUniform
102 ; CHECK: OpCapability RuntimeDescriptorArray
103 ; CHECK: OpCapability InputAttachmentArrayDynamicIndexing
104 ; CHECK: OpCapability UniformTexelBufferArrayDynamicIndexing
105 ; CHECK: OpCapability StorageTexelBufferArrayDynamicIndexing
106 ; CHECK: OpCapability UniformBufferArrayNonUniformIndexing
107 ; CHECK: OpCapability SampledImageArrayNonUniformIndexing
108 ; CHECK: OpCapability StorageBufferArrayNonUniformIndexing
109 ; CHECK: OpCapability StorageImageArrayNonUniformIndexing
110 ; CHECK: OpCapability InputAttachmentArrayNonUniformIndexing
111 ; CHECK: OpCapability UniformTexelBufferArrayNonUniformIndexing
112 ; CHECK: OpCapability StorageTexelBufferArrayNonUniformIndexing
113 ; CHECK: OpCapability VulkanMemoryModel
114 ; CHECK: OpCapability VulkanMemoryModelDeviceScope
115 ; CHECK: OpCapability PhysicalStorageBufferAddresses
116 ; CHECK: OpCapability DemoteToHelperInvocation
117 ; CHECK: OpCapability DotProductInputAll
118 ; CHECK: OpCapability DotProductInput4x8Bit
119 ; CHECK: OpCapability DotProductInput4x8BitPacked
120 ; CHECK: OpCapability DotProduct
121                OpMemoryModel Logical Vulkan
122                OpEntryPoint GLCompute %1 "main"
123        %void = OpTypeVoid
124           %3 = OpTypeFunction %void
125           %1 = OpFunction %void None %3
126           %6 = OpLabel
127                OpReturn
128                OpFunctionEnd;
129   )";
130   SetTargetEnv(SPV_ENV_VULKAN_1_3);
131   const auto result =
132       SinglePassRunAndMatch<EmptyPass>(kTest, /* skip_nop= */ false);
133   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
134 }
135 
TEST_F(TrimCapabilitiesPassTest,LinkagePreventsChanges)136 TEST_F(TrimCapabilitiesPassTest, LinkagePreventsChanges) {
137   const std::string kTest = R"(
138                OpCapability Linkage
139                OpCapability ClipDistance
140                OpCapability CullDistance
141                OpCapability DemoteToHelperInvocation
142                OpCapability DeviceGroup
143                OpCapability DrawParameters
144                OpCapability Float16
145                OpCapability Float64
146                OpCapability FragmentBarycentricKHR
147                OpCapability FragmentFullyCoveredEXT
148                OpCapability FragmentShadingRateKHR
149                OpCapability GroupNonUniform
150                OpCapability GroupNonUniformArithmetic
151                OpCapability GroupNonUniformBallot
152                OpCapability GroupNonUniformQuad
153                OpCapability GroupNonUniformShuffle
154                OpCapability Image1D
155                OpCapability ImageBuffer
156                OpCapability ImageGatherExtended
157                OpCapability ImageMSArray
158                OpCapability ImageQuery
159                OpCapability InputAttachment
160                OpCapability InputAttachmentArrayNonUniformIndexing
161                OpCapability Int16
162                OpCapability Int64
163                OpCapability Int64Atomics
164                OpCapability Int64ImageEXT
165                OpCapability MeshShadingNV
166                OpCapability MinLod
167                OpCapability MultiView
168                OpCapability MultiViewport
169                OpCapability PhysicalStorageBufferAddresses
170                OpCapability RayQueryKHR
171                OpCapability RayTracingKHR
172                OpCapability RayTracingNV
173                OpCapability RayTraversalPrimitiveCullingKHR
174                OpCapability RuntimeDescriptorArray
175                OpCapability SampleMaskPostDepthCoverage
176                OpCapability SampleRateShading
177                OpCapability Sampled1D
178                OpCapability SampledBuffer
179                OpCapability SampledImageArrayNonUniformIndexing
180                OpCapability Shader
181                OpCapability ShaderClockKHR
182                OpCapability ShaderLayer
183                OpCapability ShaderNonUniform
184                OpCapability ShaderViewportIndex
185                OpCapability ShaderViewportIndexLayerEXT
186                OpCapability SparseResidency
187                OpCapability StencilExportEXT
188                OpCapability StorageImageArrayNonUniformIndexingEXT
189                OpCapability StorageImageExtendedFormats
190                OpCapability StorageImageReadWithoutFormat
191                OpCapability StorageImageWriteWithoutFormat
192                OpCapability StorageInputOutput16
193                OpCapability StoragePushConstant16
194                OpCapability StorageTexelBufferArrayNonUniformIndexing
195                OpCapability StorageUniform16
196                OpCapability StorageUniformBufferBlock16
197                OpCapability Tessellation
198                OpCapability UniformTexelBufferArrayNonUniformIndexing
199                OpCapability VulkanMemoryModel
200                OpExtension "SPV_EXT_fragment_fully_covered"
201                OpExtension "SPV_EXT_shader_image_int64"
202                OpExtension "SPV_EXT_shader_stencil_export"
203                OpExtension "SPV_EXT_shader_viewport_index_layer"
204                OpExtension "SPV_KHR_fragment_shader_barycentric"
205                OpExtension "SPV_KHR_fragment_shading_rate"
206                OpExtension "SPV_KHR_post_depth_coverage"
207                OpExtension "SPV_KHR_ray_query"
208                OpExtension "SPV_KHR_ray_tracing"
209                OpExtension "SPV_KHR_shader_clock"
210                OpExtension "SPV_NV_mesh_shader"
211                OpExtension "SPV_NV_ray_tracing"
212                OpExtension "SPV_NV_viewport_array2"
213 ; CHECK: OpCapability Linkage
214 ; CHECK: OpCapability ClipDistance
215 ; CHECK: OpCapability CullDistance
216 ; CHECK: OpCapability DemoteToHelperInvocation
217 ; CHECK: OpCapability DeviceGroup
218 ; CHECK: OpCapability DrawParameters
219 ; CHECK: OpCapability Float16
220 ; CHECK: OpCapability Float64
221 ; CHECK: OpCapability FragmentBarycentricKHR
222 ; CHECK: OpCapability FragmentFullyCoveredEXT
223 ; CHECK: OpCapability FragmentShadingRateKHR
224 ; CHECK: OpCapability GroupNonUniform
225 ; CHECK: OpCapability GroupNonUniformArithmetic
226 ; CHECK: OpCapability GroupNonUniformBallot
227 ; CHECK: OpCapability GroupNonUniformQuad
228 ; CHECK: OpCapability GroupNonUniformShuffle
229 ; CHECK: OpCapability Image1D
230 ; CHECK: OpCapability ImageBuffer
231 ; CHECK: OpCapability ImageGatherExtended
232 ; CHECK: OpCapability ImageMSArray
233 ; CHECK: OpCapability ImageQuery
234 ; CHECK: OpCapability InputAttachment
235 ; CHECK: OpCapability InputAttachmentArrayNonUniformIndexing
236 ; CHECK: OpCapability Int16
237 ; CHECK: OpCapability Int64
238 ; CHECK: OpCapability Int64Atomics
239 ; CHECK: OpCapability Int64ImageEXT
240 ; CHECK: OpCapability MeshShadingNV
241 ; CHECK: OpCapability MinLod
242 ; CHECK: OpCapability MultiView
243 ; CHECK: OpCapability MultiViewport
244 ; CHECK: OpCapability PhysicalStorageBufferAddresses
245 ; CHECK: OpCapability RayQueryKHR
246 ; CHECK: OpCapability RayTracingKHR
247 ; CHECK: OpCapability RayTracingNV
248 ; CHECK: OpCapability RayTraversalPrimitiveCullingKHR
249 ; CHECK: OpCapability RuntimeDescriptorArray
250 ; CHECK: OpCapability SampleMaskPostDepthCoverage
251 ; CHECK: OpCapability SampleRateShading
252 ; CHECK: OpCapability Sampled1D
253 ; CHECK: OpCapability SampledBuffer
254 ; CHECK: OpCapability SampledImageArrayNonUniformIndexing
255 ; CHECK: OpCapability Shader
256 ; CHECK: OpCapability ShaderClockKHR
257 ; CHECK: OpCapability ShaderLayer
258 ; CHECK: OpCapability ShaderNonUniform
259 ; CHECK: OpCapability ShaderViewportIndex
260 ; CHECK: OpCapability ShaderViewportIndexLayerEXT
261 ; CHECK: OpCapability SparseResidency
262 ; CHECK: OpCapability StencilExportEXT
263 ; CHECK: OpCapability StorageImageArrayNonUniformIndexing
264 ; CHECK: OpCapability StorageImageExtendedFormats
265 ; CHECK: OpCapability StorageImageReadWithoutFormat
266 ; CHECK: OpCapability StorageImageWriteWithoutFormat
267 ; CHECK: OpCapability StorageInputOutput16
268 ; CHECK: OpCapability StoragePushConstant16
269 ; CHECK: OpCapability StorageTexelBufferArrayNonUniformIndexing
270 ; CHECK: OpCapability Tessellation
271 ; CHECK: OpCapability UniformTexelBufferArrayNonUniformIndex
272 ; CHECK: OpCapability VulkanMemoryModel
273 ; CHECK: OpExtension "SPV_EXT_fragment_fully_covered"
274 ; CHECK: OpExtension "SPV_EXT_shader_image_int64"
275 ; CHECK: OpExtension "SPV_EXT_shader_stencil_export"
276 ; CHECK: OpExtension "SPV_EXT_shader_viewport_index_layer"
277 ; CHECK: OpExtension "SPV_KHR_fragment_shader_barycentric"
278 ; CHECK: OpExtension "SPV_KHR_fragment_shading_rate"
279 ; CHECK: OpExtension "SPV_KHR_post_depth_coverage"
280 ; CHECK: OpExtension "SPV_KHR_ray_query"
281 ; CHECK: OpExtension "SPV_KHR_ray_tracing"
282 ; CHECK: OpExtension "SPV_KHR_shader_clock"
283 ; CHECK: OpExtension "SPV_NV_mesh_shader"
284 ; CHECK: OpExtension "SPV_NV_ray_tracing"
285 ; CHECK: OpExtension "SPV_NV_viewport_array2"
286                OpMemoryModel Logical Vulkan
287        %void = OpTypeVoid
288           %3 = OpTypeFunction %void
289           %1 = OpFunction %void None %3
290           %6 = OpLabel
291                OpReturn
292                OpFunctionEnd;
293   )";
294   SetTargetEnv(SPV_ENV_VULKAN_1_3);
295   const auto result =
296       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
297   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
298 }
299 
TEST_F(TrimCapabilitiesPassTest,KeepShader)300 TEST_F(TrimCapabilitiesPassTest, KeepShader) {
301   const std::string kTest = R"(
302                OpCapability Shader
303 ; CHECK: OpCapability Shader
304                OpMemoryModel Logical GLSL450
305                OpEntryPoint GLCompute %1 "main"
306        %void = OpTypeVoid
307           %3 = OpTypeFunction %void
308           %1 = OpFunction %void None %3
309           %6 = OpLabel
310                OpReturn
311                OpFunctionEnd;
312   )";
313   const auto result =
314       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
315   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
316 }
317 
TEST_F(TrimCapabilitiesPassTest,KeepShaderClockWhenInUse)318 TEST_F(TrimCapabilitiesPassTest, KeepShaderClockWhenInUse) {
319   const std::string kTest = R"(
320                OpCapability Shader
321                OpCapability Int64
322                OpCapability ShaderClockKHR
323                OpExtension "SPV_KHR_shader_clock"
324 ; CHECK: OpCapability ShaderClockKHR
325 ; CHECK: OpExtension "SPV_KHR_shader_clock"
326                OpMemoryModel Logical GLSL450
327                OpEntryPoint GLCompute %1 "main"
328        %void = OpTypeVoid
329        %uint = OpTypeInt 32 0
330       %ulong = OpTypeInt 64 0
331       %scope = OpConstant %uint 1
332           %3 = OpTypeFunction %void
333           %1 = OpFunction %void None %3
334           %6 = OpLabel
335           %7 = OpReadClockKHR %ulong %scope
336                OpReturn
337                OpFunctionEnd;
338   )";
339   const auto result =
340       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
341   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
342 }
343 
TEST_F(TrimCapabilitiesPassTest,TrimShaderClockWhenUnused)344 TEST_F(TrimCapabilitiesPassTest, TrimShaderClockWhenUnused) {
345   const std::string kTest = R"(
346                OpCapability Shader
347                OpCapability Int64
348                OpCapability ShaderClockKHR
349                OpExtension "SPV_KHR_shader_clock"
350 ; CHECK-NOT: OpCapability ShaderClockKHR
351 ; CHECK-NOT: OpExtension "SPV_KHR_shader_clock"
352                OpMemoryModel Logical GLSL450
353                OpEntryPoint GLCompute %1 "main"
354        %void = OpTypeVoid
355           %3 = OpTypeFunction %void
356           %1 = OpFunction %void None %3
357           %6 = OpLabel
358                OpReturn
359                OpFunctionEnd;
360   )";
361   const auto result =
362       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
363   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
364 }
365 
TEST_F(TrimCapabilitiesPassTest,AMDShaderBallotExtensionRemains)366 TEST_F(TrimCapabilitiesPassTest, AMDShaderBallotExtensionRemains) {
367   const std::string kTest = R"(
368                OpCapability Shader
369                OpCapability Groups
370                OpExtension "SPV_AMD_shader_ballot"
371 ; CHECK: OpCapability Groups
372 ; CHECK: OpExtension "SPV_AMD_shader_ballot"
373                OpMemoryModel Logical GLSL450
374                OpEntryPoint GLCompute %1 "main"
375        %void = OpTypeVoid
376        %uint = OpTypeInt 32 0
377           %1 = OpTypeFunction %void
378      %uint_0 = OpConstant %uint 0
379           %2 = OpFunction %void None %1
380           %3 = OpLabel
381           %4 = OpGroupIAddNonUniformAMD %uint %uint_0 ExclusiveScan %uint_0
382                OpReturn
383                OpFunctionEnd;
384   )";
385   const auto result =
386       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
387   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
388 }
389 
TEST_F(TrimCapabilitiesPassTest,AMDShaderBallotExtensionRemoved)390 TEST_F(TrimCapabilitiesPassTest, AMDShaderBallotExtensionRemoved) {
391   const std::string kTest = R"(
392                OpCapability Shader
393                OpCapability Groups
394                OpExtension "SPV_AMD_shader_ballot"
395 ; CHECK-NOT: OpCapability Groups
396 ; CHECK-NOT: OpExtension "SPV_AMD_shader_ballot"
397                OpMemoryModel Logical GLSL450
398                OpEntryPoint GLCompute %1 "main"
399        %void = OpTypeVoid
400           %1 = OpTypeFunction %void
401           %2 = OpFunction %void None %1
402           %3 = OpLabel
403                OpReturn
404                OpFunctionEnd;
405   )";
406   const auto result =
407       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
408   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
409 }
410 
TEST_F(TrimCapabilitiesPassTest,MinLod_RemovedIfNotUsed)411 TEST_F(TrimCapabilitiesPassTest, MinLod_RemovedIfNotUsed) {
412   const std::string kTest = R"(
413                       OpCapability Shader
414                       OpCapability Sampled1D
415                       OpCapability MinLod
416 ; CHECK-NOT:          OpCapability MinLod
417                       OpMemoryModel Logical GLSL450
418                       OpEntryPoint GLCompute %1 "main"
419               %void = OpTypeVoid
420              %float = OpTypeFloat 32
421            %v3float = OpTypeVector %float 3
422            %v4float = OpTypeVector %float 4
423         %type_image = OpTypeImage %float Cube 2 0 0 1 Rgba32f
424     %ptr_type_image = OpTypePointer UniformConstant %type_image
425       %type_sampler = OpTypeSampler
426   %ptr_type_sampler = OpTypePointer UniformConstant %type_sampler
427            %float_0 = OpConstant %float 0
428          %float_000 = OpConstantComposite %v3float %float_0 %float_0 %float_0
429              %image = OpVariable %ptr_type_image UniformConstant
430            %sampler = OpVariable %ptr_type_sampler UniformConstant
431                  %1 = OpTypeFunction %void
432                  %2 = OpFunction %void None %1
433                  %3 = OpLabel
434                 %21 = OpLoad %type_image %image
435                 %22 = OpLoad %type_sampler %sampler
436                 %24 = OpSampledImage %type_sampled_image %21 %22
437                 %25 = OpImageSampleImplicitLod %v4float %24 %float_000
438                       OpReturn
439                       OpFunctionEnd;
440   )";
441   const auto result =
442       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
443   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
444 }
445 
TEST_F(TrimCapabilitiesPassTest,MinLod_RemainsWithOpImageSampleImplicitLod)446 TEST_F(TrimCapabilitiesPassTest, MinLod_RemainsWithOpImageSampleImplicitLod) {
447   const std::string kTest = R"(
448                       OpCapability Shader
449                       OpCapability Sampled1D
450                       OpCapability MinLod
451 ; CHECK:              OpCapability MinLod
452                       OpMemoryModel Logical GLSL450
453                       OpEntryPoint GLCompute %1 "main"
454               %void = OpTypeVoid
455              %float = OpTypeFloat 32
456            %v3float = OpTypeVector %float 3
457            %v4float = OpTypeVector %float 4
458         %type_image = OpTypeImage %float Cube 2 0 0 1 Rgba32f
459     %ptr_type_image = OpTypePointer UniformConstant %type_image
460       %type_sampler = OpTypeSampler
461   %ptr_type_sampler = OpTypePointer UniformConstant %type_sampler
462            %float_0 = OpConstant %float 0
463          %float_000 = OpConstantComposite %v3float %float_0 %float_0 %float_0
464              %image = OpVariable %ptr_type_image UniformConstant
465            %sampler = OpVariable %ptr_type_sampler UniformConstant
466                  %1 = OpTypeFunction %void
467                  %2 = OpFunction %void None %1
468                  %3 = OpLabel
469                 %21 = OpLoad %type_image %image
470                 %22 = OpLoad %type_sampler %sampler
471                 %24 = OpSampledImage %type_sampled_image %21 %22
472                 %25 = OpImageSampleImplicitLod %v4float %24 %float_000 MinLod %float_0
473                       OpReturn
474                       OpFunctionEnd;
475   )";
476   const auto result =
477       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
478   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
479 }
480 
TEST_F(TrimCapabilitiesPassTest,MinLod_RemainsWithOpImageSparseSampleImplicitLod)481 TEST_F(TrimCapabilitiesPassTest,
482        MinLod_RemainsWithOpImageSparseSampleImplicitLod) {
483   const std::string kTest = R"(
484                       OpCapability Shader
485                       OpCapability SparseResidency
486                       OpCapability ImageGatherExtended
487                       OpCapability MinLod
488 ; CHECK:              OpCapability MinLod
489                       OpMemoryModel Logical GLSL450
490                       OpEntryPoint Fragment %2 "main"
491                       OpExecutionMode %2 OriginUpperLeft
492               %void = OpTypeVoid
493               %uint = OpTypeInt 32 0
494              %float = OpTypeFloat 32
495            %v2float = OpTypeVector %float 2
496            %v3float = OpTypeVector %float 3
497            %v4float = OpTypeVector %float 4
498         %type_image = OpTypeImage %float 2D 2 0 0 1 Unknown
499     %ptr_type_image = OpTypePointer UniformConstant %type_image
500       %type_sampler = OpTypeSampler
501   %ptr_type_sampler = OpTypePointer UniformConstant %type_sampler
502 %type_sampled_image = OpTypeSampledImage %type_image
503      %sparse_struct = OpTypeStruct %uint %v4float
504            %float_0 = OpConstant %float 0
505           %float_00 = OpConstantComposite %v2float %float_0 %float_0
506          %float_000 = OpConstantComposite %v3float %float_0 %float_0 %float_0
507              %image = OpVariable %ptr_type_image UniformConstant
508            %sampler = OpVariable %ptr_type_sampler UniformConstant
509                  %1 = OpTypeFunction %void
510                  %2 = OpFunction %void None %1
511                  %3 = OpLabel
512                 %21 = OpLoad %type_image %image
513                 %22 = OpLoad %type_sampler %sampler
514                 %24 = OpSampledImage %type_sampled_image %21 %22
515                 %25 = OpImageSparseSampleImplicitLod %sparse_struct %24 %float_00 MinLod %float_0
516                       OpReturn
517                       OpFunctionEnd;
518   )";
519   const auto result =
520       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
521   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
522 }
523 
TEST_F(TrimCapabilitiesPassTest,MinLod_DetectsMinLodWithBitmaskImageOperand)524 TEST_F(TrimCapabilitiesPassTest, MinLod_DetectsMinLodWithBitmaskImageOperand) {
525   const std::string kTest = R"(
526                             OpCapability MinLod
527 ; CHECK:                    OpCapability MinLod
528                             OpCapability Shader
529                             OpCapability SparseResidency
530                             OpCapability ImageGatherExtended
531                             OpMemoryModel Logical GLSL450
532                             OpEntryPoint Fragment %1 "main"
533                             OpExecutionMode %1 OriginUpperLeft
534             %type_sampler = OpTypeSampler
535                      %int = OpTypeInt 32 1
536                    %float = OpTypeFloat 32
537                    %v2int = OpTypeVector %int 2
538                  %v2float = OpTypeVector %float 2
539                  %v4float = OpTypeVector %float 4
540              %ptr_sampler = OpTypePointer UniformConstant %type_sampler
541               %type_image = OpTypeImage %float 2D 2 0 0 1 Unknown
542                %ptr_image = OpTypePointer UniformConstant %type_image
543                     %void = OpTypeVoid
544                     %uint = OpTypeInt 32 0
545       %type_sampled_image = OpTypeSampledImage %type_image
546              %type_struct = OpTypeStruct %uint %v4float
547 
548                    %int_1 = OpConstant %int 1
549                  %float_0 = OpConstant %float 0
550                  %float_1 = OpConstant %float 1
551                        %8 = OpConstantComposite %v2float %float_0 %float_0
552                       %12 = OpConstantComposite %v2int %int_1 %int_1
553 
554                        %2 = OpVariable %ptr_sampler UniformConstant
555                        %3 = OpVariable %ptr_image UniformConstant
556                       %27 = OpTypeFunction %void
557                        %1 = OpFunction %void None %27
558                       %28 = OpLabel
559                       %29 = OpLoad %type_image %3
560                       %30 = OpLoad %type_sampler %2
561                       %31 = OpSampledImage %type_sampled_image %29 %30
562                       %32 = OpImageSparseSampleImplicitLod %type_struct %31 %8 ConstOffset|MinLod %12 %float_0
563                             OpReturn
564                             OpFunctionEnd
565   )";
566   const auto result =
567       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
568   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
569 }
570 
TEST_F(TrimCapabilitiesPassTest,StorageInputOutput16_RemainsWithInputPointer_Vulkan1_0)571 TEST_F(TrimCapabilitiesPassTest,
572        StorageInputOutput16_RemainsWithInputPointer_Vulkan1_0) {
573   const std::string kTest = R"(
574                       OpCapability Shader
575                       OpCapability Float16
576                       OpCapability StorageInputOutput16
577                       OpExtension "SPV_KHR_16bit_storage"
578 ; CHECK:              OpCapability StorageInputOutput16
579 ; CHECK:              OpExtension "SPV_KHR_16bit_storage"
580                       OpMemoryModel Logical GLSL450
581                       OpEntryPoint GLCompute %2 "main"
582               %void = OpTypeVoid
583               %half = OpTypeFloat 16
584                %ptr = OpTypePointer Input %half
585                  %1 = OpTypeFunction %void
586                  %2 = OpFunction %void None %1
587                  %3 = OpLabel
588                       OpReturn
589                       OpFunctionEnd
590   )";
591   SetTargetEnv(SPV_ENV_VULKAN_1_0);
592   const auto result =
593       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
594   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
595 }
596 
TEST_F(TrimCapabilitiesPassTest,StorageInputOutput16_RemainsWithInputPointer_Vulkan1_1)597 TEST_F(TrimCapabilitiesPassTest,
598        StorageInputOutput16_RemainsWithInputPointer_Vulkan1_1) {
599   const std::string kTest = R"(
600                       OpCapability Shader
601                       OpCapability Float16
602                       OpCapability StorageInputOutput16
603                       OpExtension "SPV_KHR_16bit_storage"
604 ; CHECK:              OpCapability StorageInputOutput16
605 ; CHECK-NOT:          OpExtension "SPV_KHR_16bit_storage"
606                       OpMemoryModel Logical GLSL450
607                       OpEntryPoint GLCompute %2 "main"
608               %void = OpTypeVoid
609               %half = OpTypeFloat 16
610                %ptr = OpTypePointer Input %half
611                  %1 = OpTypeFunction %void
612                  %2 = OpFunction %void None %1
613                  %3 = OpLabel
614                       OpReturn
615                       OpFunctionEnd
616   )";
617   SetTargetEnv(SPV_ENV_VULKAN_1_1);
618   const auto result =
619       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
620   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
621 }
622 
TEST_F(TrimCapabilitiesPassTest,StorageInputOutput16_RemainsWithInputPointerArray_Vulkan1_0)623 TEST_F(TrimCapabilitiesPassTest,
624        StorageInputOutput16_RemainsWithInputPointerArray_Vulkan1_0) {
625   const std::string kTest = R"(
626                       OpCapability Shader
627                       OpCapability Float16
628                       OpCapability StorageInputOutput16
629                       OpExtension "SPV_KHR_16bit_storage"
630 ; CHECK:              OpCapability StorageInputOutput16
631 ; CHECK:              OpExtension "SPV_KHR_16bit_storage"
632                       OpMemoryModel Logical GLSL450
633                       OpEntryPoint GLCompute %2 "main"
634               %void = OpTypeVoid
635               %half = OpTypeFloat 16
636               %uint = OpTypeInt 32 0
637             %uint_1 = OpConstant %uint 1
638              %array = OpTypeArray %half %uint_1
639                %ptr = OpTypePointer Input %array
640                  %1 = OpTypeFunction %void
641                  %2 = OpFunction %void None %1
642                  %3 = OpLabel
643                       OpReturn
644                       OpFunctionEnd
645   )";
646   SetTargetEnv(SPV_ENV_VULKAN_1_0);
647   const auto result =
648       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
649   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
650 }
651 
TEST_F(TrimCapabilitiesPassTest,StorageInputOutput16_RemainsWithInputPointerArray_Vulkan1_1)652 TEST_F(TrimCapabilitiesPassTest,
653        StorageInputOutput16_RemainsWithInputPointerArray_Vulkan1_1) {
654   const std::string kTest = R"(
655                       OpCapability Shader
656                       OpCapability Float16
657                       OpCapability StorageInputOutput16
658                       OpExtension "SPV_KHR_16bit_storage"
659 ; CHECK:              OpCapability StorageInputOutput16
660 ; CHECK-NOT:          OpExtension "SPV_KHR_16bit_storage"
661                       OpMemoryModel Logical GLSL450
662                       OpEntryPoint GLCompute %2 "main"
663               %void = OpTypeVoid
664               %half = OpTypeFloat 16
665               %uint = OpTypeInt 32 0
666             %uint_1 = OpConstant %uint 1
667              %array = OpTypeArray %half %uint_1
668                %ptr = OpTypePointer Input %array
669                  %1 = OpTypeFunction %void
670                  %2 = OpFunction %void None %1
671                  %3 = OpLabel
672                       OpReturn
673                       OpFunctionEnd
674   )";
675   SetTargetEnv(SPV_ENV_VULKAN_1_1);
676   const auto result =
677       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
678   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
679 }
680 
TEST_F(TrimCapabilitiesPassTest,StorageInputOutput16_RemainsWithInputPointerStruct_Vulkan1_0)681 TEST_F(TrimCapabilitiesPassTest,
682        StorageInputOutput16_RemainsWithInputPointerStruct_Vulkan1_0) {
683   const std::string kTest = R"(
684                       OpCapability Shader
685                       OpCapability Float16
686                       OpCapability StorageInputOutput16
687                       OpExtension "SPV_KHR_16bit_storage"
688 ; CHECK:              OpCapability StorageInputOutput16
689 ; CHECK:              OpExtension "SPV_KHR_16bit_storage"
690                       OpMemoryModel Logical GLSL450
691                       OpEntryPoint GLCompute %2 "main"
692               %void = OpTypeVoid
693               %half = OpTypeFloat 16
694             %struct = OpTypeStruct %half
695                %ptr = OpTypePointer Input %struct
696                  %1 = OpTypeFunction %void
697                  %2 = OpFunction %void None %1
698                  %3 = OpLabel
699                       OpReturn
700                       OpFunctionEnd
701   )";
702   SetTargetEnv(SPV_ENV_VULKAN_1_0);
703   const auto result =
704       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
705   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
706 }
707 
TEST_F(TrimCapabilitiesPassTest,StorageInputOutput16_RemainsWithInputPointerStruct_Vulkan1_1)708 TEST_F(TrimCapabilitiesPassTest,
709        StorageInputOutput16_RemainsWithInputPointerStruct_Vulkan1_1) {
710   const std::string kTest = R"(
711                       OpCapability Shader
712                       OpCapability Float16
713                       OpCapability StorageInputOutput16
714                       OpExtension "SPV_KHR_16bit_storage"
715 ; CHECK:              OpCapability StorageInputOutput16
716 ; CHECK-NOT:          OpExtension "SPV_KHR_16bit_storage"
717                       OpMemoryModel Logical GLSL450
718                       OpEntryPoint GLCompute %2 "main"
719               %void = OpTypeVoid
720               %half = OpTypeFloat 16
721             %struct = OpTypeStruct %half
722                %ptr = OpTypePointer Input %struct
723                  %1 = OpTypeFunction %void
724                  %2 = OpFunction %void None %1
725                  %3 = OpLabel
726                       OpReturn
727                       OpFunctionEnd
728   )";
729   SetTargetEnv(SPV_ENV_VULKAN_1_1);
730   const auto result =
731       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
732   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
733 }
734 
TEST_F(TrimCapabilitiesPassTest,StorageInputOutput16_RemainsWithInputPointerStructOfStruct_Vulkan1_0)735 TEST_F(TrimCapabilitiesPassTest,
736        StorageInputOutput16_RemainsWithInputPointerStructOfStruct_Vulkan1_0) {
737   const std::string kTest = R"(
738                       OpCapability Shader
739                       OpCapability Float16
740                       OpCapability StorageInputOutput16
741                       OpExtension "SPV_KHR_16bit_storage"
742 ; CHECK:              OpCapability StorageInputOutput16
743 ; CHECK:              OpExtension "SPV_KHR_16bit_storage"
744                       OpMemoryModel Logical GLSL450
745                       OpEntryPoint GLCompute %2 "main"
746               %void = OpTypeVoid
747               %half = OpTypeFloat 16
748              %float = OpTypeFloat 32
749             %struct = OpTypeStruct %float %half
750             %parent = OpTypeStruct %float %struct
751                %ptr = OpTypePointer Input %parent
752                  %1 = OpTypeFunction %void
753                  %2 = OpFunction %void None %1
754                  %3 = OpLabel
755                       OpReturn
756                       OpFunctionEnd
757   )";
758   SetTargetEnv(SPV_ENV_VULKAN_1_0);
759   const auto result =
760       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
761   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
762 }
763 
TEST_F(TrimCapabilitiesPassTest,StorageInputOutput16_RemainsWithInputPointerStructOfStruct_Vulkan1_1)764 TEST_F(TrimCapabilitiesPassTest,
765        StorageInputOutput16_RemainsWithInputPointerStructOfStruct_Vulkan1_1) {
766   const std::string kTest = R"(
767                       OpCapability Shader
768                       OpCapability Float16
769                       OpCapability StorageInputOutput16
770                       OpExtension "SPV_KHR_16bit_storage"
771 ; CHECK:              OpCapability StorageInputOutput16
772 ; CHECK-NOT:          OpExtension "SPV_KHR_16bit_storage"
773                       OpMemoryModel Logical GLSL450
774                       OpEntryPoint GLCompute %2 "main"
775               %void = OpTypeVoid
776               %half = OpTypeFloat 16
777              %float = OpTypeFloat 32
778             %struct = OpTypeStruct %float %half
779             %parent = OpTypeStruct %float %struct
780                %ptr = OpTypePointer Input %parent
781                  %1 = OpTypeFunction %void
782                  %2 = OpFunction %void None %1
783                  %3 = OpLabel
784                       OpReturn
785                       OpFunctionEnd
786   )";
787   SetTargetEnv(SPV_ENV_VULKAN_1_1);
788   const auto result =
789       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
790   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
791 }
792 
TEST_F(TrimCapabilitiesPassTest,StorageInputOutput16_RemainsWithInputPointerArrayOfStruct_Vulkan1_0)793 TEST_F(TrimCapabilitiesPassTest,
794        StorageInputOutput16_RemainsWithInputPointerArrayOfStruct_Vulkan1_0) {
795   const std::string kTest = R"(
796                       OpCapability Shader
797                       OpCapability Float16
798                       OpCapability StorageInputOutput16
799                       OpExtension "SPV_KHR_16bit_storage"
800 ; CHECK:              OpCapability StorageInputOutput16
801 ; CHECK:              OpExtension "SPV_KHR_16bit_storage"
802                       OpMemoryModel Logical GLSL450
803                       OpEntryPoint GLCompute %2 "main"
804               %void = OpTypeVoid
805               %half = OpTypeFloat 16
806             %struct = OpTypeStruct %half
807               %uint = OpTypeInt 32 0
808             %uint_1 = OpConstant %uint 1
809              %array = OpTypeArray %struct %uint_1
810                %ptr = OpTypePointer Input %array
811                  %1 = OpTypeFunction %void
812                  %2 = OpFunction %void None %1
813                  %3 = OpLabel
814                       OpReturn
815                       OpFunctionEnd
816   )";
817   SetTargetEnv(SPV_ENV_VULKAN_1_0);
818   const auto result =
819       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
820   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
821 }
822 
TEST_F(TrimCapabilitiesPassTest,StorageInputOutput16_RemainsWithInputPointerArrayOfStruct_Vulkan1_1)823 TEST_F(TrimCapabilitiesPassTest,
824        StorageInputOutput16_RemainsWithInputPointerArrayOfStruct_Vulkan1_1) {
825   const std::string kTest = R"(
826                       OpCapability Shader
827                       OpCapability Float16
828                       OpCapability StorageInputOutput16
829                       OpExtension "SPV_KHR_16bit_storage"
830 ; CHECK:              OpCapability StorageInputOutput16
831 ; CHECK-NOT:          OpExtension "SPV_KHR_16bit_storage"
832                       OpMemoryModel Logical GLSL450
833                       OpEntryPoint GLCompute %2 "main"
834               %void = OpTypeVoid
835               %half = OpTypeFloat 16
836             %struct = OpTypeStruct %half
837               %uint = OpTypeInt 32 0
838             %uint_1 = OpConstant %uint 1
839              %array = OpTypeArray %struct %uint_1
840                %ptr = OpTypePointer Input %array
841                  %1 = OpTypeFunction %void
842                  %2 = OpFunction %void None %1
843                  %3 = OpLabel
844                       OpReturn
845                       OpFunctionEnd
846   )";
847   SetTargetEnv(SPV_ENV_VULKAN_1_1);
848   const auto result =
849       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
850   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
851 }
852 
TEST_F(TrimCapabilitiesPassTest,StorageInputOutput16_RemainsWithInputPointerVector_Vulkan1_0)853 TEST_F(TrimCapabilitiesPassTest,
854        StorageInputOutput16_RemainsWithInputPointerVector_Vulkan1_0) {
855   const std::string kTest = R"(
856                       OpCapability Shader
857                       OpCapability Float16
858                       OpCapability StorageInputOutput16
859                       OpExtension "SPV_KHR_16bit_storage"
860 ; CHECK:              OpCapability StorageInputOutput16
861 ; CHECK:              OpExtension "SPV_KHR_16bit_storage"
862                       OpMemoryModel Logical GLSL450
863                       OpEntryPoint GLCompute %2 "main"
864               %void = OpTypeVoid
865               %half = OpTypeFloat 16
866             %vector = OpTypeVector %half 4
867                %ptr = OpTypePointer Input %vector
868                  %1 = OpTypeFunction %void
869                  %2 = OpFunction %void None %1
870                  %3 = OpLabel
871                       OpReturn
872                       OpFunctionEnd
873   )";
874   SetTargetEnv(SPV_ENV_VULKAN_1_0);
875   const auto result =
876       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
877   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
878 }
879 
TEST_F(TrimCapabilitiesPassTest,StorageInputOutput16_RemainsWithInputPointerVector_Vulkan1_1)880 TEST_F(TrimCapabilitiesPassTest,
881        StorageInputOutput16_RemainsWithInputPointerVector_Vulkan1_1) {
882   const std::string kTest = R"(
883                       OpCapability Shader
884                       OpCapability Float16
885                       OpCapability StorageInputOutput16
886                       OpExtension "SPV_KHR_16bit_storage"
887 ; CHECK:              OpCapability StorageInputOutput16
888 ; CHECK-NOT:          OpExtension "SPV_KHR_16bit_storage"
889                       OpMemoryModel Logical GLSL450
890                       OpEntryPoint GLCompute %2 "main"
891               %void = OpTypeVoid
892               %half = OpTypeFloat 16
893             %vector = OpTypeVector %half 4
894                %ptr = OpTypePointer Input %vector
895                  %1 = OpTypeFunction %void
896                  %2 = OpFunction %void None %1
897                  %3 = OpLabel
898                       OpReturn
899                       OpFunctionEnd
900   )";
901   SetTargetEnv(SPV_ENV_VULKAN_1_1);
902   const auto result =
903       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
904   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
905 }
906 
TEST_F(TrimCapabilitiesPassTest,StorageInputOutput16_RemainsWithInputPointerMatrix_Vulkan1_0)907 TEST_F(TrimCapabilitiesPassTest,
908        StorageInputOutput16_RemainsWithInputPointerMatrix_Vulkan1_0) {
909   const std::string kTest = R"(
910                       OpCapability Shader
911                       OpCapability Float16
912                       OpCapability StorageInputOutput16
913                       OpExtension "SPV_KHR_16bit_storage"
914 ; CHECK:              OpCapability StorageInputOutput16
915 ; CHECK:              OpExtension "SPV_KHR_16bit_storage"
916                       OpMemoryModel Logical GLSL450
917                       OpEntryPoint GLCompute %2 "main"
918               %void = OpTypeVoid
919               %half = OpTypeFloat 16
920             %vector = OpTypeVector %half 4
921             %matrix = OpTypeMatrix %vector 4
922                %ptr = OpTypePointer Input %matrix
923                  %1 = OpTypeFunction %void
924                  %2 = OpFunction %void None %1
925                  %3 = OpLabel
926                       OpReturn
927                       OpFunctionEnd
928   )";
929   SetTargetEnv(SPV_ENV_VULKAN_1_0);
930   const auto result =
931       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
932   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
933 }
934 
TEST_F(TrimCapabilitiesPassTest,StorageInputOutput16_RemainsWithInputPointerMatrix_Vulkan1_1)935 TEST_F(TrimCapabilitiesPassTest,
936        StorageInputOutput16_RemainsWithInputPointerMatrix_Vulkan1_1) {
937   const std::string kTest = R"(
938                       OpCapability Shader
939                       OpCapability Float16
940                       OpCapability StorageInputOutput16
941                       OpExtension "SPV_KHR_16bit_storage"
942 ; CHECK:              OpCapability StorageInputOutput16
943 ; CHECK-NOT:          OpExtension "SPV_KHR_16bit_storage"
944                       OpMemoryModel Logical GLSL450
945                       OpEntryPoint GLCompute %2 "main"
946               %void = OpTypeVoid
947               %half = OpTypeFloat 16
948             %vector = OpTypeVector %half 4
949             %matrix = OpTypeMatrix %vector 4
950                %ptr = OpTypePointer Input %matrix
951                  %1 = OpTypeFunction %void
952                  %2 = OpFunction %void None %1
953                  %3 = OpLabel
954                       OpReturn
955                       OpFunctionEnd
956   )";
957   SetTargetEnv(SPV_ENV_VULKAN_1_1);
958   const auto result =
959       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
960   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
961 }
962 
TEST_F(TrimCapabilitiesPassTest,StorageInputOutput16_IsRemovedWithoutInputPointer)963 TEST_F(TrimCapabilitiesPassTest,
964        StorageInputOutput16_IsRemovedWithoutInputPointer) {
965   const std::string kTest = R"(
966                       OpCapability Shader
967                       OpCapability Float16
968                       OpCapability StorageInputOutput16
969                       OpExtension "SPV_KHR_16bit_storage"
970 ; CHECK-NOT:          OpCapability StorageInputOutput16
971 ; CHECK-NOT:          OpExtension "SPV_KHR_16bit_storage"
972                       OpMemoryModel Logical GLSL450
973                       OpEntryPoint GLCompute %2 "main"
974               %void = OpTypeVoid
975                  %1 = OpTypeFunction %void
976                  %2 = OpFunction %void None %1
977                  %3 = OpLabel
978                       OpReturn
979                       OpFunctionEnd
980   )";
981   SetTargetEnv(SPV_ENV_VULKAN_1_0);
982   const auto result =
983       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
984   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
985 }
986 
TEST_F(TrimCapabilitiesPassTest,StorageInputOutput16_RemainsWithOutputPointer_Vulkan1_0)987 TEST_F(TrimCapabilitiesPassTest,
988        StorageInputOutput16_RemainsWithOutputPointer_Vulkan1_0) {
989   const std::string kTest = R"(
990                       OpCapability Shader
991                       OpCapability Float16
992                       OpCapability StorageInputOutput16
993                       OpExtension "SPV_KHR_16bit_storage"
994 ; CHECK:              OpCapability StorageInputOutput16
995 ; CHECK:              OpExtension "SPV_KHR_16bit_storage"
996                       OpMemoryModel Logical GLSL450
997                       OpEntryPoint GLCompute %2 "main"
998               %void = OpTypeVoid
999               %half = OpTypeFloat 16
1000                %ptr = OpTypePointer Output %half
1001                  %1 = OpTypeFunction %void
1002                  %2 = OpFunction %void None %1
1003                  %3 = OpLabel
1004                       OpReturn
1005                       OpFunctionEnd
1006   )";
1007   SetTargetEnv(SPV_ENV_VULKAN_1_0);
1008   const auto result =
1009       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
1010   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
1011 }
1012 
TEST_F(TrimCapabilitiesPassTest,StorageInputOutput16_RemainsWithOutputPointer_Vulkan1_1)1013 TEST_F(TrimCapabilitiesPassTest,
1014        StorageInputOutput16_RemainsWithOutputPointer_Vulkan1_1) {
1015   const std::string kTest = R"(
1016                       OpCapability Shader
1017                       OpCapability Float16
1018                       OpCapability StorageInputOutput16
1019                       OpExtension "SPV_KHR_16bit_storage"
1020 ; CHECK:              OpCapability StorageInputOutput16
1021 ; CHECK-NOT:          OpExtension "SPV_KHR_16bit_storage"
1022                       OpMemoryModel Logical GLSL450
1023                       OpEntryPoint GLCompute %2 "main"
1024               %void = OpTypeVoid
1025               %half = OpTypeFloat 16
1026                %ptr = OpTypePointer Output %half
1027                  %1 = OpTypeFunction %void
1028                  %2 = OpFunction %void None %1
1029                  %3 = OpLabel
1030                       OpReturn
1031                       OpFunctionEnd
1032   )";
1033   SetTargetEnv(SPV_ENV_VULKAN_1_1);
1034   const auto result =
1035       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
1036   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
1037 }
1038 
TEST_F(TrimCapabilitiesPassTest,StorageInputOutput16_RemovedWithoutOutputPointer)1039 TEST_F(TrimCapabilitiesPassTest,
1040        StorageInputOutput16_RemovedWithoutOutputPointer) {
1041   const std::string kTest = R"(
1042                       OpCapability Shader
1043                       OpCapability Float16
1044                       OpCapability StorageInputOutput16
1045                       OpExtension "SPV_KHR_16bit_storage"
1046 ; CHECK-NOT:          OpCapability StorageInputOutput16
1047 ; CHECK-NOT:          OpExtension "SPV_KHR_16bit_storage"
1048                       OpMemoryModel Logical GLSL450
1049                       OpEntryPoint GLCompute %2 "main"
1050               %void = OpTypeVoid
1051                  %1 = OpTypeFunction %void
1052                  %2 = OpFunction %void None %1
1053                  %3 = OpLabel
1054                       OpReturn
1055                       OpFunctionEnd
1056   )";
1057   const auto result =
1058       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
1059   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
1060 }
1061 
TEST_F(TrimCapabilitiesPassTest,StoragePushConstant16_RemainsSimplePointer_Vulkan1_0)1062 TEST_F(TrimCapabilitiesPassTest,
1063        StoragePushConstant16_RemainsSimplePointer_Vulkan1_0) {
1064   const std::string kTest = R"(
1065                       OpCapability Shader
1066                       OpCapability Float16
1067                       OpCapability StoragePushConstant16
1068                       OpExtension "SPV_KHR_16bit_storage"
1069 ; CHECK:              OpCapability StoragePushConstant16
1070 ; CHECK:              OpExtension "SPV_KHR_16bit_storage"
1071                       OpMemoryModel Logical GLSL450
1072                       OpEntryPoint GLCompute %2 "main"
1073               %void = OpTypeVoid
1074               %half = OpTypeFloat 16
1075                %ptr = OpTypePointer PushConstant %half
1076                  %1 = OpTypeFunction %void
1077                  %2 = OpFunction %void None %1
1078                  %3 = OpLabel
1079                       OpReturn
1080                       OpFunctionEnd
1081   )";
1082   SetTargetEnv(SPV_ENV_VULKAN_1_0);
1083   const auto result =
1084       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
1085   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
1086 }
1087 
TEST_F(TrimCapabilitiesPassTest,StoragePushConstant16_RemainsSimplePointer_Vulkan1_1)1088 TEST_F(TrimCapabilitiesPassTest,
1089        StoragePushConstant16_RemainsSimplePointer_Vulkan1_1) {
1090   const std::string kTest = R"(
1091                       OpCapability Shader
1092                       OpCapability Float16
1093                       OpCapability StoragePushConstant16
1094                       OpExtension "SPV_KHR_16bit_storage"
1095 ; CHECK:              OpCapability StoragePushConstant16
1096 ; CHECK-NOT:          OpExtension "SPV_KHR_16bit_storage"
1097                       OpMemoryModel Logical GLSL450
1098                       OpEntryPoint GLCompute %2 "main"
1099               %void = OpTypeVoid
1100               %half = OpTypeFloat 16
1101                %ptr = OpTypePointer PushConstant %half
1102                  %1 = OpTypeFunction %void
1103                  %2 = OpFunction %void None %1
1104                  %3 = OpLabel
1105                       OpReturn
1106                       OpFunctionEnd
1107   )";
1108   SetTargetEnv(SPV_ENV_VULKAN_1_1);
1109   const auto result =
1110       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
1111   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
1112 }
1113 
TEST_F(TrimCapabilitiesPassTest,StoragePushConstant16_RemovedSimplePointer)1114 TEST_F(TrimCapabilitiesPassTest, StoragePushConstant16_RemovedSimplePointer) {
1115   const std::string kTest = R"(
1116                       OpCapability Shader
1117                       OpCapability Float16
1118                       OpCapability StoragePushConstant16
1119                       OpExtension "SPV_KHR_16bit_storage"
1120 ; CHECK-NOT:          OpCapability StoragePushConstant16
1121 ; CHECK-NOT:          OpExtension "SPV_KHR_16bit_storage"
1122                       OpMemoryModel Logical GLSL450
1123                       OpEntryPoint GLCompute %2 "main"
1124               %void = OpTypeVoid
1125               %half = OpTypeFloat 16
1126                %ptr = OpTypePointer Function %half
1127                  %1 = OpTypeFunction %void
1128                  %2 = OpFunction %void None %1
1129                  %3 = OpLabel
1130                       OpReturn
1131                       OpFunctionEnd
1132   )";
1133   const auto result =
1134       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
1135   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
1136 }
1137 
TEST_F(TrimCapabilitiesPassTest,StorageUniformBufferBlock16_RemainsSimplePointer_Vulkan1_0)1138 TEST_F(TrimCapabilitiesPassTest,
1139        StorageUniformBufferBlock16_RemainsSimplePointer_Vulkan1_0) {
1140   // See https://github.com/KhronosGroup/SPIRV-Tools/issues/5354
1141   static_assert(spv::Capability::StorageUniformBufferBlock16 ==
1142                 spv::Capability::StorageBuffer16BitAccess);
1143 
1144   const std::string kTest = R"(
1145                       OpCapability Shader
1146                       OpCapability Float16
1147                       OpCapability StorageBuffer16BitAccess
1148                       OpExtension "SPV_KHR_16bit_storage"
1149 
1150 ; CHECK:              OpCapability StorageBuffer16BitAccess
1151 ;                                   `-> StorageUniformBufferBlock16
1152 ; CHECK:              OpExtension "SPV_KHR_16bit_storage"
1153 
1154                       OpMemoryModel Logical GLSL450
1155                       OpEntryPoint GLCompute %2 "main"
1156                       OpDecorate %struct BufferBlock
1157               %void = OpTypeVoid
1158               %half = OpTypeFloat 16
1159             %struct = OpTypeStruct %half
1160                %ptr = OpTypePointer Uniform %struct
1161                  %1 = OpTypeFunction %void
1162                  %2 = OpFunction %void None %1
1163                  %3 = OpLabel
1164                       OpReturn
1165                       OpFunctionEnd
1166   )";
1167   SetTargetEnv(SPV_ENV_VULKAN_1_0);
1168   const auto result =
1169       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
1170   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
1171 }
1172 
TEST_F(TrimCapabilitiesPassTest,StorageUniformBufferBlock16_RemainsSimplePointer_Vulkan1_1)1173 TEST_F(TrimCapabilitiesPassTest,
1174        StorageUniformBufferBlock16_RemainsSimplePointer_Vulkan1_1) {
1175   // See https://github.com/KhronosGroup/SPIRV-Tools/issues/5354
1176   static_assert(spv::Capability::StorageUniformBufferBlock16 ==
1177                 spv::Capability::StorageBuffer16BitAccess);
1178 
1179   const std::string kTest = R"(
1180                       OpCapability Shader
1181                       OpCapability Float16
1182                       OpCapability StorageBuffer16BitAccess
1183                       OpExtension "SPV_KHR_16bit_storage"
1184 
1185 ; CHECK:              OpCapability StorageBuffer16BitAccess
1186 ;                                   `-> StorageUniformBufferBlock16
1187 ; CHECK-NOT:          OpExtension "SPV_KHR_16bit_storage"
1188 
1189                       OpMemoryModel Logical GLSL450
1190                       OpEntryPoint GLCompute %2 "main"
1191                       OpDecorate %struct BufferBlock
1192               %void = OpTypeVoid
1193               %half = OpTypeFloat 16
1194             %struct = OpTypeStruct %half
1195                %ptr = OpTypePointer Uniform %struct
1196                  %1 = OpTypeFunction %void
1197                  %2 = OpFunction %void None %1
1198                  %3 = OpLabel
1199                       OpReturn
1200                       OpFunctionEnd
1201   )";
1202   SetTargetEnv(SPV_ENV_VULKAN_1_1);
1203   const auto result =
1204       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
1205   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
1206 }
1207 
TEST_F(TrimCapabilitiesPassTest,StorageUniformBufferBlock16_RemovedSimplePointer)1208 TEST_F(TrimCapabilitiesPassTest,
1209        StorageUniformBufferBlock16_RemovedSimplePointer) {
1210   // See https://github.com/KhronosGroup/SPIRV-Tools/issues/5354
1211   static_assert(spv::Capability::StorageUniformBufferBlock16 ==
1212                 spv::Capability::StorageBuffer16BitAccess);
1213 
1214   const std::string kTest = R"(
1215                       OpCapability Shader
1216                       OpCapability Float16
1217                       OpCapability StorageBuffer16BitAccess
1218                       OpExtension "SPV_KHR_16bit_storage"
1219 
1220 ; CHECK-NOT:          OpCapability StorageBuffer16BitAccess
1221 ;                                   `-> StorageUniformBufferBlock16
1222 ; CHECK-NOT:          OpExtension "SPV_KHR_16bit_storage"
1223 
1224                       OpMemoryModel Logical GLSL450
1225                       OpEntryPoint GLCompute %2 "main"
1226               %void = OpTypeVoid
1227               %half = OpTypeFloat 16
1228             %struct = OpTypeStruct %half
1229                %ptr = OpTypePointer Function %struct
1230                  %1 = OpTypeFunction %void
1231                  %2 = OpFunction %void None %1
1232                  %3 = OpLabel
1233                       OpReturn
1234                       OpFunctionEnd
1235   )";
1236   const auto result =
1237       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
1238   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
1239 }
1240 
TEST_F(TrimCapabilitiesPassTest,StorageUniform16_RemovedWithBufferBlockPointer_Vulkan1_0)1241 TEST_F(TrimCapabilitiesPassTest,
1242        StorageUniform16_RemovedWithBufferBlockPointer_Vulkan1_0) {
1243   // See https://github.com/KhronosGroup/SPIRV-Tools/issues/5354
1244   static_assert(spv::Capability::StorageUniformBufferBlock16 ==
1245                 spv::Capability::StorageBuffer16BitAccess);
1246   static_assert(spv::Capability::StorageUniform16 ==
1247                 spv::Capability::UniformAndStorageBuffer16BitAccess);
1248 
1249   const std::string kTest = R"(
1250                       OpCapability Shader
1251                       OpCapability Float16
1252                       OpCapability StorageBuffer16BitAccess
1253                       OpCapability UniformAndStorageBuffer16BitAccess
1254                       OpExtension "SPV_KHR_16bit_storage"
1255 
1256 ; CHECK:              OpCapability StorageBuffer16BitAccess
1257 ;                                   `-> StorageUniformBufferBlock16
1258 ; CHECK-NOT:          OpCapability UniformAndStorageBuffer16BitAccess
1259 ;                                   `-> StorageUniform16
1260 ; CHECK:              OpExtension "SPV_KHR_16bit_storage"
1261 
1262                       OpMemoryModel Logical GLSL450
1263                       OpEntryPoint GLCompute %2 "main"
1264                       OpDecorate %struct BufferBlock
1265               %void = OpTypeVoid
1266               %half = OpTypeFloat 16
1267             %struct = OpTypeStruct %half
1268                %ptr = OpTypePointer Uniform %struct
1269                  %1 = OpTypeFunction %void
1270                  %2 = OpFunction %void None %1
1271                  %3 = OpLabel
1272                       OpReturn
1273                       OpFunctionEnd
1274   )";
1275   SetTargetEnv(SPV_ENV_VULKAN_1_0);
1276   const auto result =
1277       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
1278   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
1279 }
1280 
TEST_F(TrimCapabilitiesPassTest,StorageUniform16_RemovedWithBufferBlockPointer_Vulkan1_1)1281 TEST_F(TrimCapabilitiesPassTest,
1282        StorageUniform16_RemovedWithBufferBlockPointer_Vulkan1_1) {
1283   // See https://github.com/KhronosGroup/SPIRV-Tools/issues/5354
1284   static_assert(spv::Capability::StorageUniformBufferBlock16 ==
1285                 spv::Capability::StorageBuffer16BitAccess);
1286   static_assert(spv::Capability::StorageUniform16 ==
1287                 spv::Capability::UniformAndStorageBuffer16BitAccess);
1288 
1289   const std::string kTest = R"(
1290                       OpCapability Shader
1291                       OpCapability Float16
1292                       OpCapability StorageBuffer16BitAccess
1293                       OpCapability UniformAndStorageBuffer16BitAccess
1294                       OpExtension "SPV_KHR_16bit_storage"
1295 
1296 ; CHECK:              OpCapability StorageBuffer16BitAccess
1297 ;                                   `-> StorageUniformBufferBlock16
1298 ; CHECK-NOT:          OpCapability UniformAndStorageBuffer16BitAccess
1299 ;                                   `-> StorageUniform16
1300 ; CHECK-NOT:          OpExtension "SPV_KHR_16bit_storage"
1301 
1302                       OpMemoryModel Logical GLSL450
1303                       OpEntryPoint GLCompute %2 "main"
1304                       OpDecorate %struct BufferBlock
1305               %void = OpTypeVoid
1306               %half = OpTypeFloat 16
1307             %struct = OpTypeStruct %half
1308                %ptr = OpTypePointer Uniform %struct
1309                  %1 = OpTypeFunction %void
1310                  %2 = OpFunction %void None %1
1311                  %3 = OpLabel
1312                       OpReturn
1313                       OpFunctionEnd
1314   )";
1315   SetTargetEnv(SPV_ENV_VULKAN_1_1);
1316   const auto result =
1317       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
1318   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
1319 }
1320 
TEST_F(TrimCapabilitiesPassTest,StorageUniform16_RemovedWithNonBlockUniformPointer_Vulkan1_0)1321 TEST_F(TrimCapabilitiesPassTest,
1322        StorageUniform16_RemovedWithNonBlockUniformPointer_Vulkan1_0) {
1323   // See https://github.com/KhronosGroup/SPIRV-Tools/issues/5354
1324   static_assert(spv::Capability::StorageUniformBufferBlock16 ==
1325                 spv::Capability::StorageBuffer16BitAccess);
1326   static_assert(spv::Capability::StorageUniform16 ==
1327                 spv::Capability::UniformAndStorageBuffer16BitAccess);
1328 
1329   const std::string kTest = R"(
1330                       OpCapability Shader
1331                       OpCapability Float16
1332                       OpCapability StorageBuffer16BitAccess
1333                       OpCapability UniformAndStorageBuffer16BitAccess
1334                       OpExtension "SPV_KHR_16bit_storage"
1335 
1336 ; CHECK-NOT:          OpCapability StorageBuffer16BitAccess
1337 ;                                   `-> StorageUniformBufferBlock16
1338 ; CHECK:              OpCapability UniformAndStorageBuffer16BitAccess
1339 ;                                   `-> StorageUniform16
1340 ; CHECK:              OpExtension "SPV_KHR_16bit_storage"
1341 
1342                       OpMemoryModel Logical GLSL450
1343                       OpEntryPoint GLCompute %2 "main"
1344               %void = OpTypeVoid
1345               %half = OpTypeFloat 16
1346             %struct = OpTypeStruct %half
1347                %ptr = OpTypePointer Uniform %struct
1348                  %1 = OpTypeFunction %void
1349                  %2 = OpFunction %void None %1
1350                  %3 = OpLabel
1351                       OpReturn
1352                       OpFunctionEnd
1353   )";
1354   SetTargetEnv(SPV_ENV_VULKAN_1_0);
1355   const auto result =
1356       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
1357   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
1358 }
1359 
TEST_F(TrimCapabilitiesPassTest,StorageUniform16_RemovedWithNonBlockUniformPointer_Vulkan1_1)1360 TEST_F(TrimCapabilitiesPassTest,
1361        StorageUniform16_RemovedWithNonBlockUniformPointer_Vulkan1_1) {
1362   // See https://github.com/KhronosGroup/SPIRV-Tools/issues/5354
1363   static_assert(spv::Capability::StorageUniformBufferBlock16 ==
1364                 spv::Capability::StorageBuffer16BitAccess);
1365   static_assert(spv::Capability::StorageUniform16 ==
1366                 spv::Capability::UniformAndStorageBuffer16BitAccess);
1367 
1368   const std::string kTest = R"(
1369                       OpCapability Shader
1370                       OpCapability Float16
1371                       OpCapability StorageBuffer16BitAccess
1372                       OpCapability UniformAndStorageBuffer16BitAccess
1373                       OpExtension "SPV_KHR_16bit_storage"
1374 
1375 ; CHECK-NOT:          OpCapability StorageBuffer16BitAccess
1376 ;                                   `-> StorageUniformBufferBlock16
1377 ; CHECK:              OpCapability UniformAndStorageBuffer16BitAccess
1378 ;                                   `-> StorageUniform16
1379 ; CHECK-NOT:          OpExtension "SPV_KHR_16bit_storage"
1380 
1381                       OpMemoryModel Logical GLSL450
1382                       OpEntryPoint GLCompute %2 "main"
1383               %void = OpTypeVoid
1384               %half = OpTypeFloat 16
1385             %struct = OpTypeStruct %half
1386                %ptr = OpTypePointer Uniform %struct
1387                  %1 = OpTypeFunction %void
1388                  %2 = OpFunction %void None %1
1389                  %3 = OpLabel
1390                       OpReturn
1391                       OpFunctionEnd
1392   )";
1393   SetTargetEnv(SPV_ENV_VULKAN_1_1);
1394   const auto result =
1395       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
1396   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
1397 }
1398 
TEST_F(TrimCapabilitiesPassTest,FragmentShaderInterlock_RemovedIfNotUsed)1399 TEST_F(TrimCapabilitiesPassTest, FragmentShaderInterlock_RemovedIfNotUsed) {
1400   const std::string kTest = R"(
1401                OpCapability Shader
1402                OpCapability FragmentShaderPixelInterlockEXT
1403                OpCapability FragmentShaderSampleInterlockEXT
1404                OpCapability FragmentShaderShadingRateInterlockEXT
1405                OpExtension "SPV_EXT_fragment_shader_interlock"
1406 ; CHECK-NOT:   OpCapability FragmentShaderPixelInterlockEXT
1407 ; CHECK-NOT:   OpCapability FragmentShaderSampleInterlockEXT
1408 ; CHECK-NOT:   OpCapability FragmentShaderShadingRateInterlockEXT
1409 ; CHECK-NOT:   OpExtension "SPV_EXT_fragment_shader_interlock"
1410                OpMemoryModel Logical GLSL450
1411                OpEntryPoint GLCompute %1 "main"
1412        %void = OpTypeVoid
1413           %1 = OpTypeFunction %void
1414           %2 = OpFunction %void None %1
1415           %3 = OpLabel
1416                OpReturn
1417                OpFunctionEnd;
1418   )";
1419   const auto result =
1420       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
1421   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
1422 }
1423 
TEST_F(TrimCapabilitiesPassTest,FragmentShaderPixelInterlock_RemainsWhenOrderedIsUsed)1424 TEST_F(TrimCapabilitiesPassTest,
1425        FragmentShaderPixelInterlock_RemainsWhenOrderedIsUsed) {
1426   const std::string kTest = R"(
1427                OpCapability Shader
1428                OpCapability FragmentShaderPixelInterlockEXT
1429                OpCapability FragmentShaderSampleInterlockEXT
1430                OpCapability FragmentShaderShadingRateInterlockEXT
1431                OpExtension "SPV_EXT_fragment_shader_interlock"
1432 ; CHECK:       OpCapability FragmentShaderPixelInterlockEXT
1433 ; CHECK-NOT:   OpCapability FragmentShaderSampleInterlockEXT
1434 ; CHECK-NOT:   OpCapability FragmentShaderShadingRateInterlockEXT
1435 ; CHECK:       OpExtension "SPV_EXT_fragment_shader_interlock"
1436                OpMemoryModel Logical GLSL450
1437                OpEntryPoint GLCompute %1 "main"
1438                OpExecutionMode %main PixelInterlockOrderedEXT
1439        %void = OpTypeVoid
1440           %1 = OpTypeFunction %void
1441           %2 = OpFunction %void None %1
1442           %3 = OpLabel
1443                OpBeginInvocationInterlockEXT
1444                OpEndInvocationInterlockEXT
1445                OpReturn
1446                OpFunctionEnd;
1447   )";
1448   const auto result =
1449       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
1450   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
1451 }
1452 
TEST_F(TrimCapabilitiesPassTest,FragmentShaderPixelInterlock_RemainsWhenUnorderedIsUsed)1453 TEST_F(TrimCapabilitiesPassTest,
1454        FragmentShaderPixelInterlock_RemainsWhenUnorderedIsUsed) {
1455   const std::string kTest = R"(
1456                OpCapability Shader
1457                OpCapability FragmentShaderPixelInterlockEXT
1458                OpCapability FragmentShaderSampleInterlockEXT
1459                OpCapability FragmentShaderShadingRateInterlockEXT
1460                OpExtension "SPV_EXT_fragment_shader_interlock"
1461 ; CHECK:       OpCapability FragmentShaderPixelInterlockEXT
1462 ; CHECK-NOT:   OpCapability FragmentShaderSampleInterlockEXT
1463 ; CHECK-NOT:   OpCapability FragmentShaderShadingRateInterlockEXT
1464 ; CHECK:       OpExtension "SPV_EXT_fragment_shader_interlock"
1465                OpMemoryModel Logical GLSL450
1466                OpEntryPoint GLCompute %1 "main"
1467                OpExecutionMode %main PixelInterlockUnorderedEXT
1468        %void = OpTypeVoid
1469           %1 = OpTypeFunction %void
1470           %2 = OpFunction %void None %1
1471           %3 = OpLabel
1472                OpBeginInvocationInterlockEXT
1473                OpEndInvocationInterlockEXT
1474                OpReturn
1475                OpFunctionEnd;
1476   )";
1477   const auto result =
1478       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
1479   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
1480 }
1481 
TEST_F(TrimCapabilitiesPassTest,FragmentShaderSampleInterlock_RemainsWhenOrderedIsUsed)1482 TEST_F(TrimCapabilitiesPassTest,
1483        FragmentShaderSampleInterlock_RemainsWhenOrderedIsUsed) {
1484   const std::string kTest = R"(
1485                OpCapability Shader
1486                OpCapability FragmentShaderPixelInterlockEXT
1487                OpCapability FragmentShaderSampleInterlockEXT
1488                OpCapability FragmentShaderShadingRateInterlockEXT
1489                OpExtension "SPV_EXT_fragment_shader_interlock"
1490 ; CHECK-NOT:   OpCapability FragmentShaderPixelInterlockEXT
1491 ; CHECK:       OpCapability FragmentShaderSampleInterlockEXT
1492 ; CHECK-NOT:   OpCapability FragmentShaderShadingRateInterlockEXT
1493 ; CHECK:       OpExtension "SPV_EXT_fragment_shader_interlock"
1494                OpMemoryModel Logical GLSL450
1495                OpEntryPoint GLCompute %1 "main"
1496                OpExecutionMode %main SampleInterlockOrderedEXT
1497        %void = OpTypeVoid
1498           %1 = OpTypeFunction %void
1499           %2 = OpFunction %void None %1
1500           %3 = OpLabel
1501                OpBeginInvocationInterlockEXT
1502                OpEndInvocationInterlockEXT
1503                OpReturn
1504                OpFunctionEnd;
1505   )";
1506   const auto result =
1507       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
1508   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
1509 }
1510 
TEST_F(TrimCapabilitiesPassTest,FragmentShaderSampleInterlock_RemainsWhenUnorderedIsUsed)1511 TEST_F(TrimCapabilitiesPassTest,
1512        FragmentShaderSampleInterlock_RemainsWhenUnorderedIsUsed) {
1513   const std::string kTest = R"(
1514                OpCapability Shader
1515                OpCapability FragmentShaderPixelInterlockEXT
1516                OpCapability FragmentShaderSampleInterlockEXT
1517                OpCapability FragmentShaderShadingRateInterlockEXT
1518                OpExtension "SPV_EXT_fragment_shader_interlock"
1519 ; CHECK-NOT:   OpCapability FragmentShaderPixelInterlockEXT
1520 ; CHECK:       OpCapability FragmentShaderSampleInterlockEXT
1521 ; CHECK-NOT:   OpCapability FragmentShaderShadingRateInterlockEXT
1522 ; CHECK:       OpExtension "SPV_EXT_fragment_shader_interlock"
1523                OpMemoryModel Logical GLSL450
1524                OpEntryPoint GLCompute %1 "main"
1525                OpExecutionMode %main SampleInterlockUnorderedEXT
1526        %void = OpTypeVoid
1527           %1 = OpTypeFunction %void
1528           %2 = OpFunction %void None %1
1529           %3 = OpLabel
1530                OpBeginInvocationInterlockEXT
1531                OpEndInvocationInterlockEXT
1532                OpReturn
1533                OpFunctionEnd;
1534   )";
1535   const auto result =
1536       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
1537   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
1538 }
1539 
TEST_F(TrimCapabilitiesPassTest,FragmentShaderShadingRateInterlock_RemainsWhenOrderedIsUsed)1540 TEST_F(TrimCapabilitiesPassTest,
1541        FragmentShaderShadingRateInterlock_RemainsWhenOrderedIsUsed) {
1542   const std::string kTest = R"(
1543                OpCapability Shader
1544                OpCapability FragmentShaderPixelInterlockEXT
1545                OpCapability FragmentShaderSampleInterlockEXT
1546                OpCapability FragmentShaderShadingRateInterlockEXT
1547                OpExtension "SPV_EXT_fragment_shader_interlock"
1548 ; CHECK-NOT:   OpCapability FragmentShaderPixelInterlockEXT
1549 ; CHECK-NOT:   OpCapability FragmentShaderSampleInterlockEXT
1550 ; CHECK:       OpCapability FragmentShaderShadingRateInterlockEXT
1551 ; CHECK:       OpExtension "SPV_EXT_fragment_shader_interlock"
1552                OpMemoryModel Logical GLSL450
1553                OpEntryPoint GLCompute %1 "main"
1554                OpExecutionMode %main ShadingRateInterlockOrderedEXT
1555        %void = OpTypeVoid
1556           %1 = OpTypeFunction %void
1557           %2 = OpFunction %void None %1
1558           %3 = OpLabel
1559                OpBeginInvocationInterlockEXT
1560                OpEndInvocationInterlockEXT
1561                OpReturn
1562                OpFunctionEnd;
1563   )";
1564   const auto result =
1565       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
1566   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
1567 }
1568 
TEST_F(TrimCapabilitiesPassTest,FragmentShaderShadingRateInterlock_RemainsWhenUnorderedIsUsed)1569 TEST_F(TrimCapabilitiesPassTest,
1570        FragmentShaderShadingRateInterlock_RemainsWhenUnorderedIsUsed) {
1571   const std::string kTest = R"(
1572                OpCapability Shader
1573                OpCapability FragmentShaderPixelInterlockEXT
1574                OpCapability FragmentShaderSampleInterlockEXT
1575                OpCapability FragmentShaderShadingRateInterlockEXT
1576                OpExtension "SPV_EXT_fragment_shader_interlock"
1577 ; CHECK-NOT:   OpCapability FragmentShaderPixelInterlockEXT
1578 ; CHECK-NOT:   OpCapability FragmentShaderSampleInterlockEXT
1579 ; CHECK:       OpCapability FragmentShaderShadingRateInterlockEXT
1580 ; CHECK:       OpExtension "SPV_EXT_fragment_shader_interlock"
1581                OpMemoryModel Logical GLSL450
1582                OpEntryPoint GLCompute %1 "main"
1583                OpExecutionMode %main ShadingRateInterlockUnorderedEXT
1584        %void = OpTypeVoid
1585           %1 = OpTypeFunction %void
1586           %2 = OpFunction %void None %1
1587           %3 = OpLabel
1588                OpBeginInvocationInterlockEXT
1589                OpEndInvocationInterlockEXT
1590                OpReturn
1591                OpFunctionEnd;
1592   )";
1593   const auto result =
1594       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
1595   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
1596 }
1597 
TEST_F(TrimCapabilitiesPassTest,Int64_RemovedWhenUnused)1598 TEST_F(TrimCapabilitiesPassTest, Int64_RemovedWhenUnused) {
1599   const std::string kTest = R"(
1600                OpCapability Int64
1601 ; CHECK-NOT:   OpCapability Int64
1602                OpCapability Shader
1603                OpMemoryModel Logical GLSL450
1604                OpEntryPoint GLCompute %1 "main"
1605        %void = OpTypeVoid
1606           %3 = OpTypeFunction %void
1607           %1 = OpFunction %void None %3
1608           %6 = OpLabel
1609                OpReturn
1610                OpFunctionEnd;
1611   )";
1612   const auto result =
1613       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
1614   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
1615 }
1616 
TEST_F(TrimCapabilitiesPassTest,Int64_RemainsWhenUsed)1617 TEST_F(TrimCapabilitiesPassTest, Int64_RemainsWhenUsed) {
1618   const std::string kTest = R"(
1619                OpCapability Int64
1620 ; CHECK:       OpCapability Int64
1621                OpCapability Shader
1622                OpMemoryModel Logical GLSL450
1623                OpEntryPoint GLCompute %1 "main"
1624        %void = OpTypeVoid
1625         %int = OpTypeInt 64 0
1626           %3 = OpTypeFunction %void
1627           %1 = OpFunction %void None %3
1628           %6 = OpLabel
1629                OpReturn
1630                OpFunctionEnd;
1631   )";
1632   const auto result =
1633       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
1634   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
1635 }
1636 
TEST_F(TrimCapabilitiesPassTest,RayQueryKHR_RemovedWhenUnused)1637 TEST_F(TrimCapabilitiesPassTest, RayQueryKHR_RemovedWhenUnused) {
1638   const std::string kTest = R"(
1639                OpCapability Shader
1640                OpCapability RayQueryKHR
1641                OpExtension "SPV_KHR_ray_query"
1642 ; CHECK-NOT:   OpCapability RayQueryKHR
1643 ; CHECK-NOT:   OpExtension "SPV_KHR_ray_query"
1644                OpMemoryModel Logical GLSL450
1645                OpEntryPoint Vertex %main "main" %out_var_TEXCOORD1
1646                OpSource HLSL 660
1647                OpName %out_var_TEXCOORD1 "out.var.TEXCOORD1"
1648                OpName %main "main"
1649                OpDecorate %out_var_TEXCOORD1 Flat
1650                OpDecorate %out_var_TEXCOORD1 Location 0
1651        %uint = OpTypeInt 32 0
1652   %uint_1234 = OpConstant %uint 1234
1653 %_ptr_Output_uint = OpTypePointer Output %uint
1654        %void = OpTypeVoid
1655           %7 = OpTypeFunction %void
1656 %out_var_TEXCOORD1 = OpVariable %_ptr_Output_uint Output
1657        %main = OpFunction %void None %7
1658           %8 = OpLabel
1659                OpStore %out_var_TEXCOORD1 %uint_1234
1660                OpReturn
1661                OpFunctionEnd
1662   )";
1663   const auto result =
1664       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
1665   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
1666 }
1667 
TEST_F(TrimCapabilitiesPassTest,RayQueryKHR_RemainsWhenAccelerationStructureIsPresent)1668 TEST_F(TrimCapabilitiesPassTest,
1669        RayQueryKHR_RemainsWhenAccelerationStructureIsPresent) {
1670   const std::string kTest = R"(
1671                OpCapability Shader
1672                OpCapability RayQueryKHR
1673                OpExtension "SPV_KHR_ray_query"
1674 ; CHECK:       OpCapability RayQueryKHR
1675 ; CHECK:       OpExtension "SPV_KHR_ray_query"
1676                OpMemoryModel Logical GLSL450
1677                OpEntryPoint GLCompute %main "main"
1678                OpExecutionMode %main LocalSize 1 2 4
1679                OpDecorate %var_bvh DescriptorSet 0
1680                OpDecorate %var_bvh Binding 0
1681         %bvh = OpTypeAccelerationStructureKHR
1682     %ptr_bvh = OpTypePointer UniformConstant %bvh
1683        %void = OpTypeVoid
1684          %20 = OpTypeFunction %void
1685     %var_bvh = OpVariable %ptr_bvh UniformConstant
1686        %main = OpFunction %void None %20
1687          %30 = OpLabel
1688                OpReturn
1689                OpFunctionEnd
1690   )";
1691   const auto result =
1692       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
1693   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
1694 }
1695 
TEST_F(TrimCapabilitiesPassTest,RayQueryKHR_RemainsWhenRayQueryTypeIsPresent)1696 TEST_F(TrimCapabilitiesPassTest, RayQueryKHR_RemainsWhenRayQueryTypeIsPresent) {
1697   const std::string kTest = R"(
1698                OpCapability Shader
1699                OpCapability RayQueryKHR
1700                OpExtension "SPV_KHR_ray_query"
1701 ; CHECK:       OpCapability RayQueryKHR
1702 ; CHECK:       OpExtension "SPV_KHR_ray_query"
1703                OpMemoryModel Logical GLSL450
1704                OpEntryPoint GLCompute %main "main"
1705                OpExecutionMode %main LocalSize 1 2 4
1706       %query = OpTypeRayQueryKHR
1707        %void = OpTypeVoid
1708          %20 = OpTypeFunction %void
1709   %ptr_query = OpTypePointer Function %query
1710        %main = OpFunction %void None %20
1711          %30 = OpLabel
1712   %var_query = OpVariable %ptr_query Function
1713                OpReturn
1714                OpFunctionEnd
1715   )";
1716   const auto result =
1717       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
1718   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
1719 }
1720 
TEST_F(TrimCapabilitiesPassTest,RayQueryKHR_RemainsWhenUsed)1721 TEST_F(TrimCapabilitiesPassTest, RayQueryKHR_RemainsWhenUsed) {
1722   const std::string kTest = R"(
1723                OpCapability Shader
1724                OpCapability RayQueryKHR
1725                OpExtension "SPV_KHR_ray_query"
1726 ; CHECK:       OpCapability RayQueryKHR
1727 ; CHECK:       OpExtension "SPV_KHR_ray_query"
1728                OpMemoryModel Logical GLSL450
1729                OpEntryPoint GLCompute %main "main"
1730                OpExecutionMode %main LocalSize 1 2 4
1731                OpDecorate %bvh DescriptorSet 0
1732                OpDecorate %bvh Binding 0
1733                OpDecorate %output DescriptorSet 0
1734                OpDecorate %output Binding 1
1735                OpDecorate %_runtimearr_float ArrayStride 4
1736                OpMemberDecorate %type_RWStructuredBuffer_float 0 Offset 0
1737                OpDecorate %type_RWStructuredBuffer_float BufferBlock
1738       %float = OpTypeFloat 32
1739     %float_0 = OpConstant %float 0
1740         %int = OpTypeInt 32 1
1741     %v3float = OpTypeVector %float 3
1742          %12 = OpConstantComposite %v3float %float_0 %float_0 %float_0
1743       %int_0 = OpConstant %int 0
1744        %uint = OpTypeInt 32 0
1745      %uint_0 = OpConstant %uint 0
1746      %uint_1 = OpConstant %uint 1
1747 %accelerationStructureKHR = OpTypeAccelerationStructureKHR
1748 %_ptr_UniformConstant_accelerationStructureKHR = OpTypePointer UniformConstant %accelerationStructureKHR
1749 %_runtimearr_float = OpTypeRuntimeArray %float
1750 %type_RWStructuredBuffer_float = OpTypeStruct %_runtimearr_float
1751 %_ptr_Uniform_type_RWStructuredBuffer_float = OpTypePointer Uniform %type_RWStructuredBuffer_float
1752        %void = OpTypeVoid
1753          %20 = OpTypeFunction %void
1754 %rayQueryKHR = OpTypeRayQueryKHR
1755 %_ptr_Function_rayQueryKHR = OpTypePointer Function %rayQueryKHR
1756        %bool = OpTypeBool
1757 %_ptr_Uniform_float = OpTypePointer Uniform %float
1758         %bvh = OpVariable %_ptr_UniformConstant_accelerationStructureKHR UniformConstant
1759      %output = OpVariable %_ptr_Uniform_type_RWStructuredBuffer_float Uniform
1760        %main = OpFunction %void None %20
1761          %24 = OpLabel
1762          %25 = OpVariable %_ptr_Function_rayQueryKHR Function
1763          %26 = OpLoad %accelerationStructureKHR %bvh
1764                OpRayQueryInitializeKHR %25 %26 %uint_0 %uint_0 %12 %float_0 %12 %float_0
1765          %27 = OpRayQueryProceedKHR %bool %25
1766          %28 = OpRayQueryGetIntersectionTypeKHR %uint %25 %uint_1
1767          %29 = OpIEqual %bool %28 %uint_1
1768                OpSelectionMerge %30 None
1769                OpBranchConditional %29 %31 %30
1770          %31 = OpLabel
1771          %32 = OpAccessChain %_ptr_Uniform_float %output %int_0 %uint_0
1772                OpStore %32 %float_0
1773                OpBranch %30
1774          %30 = OpLabel
1775                OpReturn
1776                OpFunctionEnd
1777   )";
1778   const auto result =
1779       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
1780   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
1781 }
1782 
TEST_F(TrimCapabilitiesPassTest,RayTracingKHR_RemainsWithIntersectionExecutionMode)1783 TEST_F(TrimCapabilitiesPassTest,
1784        RayTracingKHR_RemainsWithIntersectionExecutionMode) {
1785   const std::string kTest = R"(
1786                OpCapability RayTracingKHR
1787                OpExtension "SPV_KHR_ray_tracing"
1788 ; CHECK:       OpCapability RayTracingKHR
1789 ; CHECK:       OpExtension "SPV_KHR_ray_tracing"
1790                OpMemoryModel Logical GLSL450
1791                OpEntryPoint IntersectionKHR %main "main"
1792                OpSource HLSL 660
1793                OpName %main "main"
1794        %void = OpTypeVoid
1795           %3 = OpTypeFunction %void
1796        %main = OpFunction %void None %3
1797           %4 = OpLabel
1798                OpReturn
1799                OpFunctionEnd
1800   )";
1801   const auto result =
1802       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
1803   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
1804 }
1805 
TEST_F(TrimCapabilitiesPassTest,RayTracingKHR_RemainsWithClosestHitExecutionMode)1806 TEST_F(TrimCapabilitiesPassTest,
1807        RayTracingKHR_RemainsWithClosestHitExecutionMode) {
1808   const std::string kTest = R"(
1809                OpCapability RayTracingKHR
1810                OpExtension "SPV_KHR_ray_tracing"
1811 ; CHECK:       OpCapability RayTracingKHR
1812 ; CHECK:       OpExtension "SPV_KHR_ray_tracing"
1813                OpMemoryModel Logical GLSL450
1814                OpEntryPoint ClosestHitKHR %main "main" %a
1815                OpSource HLSL 630
1816                OpName %Payload "Payload"
1817                OpMemberName %Payload 0 "color"
1818                OpName %a "a"
1819                OpName %main "main"
1820       %float = OpTypeFloat 32
1821     %v4float = OpTypeVector %float 4
1822     %Payload = OpTypeStruct %v4float
1823 %ptr_payload = OpTypePointer IncomingRayPayloadKHR %Payload
1824        %void = OpTypeVoid
1825           %8 = OpTypeFunction %void
1826           %a = OpVariable %ptr_payload IncomingRayPayloadKHR
1827        %main = OpFunction %void None %8
1828           %9 = OpLabel
1829          %10 = OpLoad %Payload %a
1830                OpStore %a %10
1831                OpReturn
1832                OpFunctionEnd
1833 
1834   )";
1835   const auto result =
1836       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
1837   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
1838 }
1839 
TEST_F(TrimCapabilitiesPassTest,RayTracingKHR_RemainsWithAnyHitExecutionMode)1840 TEST_F(TrimCapabilitiesPassTest, RayTracingKHR_RemainsWithAnyHitExecutionMode) {
1841   const std::string kTest = R"(
1842                OpCapability RayTracingKHR
1843                OpExtension "SPV_KHR_ray_tracing"
1844 ; CHECK:       OpCapability RayTracingKHR
1845 ; CHECK:       OpExtension "SPV_KHR_ray_tracing"
1846                OpMemoryModel Logical GLSL450
1847                OpEntryPoint AnyHitKHR %main "main" %a
1848                OpSource HLSL 630
1849                OpName %Payload "Payload"
1850                OpMemberName %Payload 0 "color"
1851                OpName %a "a"
1852                OpName %main "main"
1853       %float = OpTypeFloat 32
1854     %v4float = OpTypeVector %float 4
1855     %Payload = OpTypeStruct %v4float
1856 %ptr_payload = OpTypePointer IncomingRayPayloadKHR %Payload
1857        %void = OpTypeVoid
1858           %8 = OpTypeFunction %void
1859           %a = OpVariable %ptr_payload IncomingRayPayloadKHR
1860        %main = OpFunction %void None %8
1861           %9 = OpLabel
1862          %10 = OpLoad %Payload %a
1863                OpStore %a %10
1864                OpReturn
1865                OpFunctionEnd
1866   )";
1867   const auto result =
1868       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
1869   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
1870 }
1871 
TEST_F(TrimCapabilitiesPassTest,RayTracingKHR_RemainsWithMissExecutionMode)1872 TEST_F(TrimCapabilitiesPassTest, RayTracingKHR_RemainsWithMissExecutionMode) {
1873   const std::string kTest = R"(
1874                OpCapability RayTracingKHR
1875                OpExtension "SPV_KHR_ray_tracing"
1876 ; CHECK:       OpCapability RayTracingKHR
1877 ; CHECK:       OpExtension "SPV_KHR_ray_tracing"
1878                OpMemoryModel Logical GLSL450
1879                OpEntryPoint MissKHR %main "main" %a
1880                OpSource HLSL 630
1881                OpName %Payload "Payload"
1882                OpMemberName %Payload 0 "color"
1883                OpName %a "a"
1884                OpName %main "main"
1885       %float = OpTypeFloat 32
1886     %v4float = OpTypeVector %float 4
1887     %Payload = OpTypeStruct %v4float
1888 %ptr_payload = OpTypePointer IncomingRayPayloadKHR %Payload
1889        %void = OpTypeVoid
1890           %8 = OpTypeFunction %void
1891           %a = OpVariable %ptr_payload IncomingRayPayloadKHR
1892        %main = OpFunction %void None %8
1893           %9 = OpLabel
1894          %10 = OpLoad %Payload %a
1895                OpStore %a %10
1896                OpReturn
1897                OpFunctionEnd
1898   )";
1899   const auto result =
1900       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
1901   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
1902 }
1903 
TEST_F(TrimCapabilitiesPassTest,RayTracingKHR_RemainsWithRayGenerationExecutionMode)1904 TEST_F(TrimCapabilitiesPassTest,
1905        RayTracingKHR_RemainsWithRayGenerationExecutionMode) {
1906   const std::string kTest = R"(
1907                OpCapability RayTracingKHR
1908                OpExtension "SPV_KHR_ray_tracing"
1909 ; CHECK:       OpCapability RayTracingKHR
1910 ; CHECK:       OpExtension "SPV_KHR_ray_tracing"
1911                OpMemoryModel Logical GLSL450
1912                OpEntryPoint RayGenerationKHR %main "main"
1913                OpSource HLSL 630
1914                OpName %main "main"
1915        %void = OpTypeVoid
1916           %3 = OpTypeFunction %void
1917        %main = OpFunction %void None %3
1918           %4 = OpLabel
1919                OpReturn
1920                OpFunctionEnd
1921   )";
1922   const auto result =
1923       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
1924   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
1925 }
1926 
TEST_F(TrimCapabilitiesPassTest,RayTracingKHR_RemainsWithCallableExecutionMode)1927 TEST_F(TrimCapabilitiesPassTest,
1928        RayTracingKHR_RemainsWithCallableExecutionMode) {
1929   const std::string kTest = R"(
1930 ; CHECK:       OpCapability RayTracingKHR
1931 ; CHECK:       OpExtension "SPV_KHR_ray_tracing"
1932                OpCapability RayTracingKHR
1933                OpExtension "SPV_KHR_ray_tracing"
1934                OpMemoryModel Logical GLSL450
1935                OpEntryPoint CallableKHR %main "main" %a
1936                OpSource HLSL 660
1937                OpName %Payload "Payload"
1938                OpMemberName %Payload 0 "data"
1939                OpName %a "a"
1940                OpName %main "main"
1941       %float = OpTypeFloat 32
1942     %v4float = OpTypeVector %float 4
1943     %Payload = OpTypeStruct %v4float
1944 %ptr_payload = OpTypePointer IncomingCallableDataKHR %Payload
1945        %void = OpTypeVoid
1946           %8 = OpTypeFunction %void
1947           %a = OpVariable %ptr_payload IncomingCallableDataKHR
1948        %main = OpFunction %void None %8
1949           %9 = OpLabel
1950          %10 = OpLoad %Payload %a
1951                OpStore %a %10
1952                OpReturn
1953                OpFunctionEnd
1954   )";
1955   const auto result =
1956       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
1957   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
1958 }
1959 
TEST_F(TrimCapabilitiesPassTest,ImageMSArray_RemainsIfSampledIs2AndArrayedIs1)1960 TEST_F(TrimCapabilitiesPassTest,
1961        ImageMSArray_RemainsIfSampledIs2AndArrayedIs1) {
1962   const std::string kTest = R"(
1963                OpCapability ImageMSArray
1964  ; CHECK:      OpCapability ImageMSArray
1965                OpCapability Shader
1966                OpCapability StorageImageMultisample
1967                OpCapability StorageImageReadWithoutFormat
1968                OpMemoryModel Logical GLSL450
1969                OpEntryPoint Fragment %main "main"
1970                OpExecutionMode %main OriginUpperLeft
1971                OpDecorate %var_image DescriptorSet 0
1972                OpDecorate %var_image Binding 1
1973        %void = OpTypeVoid
1974        %func = OpTypeFunction %void
1975         %f32 = OpTypeFloat 32
1976         %u32 = OpTypeInt 32 0
1977      %uint_2 = OpConstant %u32 2
1978      %uint_1 = OpConstant %u32 1
1979      %v2uint = OpTypeVector %u32 2
1980     %v4float = OpTypeVector %f32 4
1981     %image = OpTypeImage %f32 2D 2 1 1 2 Unknown
1982 %ptr_image = OpTypePointer UniformConstant %image
1983        %10 = OpConstantComposite %v2uint %uint_1 %uint_2
1984 %var_image = OpVariable %ptr_image UniformConstant
1985      %main = OpFunction %void None %func
1986  %main_lab = OpLabel
1987        %18 = OpLoad %image %var_image
1988        %19 = OpImageRead %v4float %18 %10 Sample %uint_2
1989              OpReturn
1990              OpFunctionEnd
1991   )";
1992   const auto result =
1993       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
1994   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
1995 }
1996 
TEST_F(TrimCapabilitiesPassTest,ImageMSArray_RemovedIfNotUsed)1997 TEST_F(TrimCapabilitiesPassTest, ImageMSArray_RemovedIfNotUsed) {
1998   const std::string kTest = R"(
1999                OpCapability Shader
2000                OpCapability ImageMSArray
2001 ; CHECK-NOT:   OpCapability ImageMSArray
2002                OpMemoryModel Logical GLSL450
2003                OpEntryPoint Fragment %main "main" %out_var_SV_Target
2004                OpExecutionMode %main OriginUpperLeft
2005                OpSource HLSL 660
2006                OpName %out_var_SV_Target "out.var.SV_Target"
2007                OpName %main "main"
2008                OpDecorate %out_var_SV_Target Location 0
2009       %float = OpTypeFloat 32
2010     %v4float = OpTypeVector %float 4
2011 %_ptr_Output_v4float = OpTypePointer Output %v4float
2012        %void = OpTypeVoid
2013           %7 = OpTypeFunction %void
2014 %out_var_SV_Target = OpVariable %_ptr_Output_v4float Output
2015        %main = OpFunction %void None %7
2016           %8 = OpLabel
2017                OpReturn
2018                OpFunctionEnd
2019   )";
2020   const auto result =
2021       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
2022   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
2023 }
2024 
TEST_F(TrimCapabilitiesPassTest,ImageMSArray_RemovedIfArrayedIsNot1)2025 TEST_F(TrimCapabilitiesPassTest, ImageMSArray_RemovedIfArrayedIsNot1) {
2026   const std::string kTest = R"(
2027                OpCapability ImageMSArray
2028  ; CHECK-NOT:  OpCapability ImageMSArray
2029                OpCapability Shader
2030                OpCapability StorageImageMultisample
2031                OpCapability StorageImageReadWithoutFormat
2032                OpMemoryModel Logical GLSL450
2033                OpEntryPoint Fragment %main "main"
2034                OpExecutionMode %main OriginUpperLeft
2035                OpDecorate %var_image DescriptorSet 0
2036                OpDecorate %var_image Binding 1
2037        %void = OpTypeVoid
2038        %func = OpTypeFunction %void
2039         %f32 = OpTypeFloat 32
2040         %u32 = OpTypeInt 32 0
2041      %uint_2 = OpConstant %u32 2
2042      %uint_1 = OpConstant %u32 1
2043      %v2uint = OpTypeVector %u32 2
2044     %v4float = OpTypeVector %f32 4
2045     %image = OpTypeImage %f32 2D 2 0 1 2 Unknown
2046 %ptr_image = OpTypePointer UniformConstant %image
2047        %10 = OpConstantComposite %v2uint %uint_1 %uint_2
2048 %var_image = OpVariable %ptr_image UniformConstant
2049      %main = OpFunction %void None %func
2050  %main_lab = OpLabel
2051        %18 = OpLoad %image %var_image
2052        %19 = OpImageRead %v4float %18 %10 Sample %uint_2
2053              OpReturn
2054              OpFunctionEnd
2055   )";
2056   const auto result =
2057       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
2058   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
2059 }
2060 
TEST_F(TrimCapabilitiesPassTest,ImageMSArray_RemovedIfSampledNot2)2061 TEST_F(TrimCapabilitiesPassTest, ImageMSArray_RemovedIfSampledNot2) {
2062   const std::string kTest = R"(
2063                OpCapability ImageMSArray
2064  ; CHECK-NOT:  OpCapability ImageMSArray
2065                OpCapability Shader
2066                OpCapability StorageImageReadWithoutFormat
2067                OpMemoryModel Logical GLSL450
2068                OpEntryPoint Fragment %main "main"
2069                OpExecutionMode %main OriginUpperLeft
2070                OpDecorate %var_image DescriptorSet 0
2071                OpDecorate %var_image Binding 1
2072        %void = OpTypeVoid
2073        %func = OpTypeFunction %void
2074         %f32 = OpTypeFloat 32
2075         %u32 = OpTypeInt 32 0
2076      %uint_3 = OpConstant %u32 3
2077      %uint_2 = OpConstant %u32 2
2078      %uint_1 = OpConstant %u32 1
2079      %v3uint = OpTypeVector %u32 3
2080     %v4float = OpTypeVector %f32 4
2081     %image = OpTypeImage %f32 2D 2 1 0 2 Unknown
2082 %ptr_image = OpTypePointer UniformConstant %image
2083        %10 = OpConstantComposite %v3uint %uint_1 %uint_2 %uint_3
2084 %var_image = OpVariable %ptr_image UniformConstant
2085      %main = OpFunction %void None %func
2086  %main_lab = OpLabel
2087        %18 = OpLoad %image %var_image
2088        %19 = OpImageRead %v4float %18 %10
2089              OpReturn
2090              OpFunctionEnd
2091   )";
2092   const auto result =
2093       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
2094   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
2095 }
2096 
TEST_F(TrimCapabilitiesPassTest,Float64_RemovedWhenUnused)2097 TEST_F(TrimCapabilitiesPassTest, Float64_RemovedWhenUnused) {
2098   const std::string kTest = R"(
2099                OpCapability Float64
2100 ; CHECK-NOT:   OpCapability Float64
2101                OpCapability Shader
2102                OpMemoryModel Logical GLSL450
2103                OpEntryPoint GLCompute %1 "main"
2104        %void = OpTypeVoid
2105           %3 = OpTypeFunction %void
2106           %1 = OpFunction %void None %3
2107           %6 = OpLabel
2108                OpReturn
2109                OpFunctionEnd;
2110   )";
2111   const auto result =
2112       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
2113   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
2114 }
2115 
TEST_F(TrimCapabilitiesPassTest,Float64_RemainsWhenUsed)2116 TEST_F(TrimCapabilitiesPassTest, Float64_RemainsWhenUsed) {
2117   const std::string kTest = R"(
2118                OpCapability Float64
2119 ; CHECK:       OpCapability Float64
2120                OpCapability Shader
2121                OpMemoryModel Logical GLSL450
2122                OpEntryPoint GLCompute %1 "main"
2123        %void = OpTypeVoid
2124       %float = OpTypeFloat 64
2125           %3 = OpTypeFunction %void
2126           %1 = OpFunction %void None %3
2127           %6 = OpLabel
2128                OpReturn
2129                OpFunctionEnd;
2130   )";
2131   const auto result =
2132       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
2133   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
2134 }
2135 
TEST_F(TrimCapabilitiesPassTest,ComputeDerivativeGroupQuads_ReamainsWithExecMode)2136 TEST_F(TrimCapabilitiesPassTest,
2137        ComputeDerivativeGroupQuads_ReamainsWithExecMode) {
2138   const std::string kTest = R"(
2139                OpCapability ComputeDerivativeGroupQuadsNV
2140                OpCapability ComputeDerivativeGroupLinearNV
2141 ; CHECK-NOT:   OpCapability ComputeDerivativeGroupLinearNV
2142 ; CHECK:       OpCapability ComputeDerivativeGroupQuadsNV
2143 ; CHECK-NOT:   OpCapability ComputeDerivativeGroupLinearNV
2144                OpCapability Shader
2145 ; CHECK:       OpExtension "SPV_NV_compute_shader_derivatives"
2146                OpExtension "SPV_NV_compute_shader_derivatives"
2147                OpMemoryModel Logical GLSL450
2148                OpEntryPoint GLCompute %1 "main"
2149                OpExecutionMode %1 DerivativeGroupQuadsNV
2150        %void = OpTypeVoid
2151           %3 = OpTypeFunction %void
2152           %1 = OpFunction %void None %3
2153           %6 = OpLabel
2154                OpReturn
2155                OpFunctionEnd
2156   )";
2157   const auto result =
2158       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
2159   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
2160 }
2161 
TEST_F(TrimCapabilitiesPassTest,ComputeDerivativeGroupLinear_ReamainsWithExecMode)2162 TEST_F(TrimCapabilitiesPassTest,
2163        ComputeDerivativeGroupLinear_ReamainsWithExecMode) {
2164   const std::string kTest = R"(
2165                OpCapability ComputeDerivativeGroupLinearNV
2166                OpCapability ComputeDerivativeGroupQuadsNV
2167 ; CHECK-NOT:   OpCapability ComputeDerivativeGroupQuadsNV
2168 ; CHECK:       OpCapability ComputeDerivativeGroupLinearNV
2169 ; CHECK-NOT:   OpCapability ComputeDerivativeGroupQuadsNV
2170                OpCapability Shader
2171 ; CHECK:       OpExtension "SPV_NV_compute_shader_derivatives"
2172                OpExtension "SPV_NV_compute_shader_derivatives"
2173                OpMemoryModel Logical GLSL450
2174                OpEntryPoint GLCompute %1 "main"
2175                OpExecutionMode %1 DerivativeGroupLinearNV
2176        %void = OpTypeVoid
2177       %float = OpTypeFloat 64
2178           %3 = OpTypeFunction %void
2179           %1 = OpFunction %void None %3
2180           %6 = OpLabel
2181                OpReturn
2182                OpFunctionEnd
2183   )";
2184   const auto result =
2185       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
2186   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
2187 }
2188 
TEST_F(TrimCapabilitiesPassTest,StorageImageReadWithoutFormat_RemovedIfUnused)2189 TEST_F(TrimCapabilitiesPassTest,
2190        StorageImageReadWithoutFormat_RemovedIfUnused) {
2191   const std::string kTest = R"(
2192                OpCapability StorageImageReadWithoutFormat
2193 ; CHECK-NOT:   OpCapability StorageImageReadWithoutFormat
2194                OpCapability Shader
2195                OpMemoryModel Logical GLSL450
2196                OpEntryPoint Fragment %PSMain "PSMain" %out_var
2197                OpExecutionMode %PSMain OriginUpperLeft
2198                OpDecorate %out_var Location 0
2199       %float = OpTypeFloat 32
2200      %float4 = OpTypeVector %float 4
2201     %float_0 = OpConstant %float 0
2202 %float4_0000 = OpConstantComposite %float4 %float_0 %float_0 %float_0 %float_0
2203  %ptr_float4 = OpTypePointer Output %float4
2204        %void = OpTypeVoid
2205           %9 = OpTypeFunction %void
2206     %out_var = OpVariable %ptr_float4 Output
2207      %PSMain = OpFunction %void None %9
2208          %10 = OpLabel
2209                OpStore %out_var %float4_0000
2210                OpReturn
2211                OpFunctionEnd
2212   )";
2213   const auto result =
2214       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
2215   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
2216 }
2217 
TEST_F(TrimCapabilitiesPassTest,StorageImageReadWithoutFormat_RemovedIfUnusedOpImageFetch)2218 TEST_F(TrimCapabilitiesPassTest,
2219        StorageImageReadWithoutFormat_RemovedIfUnusedOpImageFetch) {
2220   const std::string kTest = R"(
2221                OpCapability StorageImageReadWithoutFormat
2222 ; CHECK-NOT:   OpCapability StorageImageReadWithoutFormat
2223                OpCapability Shader
2224                OpMemoryModel Logical GLSL450
2225                OpEntryPoint Fragment %PSMain "PSMain" %out_var
2226                OpExecutionMode %PSMain OriginUpperLeft
2227                OpDecorate %out_var Location 0
2228                OpDecorate %texture DescriptorSet 0
2229                OpDecorate %texture Binding 1
2230       %float = OpTypeFloat 32
2231      %float4 = OpTypeVector %float 4
2232         %int = OpTypeInt 32 1
2233        %int2 = OpTypeVector %int 2
2234  %type_image = OpTypeImage %float 2D 2 0 0 1 Unknown
2235   %ptr_image = OpTypePointer UniformConstant %type_image
2236       %int_0 = OpConstant %int 0
2237     %int2_00 = OpConstantComposite %int2 %int_0 %int_0
2238  %ptr_float4 = OpTypePointer Output %float4
2239        %void = OpTypeVoid
2240           %9 = OpTypeFunction %void
2241     %texture = OpVariable %ptr_image UniformConstant
2242     %out_var = OpVariable %ptr_float4 Output
2243      %PSMain = OpFunction %void None %9
2244          %10 = OpLabel
2245          %11 = OpLoad %type_image %texture
2246          %12 = OpImageFetch %float4 %11 %int2_00 Lod %int_0
2247                OpStore %out_var %12
2248                OpReturn
2249                OpFunctionEnd
2250   )";
2251   const auto result =
2252       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
2253   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
2254 }
2255 
TEST_F(TrimCapabilitiesPassTest,StorageImageReadWithoutFormat_RemainsWhenRequiredWithRead)2256 TEST_F(TrimCapabilitiesPassTest,
2257        StorageImageReadWithoutFormat_RemainsWhenRequiredWithRead) {
2258   const std::string kTest = R"(
2259                OpCapability StorageImageReadWithoutFormat
2260 ; CHECK:       OpCapability StorageImageReadWithoutFormat
2261                OpCapability Shader
2262                OpMemoryModel Logical GLSL450
2263                OpEntryPoint Fragment %PSMain "PSMain" %out_var
2264                OpExecutionMode %PSMain OriginUpperLeft
2265                OpDecorate %out_var Location 0
2266                OpDecorate %texture DescriptorSet 0
2267                OpDecorate %texture Binding 1
2268       %float = OpTypeFloat 32
2269      %float4 = OpTypeVector %float 4
2270         %int = OpTypeInt 32 1
2271        %int2 = OpTypeVector %int 2
2272  %type_image = OpTypeImage %float 2D 2 0 0 1 Unknown
2273   %ptr_image = OpTypePointer UniformConstant %type_image
2274       %int_0 = OpConstant %int 0
2275     %int2_00 = OpConstantComposite %int2 %int_0 %int_0
2276  %ptr_float4 = OpTypePointer Output %float4
2277        %void = OpTypeVoid
2278           %9 = OpTypeFunction %void
2279     %texture = OpVariable %ptr_image UniformConstant
2280     %out_var = OpVariable %ptr_float4 Output
2281      %PSMain = OpFunction %void None %9
2282          %10 = OpLabel
2283          %11 = OpLoad %type_image %texture
2284          %12 = OpImageRead %float4 %11 %int2_00 Lod %int_0
2285                OpStore %out_var %12
2286                OpReturn
2287                OpFunctionEnd
2288   )";
2289   const auto result =
2290       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
2291   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
2292 }
2293 
TEST_F(TrimCapabilitiesPassTest,StorageImageReadWithoutFormat_RemainsWhenRequiredWithSparseRead)2294 TEST_F(TrimCapabilitiesPassTest,
2295        StorageImageReadWithoutFormat_RemainsWhenRequiredWithSparseRead) {
2296   const std::string kTest = R"(
2297                OpCapability StorageImageReadWithoutFormat
2298 ; CHECK:       OpCapability StorageImageReadWithoutFormat
2299                OpCapability SparseResidency
2300                OpCapability Shader
2301                OpMemoryModel Logical GLSL450
2302                OpEntryPoint Fragment %PSMain "PSMain"
2303                OpExecutionMode %PSMain OriginUpperLeft
2304                OpDecorate %texture DescriptorSet 0
2305                OpDecorate %texture Binding 1
2306       %float = OpTypeFloat 32
2307      %float4 = OpTypeVector %float 4
2308         %int = OpTypeInt 32 1
2309        %int2 = OpTypeVector %int 2
2310  %type_image = OpTypeImage %float 2D 2 0 0 2 Unknown
2311      %struct = OpTypeStruct %int %float4
2312   %ptr_image = OpTypePointer UniformConstant %type_image
2313       %int_0 = OpConstant %int 0
2314     %int2_00 = OpConstantComposite %int2 %int_0 %int_0
2315        %void = OpTypeVoid
2316           %9 = OpTypeFunction %void
2317     %texture = OpVariable %ptr_image UniformConstant
2318      %PSMain = OpFunction %void None %9
2319          %10 = OpLabel
2320          %11 = OpLoad %type_image %texture
2321          %12 = OpImageSparseRead %struct %11 %int2_00
2322                OpReturn
2323                OpFunctionEnd
2324   )";
2325   const auto result =
2326       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
2327   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
2328 }
2329 
TEST_F(TrimCapabilitiesPassTest,StorageImageReadWithoutFormat_RemovedWithReadOnSubpassData)2330 TEST_F(TrimCapabilitiesPassTest,
2331        StorageImageReadWithoutFormat_RemovedWithReadOnSubpassData) {
2332   const std::string kTest = R"(
2333                OpCapability StorageImageReadWithoutFormat
2334 ; CHECK-NOT:   OpCapability StorageImageReadWithoutFormat
2335                OpCapability InputAttachment
2336                OpCapability Shader
2337                OpMemoryModel Logical GLSL450
2338                OpEntryPoint Fragment %PSMain "PSMain" %out_var
2339                OpExecutionMode %PSMain OriginUpperLeft
2340                OpDecorate %out_var Location 0
2341                OpDecorate %texture DescriptorSet 0
2342                OpDecorate %texture Binding 1
2343       %float = OpTypeFloat 32
2344      %float4 = OpTypeVector %float 4
2345         %int = OpTypeInt 32 1
2346        %int2 = OpTypeVector %int 2
2347  %type_image = OpTypeImage %float SubpassData 2 0 0 2 Unknown
2348   %ptr_image = OpTypePointer UniformConstant %type_image
2349       %int_0 = OpConstant %int 0
2350     %int2_00 = OpConstantComposite %int2 %int_0 %int_0
2351  %ptr_float4 = OpTypePointer Output %float4
2352        %void = OpTypeVoid
2353           %9 = OpTypeFunction %void
2354     %texture = OpVariable %ptr_image UniformConstant
2355     %out_var = OpVariable %ptr_float4 Output
2356      %PSMain = OpFunction %void None %9
2357          %10 = OpLabel
2358          %11 = OpLoad %type_image %texture
2359          %12 = OpImageRead %float4 %11 %int2_00
2360                OpStore %out_var %12
2361                OpReturn
2362                OpFunctionEnd
2363   )";
2364   const auto result =
2365       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
2366   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
2367 }
2368 
TEST_F(TrimCapabilitiesPassTest,PhysicalStorageBuffer_RemovedWhenUnused)2369 TEST_F(TrimCapabilitiesPassTest, PhysicalStorageBuffer_RemovedWhenUnused) {
2370   const std::string kTest = R"(
2371                OpCapability PhysicalStorageBufferAddresses
2372 ; CHECK-NOT:   OpCapability PhysicalStorageBufferAddresses
2373                OpCapability Shader
2374                OpMemoryModel Logical GLSL450
2375                OpEntryPoint GLCompute %1 "main"
2376        %void = OpTypeVoid
2377           %3 = OpTypeFunction %void
2378           %1 = OpFunction %void None %3
2379           %6 = OpLabel
2380                OpReturn
2381                OpFunctionEnd;
2382   )";
2383   const auto result =
2384       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
2385   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
2386 }
2387 
TEST_F(TrimCapabilitiesPassTest,PhysicalStorageBuffer_RemainsWithOpTypeForwardPointer)2388 TEST_F(TrimCapabilitiesPassTest,
2389        PhysicalStorageBuffer_RemainsWithOpTypeForwardPointer) {
2390   const std::string kTest = R"(
2391                OpCapability PhysicalStorageBufferAddresses
2392 ; CHECK:       OpCapability PhysicalStorageBufferAddresses
2393                OpCapability Shader
2394                OpMemoryModel Logical GLSL450
2395                OpEntryPoint GLCompute %main "main"
2396                OpExecutionMode %main LocalSize 1 2 4
2397        %void = OpTypeVoid
2398         %int = OpTypeInt 32 0
2399      %struct = OpTypeStruct %int
2400                OpTypeForwardPointer %ptr PhysicalStorageBuffer
2401         %ptr = OpTypePointer PhysicalStorageBuffer %struct
2402           %3 = OpTypeFunction %void
2403        %main = OpFunction %void None %3
2404           %6 = OpLabel
2405                OpReturn
2406                OpFunctionEnd
2407   )";
2408   const auto result =
2409       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
2410   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
2411 }
2412 
TEST_F(TrimCapabilitiesPassTest,PhysicalStorageBuffer_RemainsWithPhysicalStorageBufferStorage)2413 TEST_F(TrimCapabilitiesPassTest,
2414        PhysicalStorageBuffer_RemainsWithPhysicalStorageBufferStorage) {
2415   const std::string kTest = R"(
2416                OpCapability PhysicalStorageBufferAddresses
2417 ; CHECK:       OpCapability PhysicalStorageBufferAddresses
2418                OpCapability Shader
2419                OpMemoryModel Logical GLSL450
2420                OpEntryPoint GLCompute %main "main"
2421                OpExecutionMode %main LocalSize 1 2 4
2422        %void = OpTypeVoid
2423         %int = OpTypeInt 32 0
2424      %struct = OpTypeStruct %int
2425         %ptr = OpTypePointer PhysicalStorageBuffer %struct
2426           %3 = OpTypeFunction %void
2427        %main = OpFunction %void None %3
2428           %6 = OpLabel
2429                OpReturn
2430                OpFunctionEnd;
2431   )";
2432   const auto result =
2433       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
2434   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
2435 }
2436 
TEST_F(TrimCapabilitiesPassTest,PhysicalStorageBuffer_RemainsWithRestrictDecoration)2437 TEST_F(TrimCapabilitiesPassTest,
2438        PhysicalStorageBuffer_RemainsWithRestrictDecoration) {
2439   const std::string kTest = R"(
2440                OpCapability PhysicalStorageBufferAddresses
2441 ; CHECK:       OpCapability PhysicalStorageBufferAddresses
2442                OpCapability Shader
2443                OpMemoryModel Logical GLSL450
2444                OpEntryPoint GLCompute %main "main"
2445                OpExecutionMode %main LocalSize 1 2 4
2446                OpDecorate %var RestrictPointer
2447        %void = OpTypeVoid
2448         %int = OpTypeInt 32 0
2449      %struct = OpTypeStruct %int
2450         %ptr = OpTypePointer Function %struct
2451           %3 = OpTypeFunction %void
2452        %main = OpFunction %void None %3
2453           %6 = OpLabel
2454         %var = OpVariable %ptr Function
2455                OpReturn
2456                OpFunctionEnd;
2457   )";
2458   const auto result =
2459       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
2460   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
2461 }
2462 
TEST_F(TrimCapabilitiesPassTest,PhysicalStorageBuffer_RemainsWithAliasedDecoration)2463 TEST_F(TrimCapabilitiesPassTest,
2464        PhysicalStorageBuffer_RemainsWithAliasedDecoration) {
2465   const std::string kTest = R"(
2466                OpCapability PhysicalStorageBufferAddresses
2467 ; CHECK:       OpCapability PhysicalStorageBufferAddresses
2468                OpCapability Shader
2469                OpMemoryModel Logical GLSL450
2470                OpEntryPoint GLCompute %main "main"
2471                OpExecutionMode %main LocalSize 1 2 4
2472                OpDecorate %var AliasedPointer
2473        %void = OpTypeVoid
2474         %int = OpTypeInt 32 0
2475      %struct = OpTypeStruct %int
2476         %ptr = OpTypePointer Function %struct
2477           %3 = OpTypeFunction %void
2478        %main = OpFunction %void None %3
2479           %6 = OpLabel
2480         %var = OpVariable %ptr Function
2481                OpReturn
2482                OpFunctionEnd;
2483   )";
2484   const auto result =
2485       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
2486   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
2487 }
2488 
TEST_F(TrimCapabilitiesPassTest,Float16_RemovedWhenUnused)2489 TEST_F(TrimCapabilitiesPassTest, Float16_RemovedWhenUnused) {
2490   const std::string kTest = R"(
2491                OpCapability Float16
2492 ; CHECK-NOT:   OpCapability Float16
2493                OpCapability Shader
2494                OpMemoryModel Logical GLSL450
2495                OpEntryPoint GLCompute %1 "main"
2496        %void = OpTypeVoid
2497           %3 = OpTypeFunction %void
2498           %1 = OpFunction %void None %3
2499           %6 = OpLabel
2500                OpReturn
2501                OpFunctionEnd;
2502   )";
2503   const auto result =
2504       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
2505   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
2506 }
2507 
TEST_F(TrimCapabilitiesPassTest,Float16_RemainsWhenUsed)2508 TEST_F(TrimCapabilitiesPassTest, Float16_RemainsWhenUsed) {
2509   const std::string kTest = R"(
2510                OpCapability Float16
2511 ; CHECK:       OpCapability Float16
2512                OpCapability Shader
2513                OpMemoryModel Logical GLSL450
2514                OpEntryPoint GLCompute %1 "main"
2515        %void = OpTypeVoid
2516       %float = OpTypeFloat 16
2517           %3 = OpTypeFunction %void
2518           %1 = OpFunction %void None %3
2519           %6 = OpLabel
2520                OpReturn
2521                OpFunctionEnd;
2522   )";
2523   const auto result =
2524       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
2525   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
2526 }
2527 
TEST_F(TrimCapabilitiesPassTest,Int16_RemovedWhenUnused)2528 TEST_F(TrimCapabilitiesPassTest, Int16_RemovedWhenUnused) {
2529   const std::string kTest = R"(
2530                OpCapability Int16
2531 ; CHECK-NOT:   OpCapability Int16
2532                OpCapability Shader
2533                OpMemoryModel Logical GLSL450
2534                OpEntryPoint GLCompute %1 "main"
2535        %void = OpTypeVoid
2536           %3 = OpTypeFunction %void
2537           %1 = OpFunction %void None %3
2538           %6 = OpLabel
2539                OpReturn
2540                OpFunctionEnd;
2541   )";
2542   const auto result =
2543       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
2544   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
2545 }
2546 
TEST_F(TrimCapabilitiesPassTest,Int16_RemainsWhenUsed)2547 TEST_F(TrimCapabilitiesPassTest, Int16_RemainsWhenUsed) {
2548   const std::string kTest = R"(
2549                OpCapability Int16
2550 ; CHECK:       OpCapability Int16
2551                OpCapability Shader
2552                OpMemoryModel Logical GLSL450
2553                OpEntryPoint GLCompute %1 "main"
2554        %void = OpTypeVoid
2555         %int = OpTypeInt 16 1
2556           %3 = OpTypeFunction %void
2557           %1 = OpFunction %void None %3
2558           %6 = OpLabel
2559                OpReturn
2560                OpFunctionEnd;
2561   )";
2562   const auto result =
2563       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
2564   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
2565 }
2566 
TEST_F(TrimCapabilitiesPassTest,UInt16_RemainsWhenUsed)2567 TEST_F(TrimCapabilitiesPassTest, UInt16_RemainsWhenUsed) {
2568   const std::string kTest = R"(
2569                OpCapability Int16
2570 ; CHECK:       OpCapability Int16
2571                OpCapability Shader
2572                OpMemoryModel Logical GLSL450
2573                OpEntryPoint GLCompute %1 "main"
2574        %void = OpTypeVoid
2575        %uint = OpTypeInt 16 0
2576           %3 = OpTypeFunction %void
2577           %1 = OpFunction %void None %3
2578           %6 = OpLabel
2579                OpReturn
2580                OpFunctionEnd;
2581   )";
2582   const auto result =
2583       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
2584   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
2585 }
2586 
TEST_F(TrimCapabilitiesPassTest,VulkanMemoryModelDeviceScope_RemovedWhenUnused)2587 TEST_F(TrimCapabilitiesPassTest,
2588        VulkanMemoryModelDeviceScope_RemovedWhenUnused) {
2589   const std::string kTest = R"(
2590                OpCapability VulkanMemoryModelDeviceScope
2591 ; CHECK-NOT:   OpCapability VulkanMemoryModelDeviceScope
2592                OpCapability Shader
2593                OpMemoryModel Logical GLSL450
2594                OpEntryPoint GLCompute %1 "main"
2595        %void = OpTypeVoid
2596           %3 = OpTypeFunction %void
2597           %1 = OpFunction %void None %3
2598           %6 = OpLabel
2599                OpReturn
2600                OpFunctionEnd;
2601   )";
2602   const auto result =
2603       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
2604   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
2605 }
2606 
TEST_F(TrimCapabilitiesPassTest,VulkanMemoryModelDeviceScope_RemovedWhenUsedWithGLSL450)2607 TEST_F(TrimCapabilitiesPassTest,
2608        VulkanMemoryModelDeviceScope_RemovedWhenUsedWithGLSL450) {
2609   const std::string kTest = R"(
2610                OpCapability VulkanMemoryModelDeviceScope
2611 ; CHECK-NOT:   OpCapability VulkanMemoryModelDeviceScope
2612                OpCapability Shader
2613                OpCapability ShaderClockKHR
2614                OpCapability Int64
2615                OpExtension "SPV_KHR_shader_clock"
2616                OpMemoryModel Logical GLSL450
2617                OpEntryPoint GLCompute %main "main"
2618                OpExecutionMode %main LocalSize 1 2 4
2619        %void = OpTypeVoid
2620        %uint = OpTypeInt 32 0
2621       %ulong = OpTypeInt 64 0
2622      %uint_1 = OpConstant %uint 1
2623           %3 = OpTypeFunction %void
2624        %main = OpFunction %void None %3
2625           %6 = OpLabel
2626          %22 = OpReadClockKHR %ulong %uint_1 ; Device Scope
2627                OpReturn
2628                OpFunctionEnd
2629   )";
2630   const auto result =
2631       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
2632   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
2633 }
2634 
TEST_F(TrimCapabilitiesPassTest,VulkanMemoryModelDeviceScope_RemainsWhenUsedWithVulkan)2635 TEST_F(TrimCapabilitiesPassTest,
2636        VulkanMemoryModelDeviceScope_RemainsWhenUsedWithVulkan) {
2637   const std::string kTest = R"(
2638                OpCapability VulkanMemoryModelDeviceScope
2639 ; CHECK:       OpCapability VulkanMemoryModelDeviceScope
2640                OpCapability Shader
2641                OpCapability ShaderClockKHR
2642                OpCapability Int64
2643                OpExtension "SPV_KHR_shader_clock"
2644                OpMemoryModel Logical Vulkan
2645                OpEntryPoint GLCompute %main "main"
2646                OpExecutionMode %main LocalSize 1 2 4
2647        %void = OpTypeVoid
2648        %uint = OpTypeInt 32 0
2649       %ulong = OpTypeInt 64 0
2650      %uint_1 = OpConstant %uint 1
2651           %3 = OpTypeFunction %void
2652        %main = OpFunction %void None %3
2653           %6 = OpLabel
2654          %22 = OpReadClockKHR %ulong %uint_1 ; Device Scope
2655                OpReturn
2656                OpFunctionEnd
2657   )";
2658   const auto result =
2659       SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
2660   EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
2661 }
2662 
2663 }  // namespace
2664 }  // namespace opt
2665 }  // namespace spvtools
2666