• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2018 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 // Validation tests for memory/storage
16 
17 #include <string>
18 #include <vector>
19 
20 #include "gmock/gmock.h"
21 #include "test/unit_spirv.h"
22 #include "test/val/val_fixtures.h"
23 
24 namespace spvtools {
25 namespace val {
26 namespace {
27 
28 using ::testing::Eq;
29 using ::testing::HasSubstr;
30 
31 using ValidateMemory = spvtest::ValidateBase<bool>;
32 
TEST_F(ValidateMemory,VulkanUniformConstantOnNonOpaqueResourceBad)33 TEST_F(ValidateMemory, VulkanUniformConstantOnNonOpaqueResourceBad) {
34   std::string spirv = R"(
35 OpCapability Shader
36 OpMemoryModel Logical GLSL450
37 OpEntryPoint Fragment %func "func"
38 OpExecutionMode %func OriginUpperLeft
39 %float = OpTypeFloat 32
40 %float_ptr = OpTypePointer UniformConstant %float
41 %2 = OpVariable %float_ptr UniformConstant
42 %void = OpTypeVoid
43 %functy = OpTypeFunction %void
44 %func = OpFunction %void None %functy
45 %1 = OpLabel
46 OpReturn
47 OpFunctionEnd
48 )";
49   CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
50   EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
51   EXPECT_THAT(
52       getDiagnosticString(),
53       HasSubstr("From Vulkan spec, section 14.5.2:\n"
54                 "Variables identified with the UniformConstant storage class "
55                 "are used only as handles to refer to opaque resources. Such "
56                 "variables must be typed as OpTypeImage, OpTypeSampler, "
57                 "OpTypeSampledImage, OpTypeAccelerationStructureNV, or an "
58                 "array of one of these types."));
59 }
60 
TEST_F(ValidateMemory,VulkanUniformConstantOnOpaqueResourceGood)61 TEST_F(ValidateMemory, VulkanUniformConstantOnOpaqueResourceGood) {
62   std::string spirv = R"(
63 OpCapability Shader
64 OpMemoryModel Logical GLSL450
65 OpEntryPoint Fragment %func "func"
66 OpExecutionMode %func OriginUpperLeft
67 OpDecorate %2 DescriptorSet 0
68 OpDecorate %2 Binding 0
69 %sampler = OpTypeSampler
70 %sampler_ptr = OpTypePointer UniformConstant %sampler
71 %2 = OpVariable %sampler_ptr UniformConstant
72 %void = OpTypeVoid
73 %functy = OpTypeFunction %void
74 %func = OpFunction %void None %functy
75 %1 = OpLabel
76 OpReturn
77 OpFunctionEnd
78 )";
79   CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
80   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
81 }
82 
TEST_F(ValidateMemory,VulkanUniformConstantOnNonOpaqueResourceArrayBad)83 TEST_F(ValidateMemory, VulkanUniformConstantOnNonOpaqueResourceArrayBad) {
84   std::string spirv = R"(
85 OpCapability Shader
86 OpMemoryModel Logical GLSL450
87 OpEntryPoint Fragment %func "func"
88 OpExecutionMode %func OriginUpperLeft
89 %float = OpTypeFloat 32
90 %uint = OpTypeInt 32 0
91 %array_size = OpConstant %uint 5
92 %array = OpTypeArray %float %array_size
93 %array_ptr = OpTypePointer UniformConstant %array
94 %2 = OpVariable %array_ptr UniformConstant
95 %void = OpTypeVoid
96 %functy = OpTypeFunction %void
97 %func = OpFunction %void None %functy
98 %1 = OpLabel
99 OpReturn
100 OpFunctionEnd
101 )";
102   CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
103   EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
104   EXPECT_THAT(
105       getDiagnosticString(),
106       HasSubstr("From Vulkan spec, section 14.5.2:\n"
107                 "Variables identified with the UniformConstant storage class "
108                 "are used only as handles to refer to opaque resources. Such "
109                 "variables must be typed as OpTypeImage, OpTypeSampler, "
110                 "OpTypeSampledImage, OpTypeAccelerationStructureNV, or an "
111                 "array of one of these types."));
112 }
113 
TEST_F(ValidateMemory,VulkanUniformConstantOnOpaqueResourceArrayGood)114 TEST_F(ValidateMemory, VulkanUniformConstantOnOpaqueResourceArrayGood) {
115   std::string spirv = R"(
116 OpCapability Shader
117 OpMemoryModel Logical GLSL450
118 OpEntryPoint Fragment %func "func"
119 OpExecutionMode %func OriginUpperLeft
120 OpDecorate %2 DescriptorSet 0
121 OpDecorate %2 Binding 0
122 %sampler = OpTypeSampler
123 %uint = OpTypeInt 32 0
124 %array_size = OpConstant %uint 5
125 %array = OpTypeArray %sampler %array_size
126 %array_ptr = OpTypePointer UniformConstant %array
127 %2 = OpVariable %array_ptr UniformConstant
128 %void = OpTypeVoid
129 %functy = OpTypeFunction %void
130 %func = OpFunction %void None %functy
131 %1 = OpLabel
132 OpReturn
133 OpFunctionEnd
134 )";
135   CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
136   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
137 }
138 
TEST_F(ValidateMemory,VulkanUniformConstantOnOpaqueResourceRuntimeArrayGood)139 TEST_F(ValidateMemory, VulkanUniformConstantOnOpaqueResourceRuntimeArrayGood) {
140   std::string spirv = R"(
141 OpCapability Shader
142 OpMemoryModel Logical GLSL450
143 OpEntryPoint Fragment %func "func"
144 OpExecutionMode %func OriginUpperLeft
145 OpDecorate %2 DescriptorSet 0
146 OpDecorate %2 Binding 0
147 %sampler = OpTypeSampler
148 %uint = OpTypeInt 32 0
149 %array = OpTypeRuntimeArray %sampler
150 %array_ptr = OpTypePointer UniformConstant %array
151 %2 = OpVariable %array_ptr UniformConstant
152 %void = OpTypeVoid
153 %functy = OpTypeFunction %void
154 %func = OpFunction %void None %functy
155 %1 = OpLabel
156 OpReturn
157 OpFunctionEnd
158 )";
159   CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
160   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
161 }
162 
TEST_F(ValidateMemory,VulkanUniformOnIntBad)163 TEST_F(ValidateMemory, VulkanUniformOnIntBad) {
164   char src[] = R"(
165             OpCapability Shader
166             OpMemoryModel Logical GLSL450
167             OpEntryPoint GLCompute %kernel "main"
168             OpExecutionMode %kernel LocalSize 1 1 1
169 
170             OpDecorate %var DescriptorSet 0
171             OpDecorate %var Binding 0
172 
173   %voidty = OpTypeVoid
174 %kernelty = OpTypeFunction %voidty
175    %intty = OpTypeInt 32 0
176    %varty = OpTypePointer Uniform %intty
177    %value = OpConstant %intty 42
178 
179      %var = OpVariable %varty Uniform
180 
181   %kernel = OpFunction %voidty None %kernelty
182    %label = OpLabel
183             OpStore %var %value
184             OpReturn
185             OpFunctionEnd
186 )";
187   CompileSuccessfully(src, SPV_ENV_VULKAN_1_1);
188   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
189   EXPECT_THAT(
190       getDiagnosticString(),
191       HasSubstr("From Vulkan spec, section 14.5.2:\n"
192                 "Variables identified with the Uniform storage class are used "
193                 "to access transparent buffer backed resources. Such variables "
194                 "must be typed as OpTypeStruct, or an array of this type"));
195 }
196 
197 // #version 440
198 // #extension GL_EXT_nonuniform_qualifier : enable
199 // layout(binding = 1) uniform sampler2D s2d[][2];
200 // layout(location = 0) in nonuniformEXT int i;
201 // void main()
202 // {
203 //     vec4 v = texture(s2d[i][i], vec2(0.3));
204 // }
TEST_F(ValidateMemory,VulkanUniformOnRuntimeArrayOfArrayBad)205 TEST_F(ValidateMemory, VulkanUniformOnRuntimeArrayOfArrayBad) {
206   char src[] = R"(
207                OpCapability Shader
208                OpCapability ShaderNonUniformEXT
209                OpCapability RuntimeDescriptorArrayEXT
210                OpCapability SampledImageArrayNonUniformIndexingEXT
211                OpExtension "SPV_EXT_descriptor_indexing"
212           %1 = OpExtInstImport "GLSL.std.450"
213                OpMemoryModel Logical GLSL450
214                OpEntryPoint Vertex %main "main" %i
215                OpSource GLSL 440
216                OpSourceExtension "GL_EXT_nonuniform_qualifier"
217                OpName %main "main"
218                OpName %v "v"
219                OpName %s2d "s2d"
220                OpName %i "i"
221                OpDecorate %s2d DescriptorSet 0
222                OpDecorate %s2d Binding 1
223                OpDecorate %i Location 0
224                OpDecorate %i NonUniformEXT
225                OpDecorate %21 NonUniformEXT
226                OpDecorate %22 NonUniformEXT
227                OpDecorate %25 NonUniformEXT
228        %void = OpTypeVoid
229           %3 = OpTypeFunction %void
230       %float = OpTypeFloat 32
231     %v4float = OpTypeVector %float 4
232 %_ptr_Function_v4float = OpTypePointer Function %v4float
233          %10 = OpTypeImage %float 2D 0 0 0 1 Unknown
234          %11 = OpTypeSampledImage %10
235        %uint = OpTypeInt 32 0
236      %uint_2 = OpConstant %uint 2
237 %_arr_11_uint_2 = OpTypeArray %11 %uint_2
238 %_runtimearr__arr_11_uint_2 = OpTypeRuntimeArray %_arr_11_uint_2
239 %_ptr_Uniform__runtimearr__arr_11_uint_2 = OpTypePointer Uniform %_runtimearr__arr_11_uint_2
240         %s2d = OpVariable %_ptr_Uniform__runtimearr__arr_11_uint_2 Uniform
241         %int = OpTypeInt 32 1
242 %_ptr_Input_int = OpTypePointer Input %int
243           %i = OpVariable %_ptr_Input_int Input
244 %_ptr_Uniform_11 = OpTypePointer Uniform %11
245     %v2float = OpTypeVector %float 2
246 %float_0_300000012 = OpConstant %float 0.300000012
247          %28 = OpConstantComposite %v2float %float_0_300000012 %float_0_300000012
248     %float_0 = OpConstant %float 0
249        %main = OpFunction %void None %3
250           %5 = OpLabel
251           %v = OpVariable %_ptr_Function_v4float Function
252          %21 = OpLoad %int %i
253          %22 = OpLoad %int %i
254          %24 = OpAccessChain %_ptr_Uniform_11 %s2d %21 %22
255          %25 = OpLoad %11 %24
256          %30 = OpImageSampleExplicitLod %v4float %25 %28 Lod %float_0
257                OpStore %v %30
258                OpReturn
259                OpFunctionEnd
260 )";
261   CompileSuccessfully(src, SPV_ENV_VULKAN_1_1);
262   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
263   EXPECT_THAT(
264       getDiagnosticString(),
265       HasSubstr("From Vulkan spec, section 14.5.2:\n"
266                 "Variables identified with the Uniform storage class are used "
267                 "to access transparent buffer backed resources. Such variables "
268                 "must be typed as OpTypeStruct, or an array of this type"));
269 }
270 
271 // #version 440
272 // layout (set=1, binding=1) uniform sampler2D variableName[2][2];
273 // void main() {
274 // }
TEST_F(ValidateMemory,VulkanUniformOnArrayOfArrayBad)275 TEST_F(ValidateMemory, VulkanUniformOnArrayOfArrayBad) {
276   char src[] = R"(
277                OpCapability Shader
278           %1 = OpExtInstImport "GLSL.std.450"
279                OpMemoryModel Logical GLSL450
280                OpEntryPoint Vertex %main "main"
281                OpSource GLSL 440
282                OpName %main "main"
283                OpName %variableName "variableName"
284                OpDecorate %variableName DescriptorSet 1
285                OpDecorate %variableName Binding 1
286        %void = OpTypeVoid
287           %3 = OpTypeFunction %void
288       %float = OpTypeFloat 32
289           %7 = OpTypeImage %float 2D 0 0 0 1 Unknown
290           %8 = OpTypeSampledImage %7
291        %uint = OpTypeInt 32 0
292      %uint_2 = OpConstant %uint 2
293 %_arr_8_uint_2 = OpTypeArray %8 %uint_2
294 %_arr__arr_8_uint_2_uint_2 = OpTypeArray %_arr_8_uint_2 %uint_2
295 %_ptr_Uniform__arr__arr_8_uint_2_uint_2 = OpTypePointer Uniform %_arr__arr_8_uint_2_uint_2
296 %variableName = OpVariable %_ptr_Uniform__arr__arr_8_uint_2_uint_2 Uniform
297        %main = OpFunction %void None %3
298           %5 = OpLabel
299                OpReturn
300                OpFunctionEnd
301 )";
302   CompileSuccessfully(src, SPV_ENV_VULKAN_1_1);
303   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
304   EXPECT_THAT(
305       getDiagnosticString(),
306       HasSubstr("From Vulkan spec, section 14.5.2:\n"
307                 "Variables identified with the Uniform storage class are used "
308                 "to access transparent buffer backed resources. Such variables "
309                 "must be typed as OpTypeStruct, or an array of this type"));
310 }
311 
TEST_F(ValidateMemory,MismatchingStorageClassesBad)312 TEST_F(ValidateMemory, MismatchingStorageClassesBad) {
313   std::string spirv = R"(
314 OpCapability Shader
315 OpMemoryModel Logical GLSL450
316 OpEntryPoint Fragment %func "func"
317 OpExecutionMode %func OriginUpperLeft
318 %float = OpTypeFloat 32
319 %float_ptr = OpTypePointer Uniform %float
320 %void = OpTypeVoid
321 %functy = OpTypeFunction %void
322 %func = OpFunction %void None %functy
323 %1 = OpLabel
324 %2 = OpVariable %float_ptr Function
325 OpReturn
326 OpFunctionEnd
327 )";
328   CompileSuccessfully(spirv.c_str());
329   EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
330   EXPECT_THAT(
331       getDiagnosticString(),
332       HasSubstr(
333           "From SPIR-V spec, section 3.32.8 on OpVariable:\n"
334           "Its Storage Class operand must be the same as the Storage Class "
335           "operand of the result type."));
336 }
337 
TEST_F(ValidateMemory,MatchingStorageClassesGood)338 TEST_F(ValidateMemory, MatchingStorageClassesGood) {
339   std::string spirv = R"(
340 OpCapability Shader
341 OpMemoryModel Logical GLSL450
342 OpEntryPoint Fragment %func "func"
343 OpExecutionMode %func OriginUpperLeft
344 %float = OpTypeFloat 32
345 %float_ptr = OpTypePointer Function %float
346 %void = OpTypeVoid
347 %functy = OpTypeFunction %void
348 %func = OpFunction %void None %functy
349 %1 = OpLabel
350 %2 = OpVariable %float_ptr Function
351 OpReturn
352 OpFunctionEnd
353 )";
354   CompileSuccessfully(spirv.c_str());
355   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
356 }
357 
TEST_F(ValidateMemory,WebGPUInitializerWithOutputStorageClassesGood)358 TEST_F(ValidateMemory, WebGPUInitializerWithOutputStorageClassesGood) {
359   std::string spirv = R"(
360 OpCapability Shader
361 OpCapability VulkanMemoryModelKHR
362 OpExtension "SPV_KHR_vulkan_memory_model"
363 OpMemoryModel Logical VulkanKHR
364 OpEntryPoint Fragment %func "func"
365 OpExecutionMode %func OriginUpperLeft
366 %float = OpTypeFloat 32
367 %float_ptr = OpTypePointer Output %float
368 %init_val = OpConstant %float 1.0
369 %1 = OpVariable %float_ptr Output %init_val
370 %void = OpTypeVoid
371 %functy = OpTypeFunction %void
372 %func = OpFunction %void None %functy
373 %2 = OpLabel
374 OpReturn
375 OpFunctionEnd
376 )";
377   CompileSuccessfully(spirv.c_str(), SPV_ENV_WEBGPU_0);
378   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_WEBGPU_0));
379 }
380 
TEST_F(ValidateMemory,WebGPUInitializerWithFunctionStorageClassesGood)381 TEST_F(ValidateMemory, WebGPUInitializerWithFunctionStorageClassesGood) {
382   std::string spirv = R"(
383 OpCapability Shader
384 OpCapability VulkanMemoryModelKHR
385 OpExtension "SPV_KHR_vulkan_memory_model"
386 OpMemoryModel Logical VulkanKHR
387 OpEntryPoint Fragment %func "func"
388 OpExecutionMode %func OriginUpperLeft
389 %float = OpTypeFloat 32
390 %float_ptr = OpTypePointer Function %float
391 %init_val = OpConstant %float 1.0
392 %void = OpTypeVoid
393 %functy = OpTypeFunction %void
394 %func = OpFunction %void None %functy
395 %1 = OpLabel
396 %2 = OpVariable %float_ptr Function %init_val
397 OpReturn
398 OpFunctionEnd
399 )";
400   CompileSuccessfully(spirv.c_str(), SPV_ENV_WEBGPU_0);
401   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_WEBGPU_0));
402 }
403 
TEST_F(ValidateMemory,WebGPUInitializerWithPrivateStorageClassesGood)404 TEST_F(ValidateMemory, WebGPUInitializerWithPrivateStorageClassesGood) {
405   std::string spirv = R"(
406 OpCapability Shader
407 OpCapability VulkanMemoryModelKHR
408 OpExtension "SPV_KHR_vulkan_memory_model"
409 OpMemoryModel Logical VulkanKHR
410 OpEntryPoint Fragment %func "func"
411 OpExecutionMode %func OriginUpperLeft
412 %float = OpTypeFloat 32
413 %float_ptr = OpTypePointer Private %float
414 %init_val = OpConstant %float 1.0
415 %1 = OpVariable %float_ptr Private %init_val
416 %void = OpTypeVoid
417 %functy = OpTypeFunction %void
418 %func = OpFunction %void None %functy
419 %2 = OpLabel
420 OpReturn
421 OpFunctionEnd
422 )";
423   CompileSuccessfully(spirv.c_str(), SPV_ENV_WEBGPU_0);
424   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_WEBGPU_0));
425 }
426 
TEST_F(ValidateMemory,WebGPUInitializerWithDisallowedStorageClassesBad)427 TEST_F(ValidateMemory, WebGPUInitializerWithDisallowedStorageClassesBad) {
428   std::string spirv = R"(
429 OpCapability Shader
430 OpCapability VulkanMemoryModelKHR
431 OpExtension "SPV_KHR_vulkan_memory_model"
432 OpMemoryModel Logical VulkanKHR
433 OpEntryPoint Fragment %func "func"
434 OpExecutionMode %func OriginUpperLeft
435 %float = OpTypeFloat 32
436 %float_ptr = OpTypePointer Uniform %float
437 %init_val = OpConstant %float 1.0
438 %1 = OpVariable %float_ptr Uniform %init_val
439 %void = OpTypeVoid
440 %functy = OpTypeFunction %void
441 %func = OpFunction %void None %functy
442 %2 = OpLabel
443 OpReturn
444 OpFunctionEnd
445 )";
446   CompileSuccessfully(spirv.c_str(), SPV_ENV_WEBGPU_0);
447   EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_WEBGPU_0));
448   EXPECT_THAT(
449       getDiagnosticString(),
450       HasSubstr(
451           "OpVariable, <id> '5[%5]', has a disallowed initializer & storage "
452           "class combination.\nFrom WebGPU execution environment spec:\n"
453           "Variable declarations that include initializers must have one of "
454           "the following storage classes: Output, Private, or Function\n"
455           "  %5 = OpVariable %_ptr_Uniform_float Uniform %float_1\n"));
456 }
457 
TEST_F(ValidateMemory,VulkanInitializerWithOutputStorageClassesGood)458 TEST_F(ValidateMemory, VulkanInitializerWithOutputStorageClassesGood) {
459   std::string spirv = R"(
460 OpCapability Shader
461 OpMemoryModel Logical GLSL450
462 OpEntryPoint Fragment %func "func"
463 OpExecutionMode %func OriginUpperLeft
464 %float = OpTypeFloat 32
465 %float_ptr = OpTypePointer Output %float
466 %init_val = OpConstant %float 1.0
467 %1 = OpVariable %float_ptr Output %init_val
468 %void = OpTypeVoid
469 %functy = OpTypeFunction %void
470 %func = OpFunction %void None %functy
471 %2 = OpLabel
472 OpReturn
473 OpFunctionEnd
474 )";
475   CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
476   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
477 }
478 
TEST_F(ValidateMemory,VulkanInitializerWithFunctionStorageClassesGood)479 TEST_F(ValidateMemory, VulkanInitializerWithFunctionStorageClassesGood) {
480   std::string spirv = R"(
481 OpCapability Shader
482 OpMemoryModel Logical GLSL450
483 OpEntryPoint Fragment %func "func"
484 OpExecutionMode %func OriginUpperLeft
485 %float = OpTypeFloat 32
486 %float_ptr = OpTypePointer Function %float
487 %init_val = OpConstant %float 1.0
488 %void = OpTypeVoid
489 %functy = OpTypeFunction %void
490 %func = OpFunction %void None %functy
491 %1 = OpLabel
492 %2 = OpVariable %float_ptr Function %init_val
493 OpReturn
494 OpFunctionEnd
495 )";
496   CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
497   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
498 }
499 
TEST_F(ValidateMemory,VulkanInitializerWithPrivateStorageClassesGood)500 TEST_F(ValidateMemory, VulkanInitializerWithPrivateStorageClassesGood) {
501   std::string spirv = R"(
502 OpCapability Shader
503 OpMemoryModel Logical GLSL450
504 OpEntryPoint Fragment %func "func"
505 OpExecutionMode %func OriginUpperLeft
506 %float = OpTypeFloat 32
507 %float_ptr = OpTypePointer Private %float
508 %init_val = OpConstant %float 1.0
509 %1 = OpVariable %float_ptr Private %init_val
510 %void = OpTypeVoid
511 %functy = OpTypeFunction %void
512 %func = OpFunction %void None %functy
513 %2 = OpLabel
514 OpReturn
515 OpFunctionEnd
516 )";
517   CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
518   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
519 }
520 
TEST_F(ValidateMemory,VulkanInitializerWithDisallowedStorageClassesBad)521 TEST_F(ValidateMemory, VulkanInitializerWithDisallowedStorageClassesBad) {
522   std::string spirv = R"(
523 OpCapability Shader
524 OpMemoryModel Logical GLSL450
525 OpEntryPoint Fragment %func "func"
526 OpExecutionMode %func OriginUpperLeft
527 %float = OpTypeFloat 32
528 %float_ptr = OpTypePointer Input %float
529 %init_val = OpConstant %float 1.0
530 %1 = OpVariable %float_ptr Input %init_val
531 %void = OpTypeVoid
532 %functy = OpTypeFunction %void
533 %func = OpFunction %void None %functy
534 %2 = OpLabel
535 OpReturn
536 OpFunctionEnd
537 )";
538   CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
539   EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
540   EXPECT_THAT(
541       getDiagnosticString(),
542       HasSubstr(
543           "OpVariable, <id> '5[%5]', has a disallowed initializer & storage "
544           "class combination.\nFrom Vulkan spec, Appendix A:\n"
545           "Variable declarations that include initializers must have one of "
546           "the following storage classes: Output, Private, or Function\n  "
547           "%5 = OpVariable %_ptr_Input_float Input %float_1\n"));
548 }
549 
TEST_F(ValidateMemory,ArrayLenCorrectResultType)550 TEST_F(ValidateMemory, ArrayLenCorrectResultType) {
551   std::string spirv = R"(
552                OpCapability Shader
553                OpMemoryModel Logical GLSL450
554                OpEntryPoint Fragment %1 "main"
555                OpExecutionMode %1 OriginUpperLeft
556        %void = OpTypeVoid
557           %3 = OpTypeFunction %void
558       %float = OpTypeFloat 32
559      %uint = OpTypeInt 32 0
560 %_runtimearr_float = OpTypeRuntimeArray %float
561   %_struct_7 = OpTypeStruct %_runtimearr_float
562 %_ptr_Function__struct_7 = OpTypePointer Function %_struct_7
563           %1 = OpFunction %void None %3
564           %9 = OpLabel
565          %10 = OpVariable %_ptr_Function__struct_7 Function
566          %11 = OpArrayLength %uint %10 0
567                OpReturn
568                OpFunctionEnd
569 
570 )";
571 
572   CompileSuccessfully(spirv.c_str());
573   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
574 }
575 
TEST_F(ValidateMemory,ArrayLenIndexCorrectWith2Members)576 TEST_F(ValidateMemory, ArrayLenIndexCorrectWith2Members) {
577   std::string spirv = R"(
578                OpCapability Shader
579                OpMemoryModel Logical GLSL450
580                OpEntryPoint Fragment %1 "main"
581                OpExecutionMode %1 OriginUpperLeft
582        %void = OpTypeVoid
583           %3 = OpTypeFunction %void
584       %float = OpTypeFloat 32
585      %uint = OpTypeInt 32 0
586 %_runtimearr_float = OpTypeRuntimeArray %float
587   %_struct_7 = OpTypeStruct %float %_runtimearr_float
588 %_ptr_Function__struct_7  = OpTypePointer Function %_struct_7
589           %1 = OpFunction %void None %3
590           %9 = OpLabel
591          %10 = OpVariable %_ptr_Function__struct_7  Function
592          %11 = OpArrayLength %uint %10 1
593                OpReturn
594                OpFunctionEnd
595 
596 )";
597 
598   CompileSuccessfully(spirv.c_str());
599   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
600 }
601 
TEST_F(ValidateMemory,ArrayLenResultNotIntType)602 TEST_F(ValidateMemory, ArrayLenResultNotIntType) {
603   std::string spirv = R"(
604                OpCapability Shader
605                OpMemoryModel Logical GLSL450
606                OpEntryPoint Fragment %1 "main"
607                OpExecutionMode %1 OriginUpperLeft
608        %void = OpTypeVoid
609           %3 = OpTypeFunction %void
610       %float = OpTypeFloat 32
611 %_runtimearr_float = OpTypeRuntimeArray %float
612   %_struct_6 = OpTypeStruct %_runtimearr_float
613 %_ptr_Function__struct_6 = OpTypePointer Function %_struct_6
614           %1 = OpFunction %void None %3
615           %8 = OpLabel
616           %9 = OpVariable %_ptr_Function__struct_6 Function
617          %10 = OpArrayLength %float %9 0
618                OpReturn
619                OpFunctionEnd
620 )";
621 
622   CompileSuccessfully(spirv.c_str());
623   EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
624   EXPECT_THAT(
625       getDiagnosticString(),
626       HasSubstr(
627           "The Result Type of OpArrayLength <id> '10[%10]' must be OpTypeInt "
628           "with width 32 and signedness 0.\n  %10 = OpArrayLength %float %9 "
629           "0\n"));
630 }
631 
TEST_F(ValidateMemory,ArrayLenResultNot32bits)632 TEST_F(ValidateMemory, ArrayLenResultNot32bits) {
633   std::string spirv = R"(
634                OpCapability Shader
635                OpCapability Int16
636                OpMemoryModel Logical GLSL450
637                OpEntryPoint Fragment %1 "main"
638                OpExecutionMode %1 OriginUpperLeft
639        %void = OpTypeVoid
640           %3 = OpTypeFunction %void
641       %float = OpTypeFloat 32
642      %ushort = OpTypeInt 16 0
643 %_runtimearr_float = OpTypeRuntimeArray %float
644   %_struct_7 = OpTypeStruct %_runtimearr_float
645 %_ptr_Function__struct_7 = OpTypePointer Function %_struct_7
646           %1 = OpFunction %void None %3
647           %9 = OpLabel
648          %10 = OpVariable %_ptr_Function__struct_7 Function
649          %11 = OpArrayLength %ushort %10 0
650                OpReturn
651                OpFunctionEnd
652 
653 )";
654 
655   CompileSuccessfully(spirv.c_str());
656   EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
657   EXPECT_THAT(
658       getDiagnosticString(),
659       HasSubstr(
660           "The Result Type of OpArrayLength <id> '11[%11]' must be OpTypeInt "
661           "with width 32 and signedness 0.\n  %11 = OpArrayLength %ushort %10 "
662           "0\n"));
663 }
664 
TEST_F(ValidateMemory,ArrayLenResultSigned)665 TEST_F(ValidateMemory, ArrayLenResultSigned) {
666   std::string spirv = R"(
667                OpCapability Shader
668                OpMemoryModel Logical GLSL450
669                OpEntryPoint Fragment %1 "main"
670                OpExecutionMode %1 OriginUpperLeft
671        %void = OpTypeVoid
672           %3 = OpTypeFunction %void
673       %float = OpTypeFloat 32
674      %int = OpTypeInt 32 1
675 %_runtimearr_float = OpTypeRuntimeArray %float
676   %_struct_7 = OpTypeStruct %_runtimearr_float
677 %_ptr_Function__struct_7 = OpTypePointer Function %_struct_7
678           %1 = OpFunction %void None %3
679           %9 = OpLabel
680          %10 = OpVariable %_ptr_Function__struct_7 Function
681          %11 = OpArrayLength %int %10 0
682                OpReturn
683                OpFunctionEnd
684 
685 )";
686 
687   CompileSuccessfully(spirv.c_str());
688   EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
689   EXPECT_THAT(
690       getDiagnosticString(),
691       HasSubstr(
692           "The Result Type of OpArrayLength <id> '11[%11]' must be OpTypeInt "
693           "with width 32 and signedness 0.\n  %11 = OpArrayLength %int %10 "
694           "0\n"));
695 }
696 
TEST_F(ValidateMemory,ArrayLenInputNotStruct)697 TEST_F(ValidateMemory, ArrayLenInputNotStruct) {
698   std::string spirv = R"(
699                OpCapability Shader
700                OpMemoryModel Logical GLSL450
701                OpEntryPoint Fragment %1 "main"
702                OpExecutionMode %1 OriginUpperLeft
703        %void = OpTypeVoid
704           %3 = OpTypeFunction %void
705       %float = OpTypeFloat 32
706      %uint = OpTypeInt 32 0
707 %_runtimearr_float = OpTypeRuntimeArray %float
708   %_struct_7 = OpTypeStruct %_runtimearr_float
709 %_ptr_Function_float = OpTypePointer Function %float
710           %1 = OpFunction %void None %3
711           %9 = OpLabel
712          %10 = OpVariable %_ptr_Function_float Function
713          %11 = OpArrayLength %uint %10 0
714                OpReturn
715                OpFunctionEnd
716 
717 )";
718 
719   CompileSuccessfully(spirv.c_str());
720   EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
721   EXPECT_THAT(getDiagnosticString(),
722               HasSubstr("The Struture's type in OpArrayLength <id> '11[%11]' "
723                         "must be a pointer to an OpTypeStruct."));
724 }
725 
TEST_F(ValidateMemory,ArrayLenInputLastMemberNoRTA)726 TEST_F(ValidateMemory, ArrayLenInputLastMemberNoRTA) {
727   std::string spirv = R"(
728                OpCapability Shader
729                OpMemoryModel Logical GLSL450
730                OpEntryPoint Fragment %1 "main"
731                OpExecutionMode %1 OriginUpperLeft
732        %void = OpTypeVoid
733           %3 = OpTypeFunction %void
734       %float = OpTypeFloat 32
735      %uint = OpTypeInt 32 0
736 %_runtimearr_float = OpTypeRuntimeArray %float
737   %_struct_7 = OpTypeStruct %float
738 %_ptr_Function__struct_7  = OpTypePointer Function %_struct_7
739           %1 = OpFunction %void None %3
740           %9 = OpLabel
741          %10 = OpVariable %_ptr_Function__struct_7  Function
742          %11 = OpArrayLength %uint %10 0
743                OpReturn
744                OpFunctionEnd
745 
746 )";
747 
748   CompileSuccessfully(spirv.c_str());
749   EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
750   EXPECT_THAT(
751       getDiagnosticString(),
752       HasSubstr("The Struture's last member in OpArrayLength <id> '11[%11]' "
753                 "must be an OpTypeRuntimeArray.\n  %11 = OpArrayLength %uint "
754                 "%10 0\n"));
755 }
756 
TEST_F(ValidateMemory,ArrayLenInputLastMemberNoRTA2)757 TEST_F(ValidateMemory, ArrayLenInputLastMemberNoRTA2) {
758   std::string spirv = R"(
759                OpCapability Shader
760                OpMemoryModel Logical GLSL450
761                OpEntryPoint Fragment %1 "main"
762                OpExecutionMode %1 OriginUpperLeft
763        %void = OpTypeVoid
764           %3 = OpTypeFunction %void
765       %float = OpTypeFloat 32
766      %uint = OpTypeInt 32 0
767 %_runtimearr_float = OpTypeRuntimeArray %float
768   %_struct_7 = OpTypeStruct %_runtimearr_float %float
769 %_ptr_Function__struct_7  = OpTypePointer Function %_struct_7
770           %1 = OpFunction %void None %3
771           %9 = OpLabel
772          %10 = OpVariable %_ptr_Function__struct_7  Function
773          %11 = OpArrayLength %uint %10 1
774                OpReturn
775                OpFunctionEnd
776 
777 )";
778 
779   CompileSuccessfully(spirv.c_str());
780   EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
781   EXPECT_THAT(
782       getDiagnosticString(),
783       HasSubstr("The Struture's last member in OpArrayLength <id> '11[%11]' "
784                 "must be an OpTypeRuntimeArray.\n  %11 = OpArrayLength %uint "
785                 "%10 1\n"));
786 }
787 
TEST_F(ValidateMemory,ArrayLenIndexNotLastMember)788 TEST_F(ValidateMemory, ArrayLenIndexNotLastMember) {
789   std::string spirv = R"(
790                OpCapability Shader
791                OpMemoryModel Logical GLSL450
792                OpEntryPoint Fragment %1 "main"
793                OpExecutionMode %1 OriginUpperLeft
794        %void = OpTypeVoid
795           %3 = OpTypeFunction %void
796       %float = OpTypeFloat 32
797      %uint = OpTypeInt 32 0
798 %_runtimearr_float = OpTypeRuntimeArray %float
799   %_struct_7 = OpTypeStruct %float %_runtimearr_float
800 %_ptr_Function__struct_7  = OpTypePointer Function %_struct_7
801           %1 = OpFunction %void None %3
802           %9 = OpLabel
803          %10 = OpVariable %_ptr_Function__struct_7  Function
804          %11 = OpArrayLength %uint %10 0
805                OpReturn
806                OpFunctionEnd
807 
808 )";
809 
810   CompileSuccessfully(spirv.c_str());
811   EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
812   EXPECT_THAT(
813       getDiagnosticString(),
814       HasSubstr(
815           "The array member in OpArrayLength <id> '11[%11]' must be an the "
816           "last member of the struct.\n  %11 = OpArrayLength %uint %10 0\n"));
817 }
818 
TEST_F(ValidateMemory,ArrayLenIndexNotPointerToStruct)819 TEST_F(ValidateMemory, ArrayLenIndexNotPointerToStruct) {
820   std::string spirv = R"(
821                OpCapability Shader
822                OpMemoryModel Logical GLSL450
823                OpEntryPoint Fragment %1 "main"
824                OpExecutionMode %1 OriginUpperLeft
825        %void = OpTypeVoid
826           %3 = OpTypeFunction %void
827       %float = OpTypeFloat 32
828      %uint = OpTypeInt 32 0
829 %_runtimearr_float = OpTypeRuntimeArray %float
830   %_struct_7 = OpTypeStruct %float %_runtimearr_float
831 %_ptr_Function__struct_7  = OpTypePointer Function %_struct_7
832           %1 = OpFunction %void None %3
833           %9 = OpLabel
834          %10 = OpVariable %_ptr_Function__struct_7  Function
835          %11 = OpLoad %_struct_7 %10
836          %12 = OpArrayLength %uint %11 0
837                OpReturn
838                OpFunctionEnd
839 
840 )";
841 
842   CompileSuccessfully(spirv.c_str());
843   EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
844   EXPECT_THAT(
845       getDiagnosticString(),
846       HasSubstr(
847           "The Struture's type in OpArrayLength <id> '12[%12]' must be a "
848           "pointer to an OpTypeStruct.\n  %12 = OpArrayLength %uint %11 0\n"));
849 }
850 
TEST_F(ValidateMemory,ArrayLenPointerIsAType)851 TEST_F(ValidateMemory, ArrayLenPointerIsAType) {
852   std::string spirv = R"(
853                OpCapability Shader
854                OpMemoryModel Logical GLSL450
855                OpEntryPoint Fragment %1 "main"
856                OpExecutionMode %1 OriginUpperLeft
857        %void = OpTypeVoid
858           %3 = OpTypeFunction %void
859       %float = OpTypeFloat 32
860        %uint = OpTypeInt 32 0
861           %1 = OpFunction %void None %3
862           %9 = OpLabel
863          %12 = OpArrayLength %uint %float 0
864                OpReturn
865                OpFunctionEnd
866 
867 )";
868 
869   CompileSuccessfully(spirv.c_str());
870   EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
871   EXPECT_THAT(getDiagnosticString(), HasSubstr("Operand 4[%float] cannot be a "
872                                                "type"));
873 }
874 
TEST_F(ValidateMemory,PushConstantNotStructGood)875 TEST_F(ValidateMemory, PushConstantNotStructGood) {
876   std::string spirv = R"(
877             OpCapability Shader
878             OpMemoryModel Logical GLSL450
879             OpEntryPoint Fragment %1 "main"
880             OpExecutionMode %1 OriginUpperLeft
881 
882     %void = OpTypeVoid
883   %voidfn = OpTypeFunction %void
884    %float = OpTypeFloat 32
885      %ptr = OpTypePointer PushConstant %float
886       %pc = OpVariable %ptr PushConstant
887 
888        %1 = OpFunction %void None %voidfn
889    %label = OpLabel
890             OpReturn
891             OpFunctionEnd
892 )";
893   CompileSuccessfully(spirv);
894   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
895 }
896 
TEST_F(ValidateMemory,VulkanPushConstantNotStructBad)897 TEST_F(ValidateMemory, VulkanPushConstantNotStructBad) {
898   std::string spirv = R"(
899             OpCapability Shader
900             OpMemoryModel Logical GLSL450
901             OpEntryPoint Fragment %1 "main"
902             OpExecutionMode %1 OriginUpperLeft
903 
904     %void = OpTypeVoid
905   %voidfn = OpTypeFunction %void
906    %float = OpTypeFloat 32
907      %ptr = OpTypePointer PushConstant %float
908       %pc = OpVariable %ptr PushConstant
909 
910        %1 = OpFunction %void None %voidfn
911    %label = OpLabel
912             OpReturn
913             OpFunctionEnd
914 )";
915   CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
916   EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
917   EXPECT_THAT(getDiagnosticString(),
918               HasSubstr("PushConstant OpVariable <id> '6[%6]' has illegal "
919                         "type.\nFrom Vulkan spec, section 14.5.1:\n"
920                         "Such variables must be typed as OpTypeStruct, "
921                         "or an array of this type"));
922 }
923 
TEST_F(ValidateMemory,VulkanPushConstant)924 TEST_F(ValidateMemory, VulkanPushConstant) {
925   std::string spirv = R"(
926             OpCapability Shader
927             OpMemoryModel Logical GLSL450
928             OpEntryPoint Fragment %1 "main"
929             OpExecutionMode %1 OriginUpperLeft
930 
931             OpDecorate %struct Block
932             OpMemberDecorate %struct 0 Offset 0
933 
934     %void = OpTypeVoid
935   %voidfn = OpTypeFunction %void
936    %float = OpTypeFloat 32
937   %struct = OpTypeStruct %float
938      %ptr = OpTypePointer PushConstant %struct
939       %pc = OpVariable %ptr PushConstant
940 
941        %1 = OpFunction %void None %voidfn
942    %label = OpLabel
943             OpReturn
944             OpFunctionEnd
945 )";
946   CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
947   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
948 }
949 
TEST_F(ValidateMemory,VulkanMemoryModelDeviceScopeLoadBad1)950 TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeLoadBad1) {
951   const std::string spirv = R"(
952 OpCapability Shader
953 OpCapability VulkanMemoryModelKHR
954 OpCapability Linkage
955 OpExtension "SPV_KHR_vulkan_memory_model"
956 OpMemoryModel Logical VulkanKHR
957 %void = OpTypeVoid
958 %int = OpTypeInt 32 0
959 %device = OpConstant %int 1
960 %int_ptr_ssbo = OpTypePointer StorageBuffer %int
961 %var = OpVariable %int_ptr_ssbo StorageBuffer
962 %voidfn = OpTypeFunction %void
963 %func = OpFunction %void None %voidfn
964 %entry = OpLabel
965 %load = OpLoad %int %var MakePointerVisibleKHR|NonPrivatePointerKHR %device
966 OpReturn
967 OpFunctionEnd
968 )";
969 
970   CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
971   EXPECT_EQ(SPV_ERROR_INVALID_DATA,
972             ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
973   EXPECT_THAT(
974       getDiagnosticString(),
975       HasSubstr("Use of device scope with VulkanKHR memory model requires the "
976                 "VulkanMemoryModelDeviceScopeKHR capability"));
977 }
978 
TEST_F(ValidateMemory,VulkanMemoryModelDeviceScopeLoadBad2)979 TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeLoadBad2) {
980   const std::string spirv = R"(
981 OpCapability Shader
982 OpCapability VulkanMemoryModelKHR
983 OpCapability Linkage
984 OpExtension "SPV_KHR_vulkan_memory_model"
985 OpMemoryModel Logical VulkanKHR
986 %void = OpTypeVoid
987 %int = OpTypeInt 32 0
988 %device = OpConstant %int 1
989 %int_ptr_ssbo = OpTypePointer StorageBuffer %int
990 %var = OpVariable %int_ptr_ssbo StorageBuffer
991 %voidfn = OpTypeFunction %void
992 %func = OpFunction %void None %voidfn
993 %entry = OpLabel
994 %load = OpLoad %int %var Aligned|MakePointerVisibleKHR|NonPrivatePointerKHR 4 %device
995 OpReturn
996 OpFunctionEnd
997 )";
998 
999   CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
1000   EXPECT_EQ(SPV_ERROR_INVALID_DATA,
1001             ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1002   EXPECT_THAT(
1003       getDiagnosticString(),
1004       HasSubstr("Use of device scope with VulkanKHR memory model requires the "
1005                 "VulkanMemoryModelDeviceScopeKHR capability"));
1006 }
1007 
TEST_F(ValidateMemory,VulkanMemoryModelDeviceScopeLoadGood1)1008 TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeLoadGood1) {
1009   const std::string spirv = R"(
1010 OpCapability Shader
1011 OpCapability VulkanMemoryModelKHR
1012 OpCapability VulkanMemoryModelDeviceScopeKHR
1013 OpCapability Linkage
1014 OpExtension "SPV_KHR_vulkan_memory_model"
1015 OpMemoryModel Logical VulkanKHR
1016 %void = OpTypeVoid
1017 %int = OpTypeInt 32 0
1018 %device = OpConstant %int 1
1019 %int_ptr_ssbo = OpTypePointer StorageBuffer %int
1020 %var = OpVariable %int_ptr_ssbo StorageBuffer
1021 %voidfn = OpTypeFunction %void
1022 %func = OpFunction %void None %voidfn
1023 %entry = OpLabel
1024 %load = OpLoad %int %var MakePointerVisibleKHR|NonPrivatePointerKHR %device
1025 OpReturn
1026 OpFunctionEnd
1027 )";
1028 
1029   CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
1030   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1031 }
1032 
TEST_F(ValidateMemory,VulkanMemoryModelDeviceScopeLoadGood2)1033 TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeLoadGood2) {
1034   const std::string spirv = R"(
1035 OpCapability Shader
1036 OpCapability VulkanMemoryModelKHR
1037 OpCapability VulkanMemoryModelDeviceScopeKHR
1038 OpCapability Linkage
1039 OpExtension "SPV_KHR_vulkan_memory_model"
1040 OpMemoryModel Logical VulkanKHR
1041 %void = OpTypeVoid
1042 %int = OpTypeInt 32 0
1043 %device = OpConstant %int 1
1044 %int_ptr_ssbo = OpTypePointer StorageBuffer %int
1045 %var = OpVariable %int_ptr_ssbo StorageBuffer
1046 %voidfn = OpTypeFunction %void
1047 %func = OpFunction %void None %voidfn
1048 %entry = OpLabel
1049 %load = OpLoad %int %var Aligned|MakePointerVisibleKHR|NonPrivatePointerKHR 4 %device
1050 OpReturn
1051 OpFunctionEnd
1052 )";
1053 
1054   CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
1055   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1056 }
1057 
TEST_F(ValidateMemory,VulkanMemoryModelDeviceScopeStoreBad1)1058 TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeStoreBad1) {
1059   const std::string spirv = R"(
1060 OpCapability Shader
1061 OpCapability VulkanMemoryModelKHR
1062 OpCapability Linkage
1063 OpExtension "SPV_KHR_vulkan_memory_model"
1064 OpMemoryModel Logical VulkanKHR
1065 %void = OpTypeVoid
1066 %int = OpTypeInt 32 0
1067 %device = OpConstant %int 1
1068 %int_ptr_ssbo = OpTypePointer StorageBuffer %int
1069 %var = OpVariable %int_ptr_ssbo StorageBuffer
1070 %voidfn = OpTypeFunction %void
1071 %func = OpFunction %void None %voidfn
1072 %entry = OpLabel
1073 OpStore %var %device MakePointerAvailableKHR|NonPrivatePointerKHR %device
1074 OpReturn
1075 OpFunctionEnd
1076 )";
1077 
1078   CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
1079   EXPECT_EQ(SPV_ERROR_INVALID_DATA,
1080             ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1081   EXPECT_THAT(
1082       getDiagnosticString(),
1083       HasSubstr("Use of device scope with VulkanKHR memory model requires the "
1084                 "VulkanMemoryModelDeviceScopeKHR capability"));
1085 }
1086 
TEST_F(ValidateMemory,VulkanMemoryModelDeviceScopeStoreBad2)1087 TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeStoreBad2) {
1088   const std::string spirv = R"(
1089 OpCapability Shader
1090 OpCapability VulkanMemoryModelKHR
1091 OpCapability Linkage
1092 OpExtension "SPV_KHR_vulkan_memory_model"
1093 OpMemoryModel Logical VulkanKHR
1094 %void = OpTypeVoid
1095 %int = OpTypeInt 32 0
1096 %device = OpConstant %int 1
1097 %int_ptr_ssbo = OpTypePointer StorageBuffer %int
1098 %var = OpVariable %int_ptr_ssbo StorageBuffer
1099 %voidfn = OpTypeFunction %void
1100 %func = OpFunction %void None %voidfn
1101 %entry = OpLabel
1102 OpStore %var %device Aligned|MakePointerAvailableKHR|NonPrivatePointerKHR 4 %device
1103 OpReturn
1104 OpFunctionEnd
1105 )";
1106 
1107   CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
1108   EXPECT_EQ(SPV_ERROR_INVALID_DATA,
1109             ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1110   EXPECT_THAT(
1111       getDiagnosticString(),
1112       HasSubstr("Use of device scope with VulkanKHR memory model requires the "
1113                 "VulkanMemoryModelDeviceScopeKHR capability"));
1114 }
1115 
TEST_F(ValidateMemory,VulkanMemoryModelDeviceScopeStoreGood1)1116 TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeStoreGood1) {
1117   const std::string spirv = R"(
1118 OpCapability Shader
1119 OpCapability VulkanMemoryModelKHR
1120 OpCapability VulkanMemoryModelDeviceScopeKHR
1121 OpCapability Linkage
1122 OpExtension "SPV_KHR_vulkan_memory_model"
1123 OpMemoryModel Logical VulkanKHR
1124 %void = OpTypeVoid
1125 %int = OpTypeInt 32 0
1126 %device = OpConstant %int 1
1127 %int_ptr_ssbo = OpTypePointer StorageBuffer %int
1128 %var = OpVariable %int_ptr_ssbo StorageBuffer
1129 %voidfn = OpTypeFunction %void
1130 %func = OpFunction %void None %voidfn
1131 %entry = OpLabel
1132 OpStore %var %device MakePointerAvailableKHR|NonPrivatePointerKHR %device
1133 OpReturn
1134 OpFunctionEnd
1135 )";
1136 
1137   CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
1138   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1139 }
1140 
TEST_F(ValidateMemory,VulkanMemoryModelDeviceScopeStoreGood2)1141 TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeStoreGood2) {
1142   const std::string spirv = R"(
1143 OpCapability Shader
1144 OpCapability VulkanMemoryModelKHR
1145 OpCapability VulkanMemoryModelDeviceScopeKHR
1146 OpCapability Linkage
1147 OpExtension "SPV_KHR_vulkan_memory_model"
1148 OpMemoryModel Logical VulkanKHR
1149 %void = OpTypeVoid
1150 %int = OpTypeInt 32 0
1151 %device = OpConstant %int 1
1152 %int_ptr_ssbo = OpTypePointer StorageBuffer %int
1153 %var = OpVariable %int_ptr_ssbo StorageBuffer
1154 %voidfn = OpTypeFunction %void
1155 %func = OpFunction %void None %voidfn
1156 %entry = OpLabel
1157 OpStore %var %device Aligned|MakePointerAvailableKHR|NonPrivatePointerKHR 4 %device
1158 OpReturn
1159 OpFunctionEnd
1160 )";
1161 
1162   CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
1163   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1164 }
1165 
TEST_F(ValidateMemory,VulkanMemoryModelDeviceScopeCopyMemoryBad1)1166 TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeCopyMemoryBad1) {
1167   const std::string spirv = R"(
1168 OpCapability Shader
1169 OpCapability VulkanMemoryModelKHR
1170 OpCapability Linkage
1171 OpExtension "SPV_KHR_vulkan_memory_model"
1172 OpMemoryModel Logical VulkanKHR
1173 %void = OpTypeVoid
1174 %int = OpTypeInt 32 0
1175 %device = OpConstant %int 1
1176 %int_ptr_ssbo = OpTypePointer StorageBuffer %int
1177 %var1 = OpVariable %int_ptr_ssbo StorageBuffer
1178 %var2 = OpVariable %int_ptr_ssbo StorageBuffer
1179 %voidfn = OpTypeFunction %void
1180 %func = OpFunction %void None %voidfn
1181 %entry = OpLabel
1182 OpCopyMemory %var1 %var2 MakePointerAvailableKHR|NonPrivatePointerKHR %device
1183 OpReturn
1184 OpFunctionEnd
1185 )";
1186 
1187   CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
1188   EXPECT_EQ(SPV_ERROR_INVALID_DATA,
1189             ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1190   EXPECT_THAT(
1191       getDiagnosticString(),
1192       HasSubstr("Use of device scope with VulkanKHR memory model requires the "
1193                 "VulkanMemoryModelDeviceScopeKHR capability"));
1194 }
1195 
TEST_F(ValidateMemory,VulkanMemoryModelDeviceScopeCopyMemoryBad2)1196 TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeCopyMemoryBad2) {
1197   const std::string spirv = R"(
1198 OpCapability Shader
1199 OpCapability VulkanMemoryModelKHR
1200 OpCapability Linkage
1201 OpExtension "SPV_KHR_vulkan_memory_model"
1202 OpMemoryModel Logical VulkanKHR
1203 %void = OpTypeVoid
1204 %int = OpTypeInt 32 0
1205 %device = OpConstant %int 1
1206 %workgroup = OpConstant %int 1
1207 %int_ptr_ssbo = OpTypePointer StorageBuffer %int
1208 %var1 = OpVariable %int_ptr_ssbo StorageBuffer
1209 %var2 = OpVariable %int_ptr_ssbo StorageBuffer
1210 %voidfn = OpTypeFunction %void
1211 %func = OpFunction %void None %voidfn
1212 %entry = OpLabel
1213 OpCopyMemory %var1 %var2 Aligned|MakePointerVisibleKHR|MakePointerAvailableKHR|NonPrivatePointerKHR 4 %device %workgroup
1214 OpReturn
1215 OpFunctionEnd
1216 )";
1217 
1218   CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
1219   EXPECT_EQ(SPV_ERROR_INVALID_DATA,
1220             ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1221   EXPECT_THAT(
1222       getDiagnosticString(),
1223       HasSubstr("Use of device scope with VulkanKHR memory model requires the "
1224                 "VulkanMemoryModelDeviceScopeKHR capability"));
1225 }
1226 
TEST_F(ValidateMemory,VulkanMemoryModelDeviceScopeCopyMemoryBad3)1227 TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeCopyMemoryBad3) {
1228   const std::string spirv = R"(
1229 OpCapability Shader
1230 OpCapability VulkanMemoryModelKHR
1231 OpCapability Linkage
1232 OpExtension "SPV_KHR_vulkan_memory_model"
1233 OpMemoryModel Logical VulkanKHR
1234 %void = OpTypeVoid
1235 %int = OpTypeInt 32 0
1236 %device = OpConstant %int 1
1237 %workgroup = OpConstant %int 1
1238 %int_ptr_ssbo = OpTypePointer StorageBuffer %int
1239 %var1 = OpVariable %int_ptr_ssbo StorageBuffer
1240 %var2 = OpVariable %int_ptr_ssbo StorageBuffer
1241 %voidfn = OpTypeFunction %void
1242 %func = OpFunction %void None %voidfn
1243 %entry = OpLabel
1244 OpCopyMemory %var1 %var2 Aligned|MakePointerVisibleKHR|MakePointerAvailableKHR|NonPrivatePointerKHR 4 %workgroup %device
1245 OpReturn
1246 OpFunctionEnd
1247 )";
1248 
1249   CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
1250   EXPECT_EQ(SPV_ERROR_INVALID_DATA,
1251             ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1252   EXPECT_THAT(
1253       getDiagnosticString(),
1254       HasSubstr("Use of device scope with VulkanKHR memory model requires the "
1255                 "VulkanMemoryModelDeviceScopeKHR capability"));
1256 }
1257 
TEST_F(ValidateMemory,VulkanMemoryModelDeviceScopeCopyMemoryGood1)1258 TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeCopyMemoryGood1) {
1259   const std::string spirv = R"(
1260 OpCapability Shader
1261 OpCapability VulkanMemoryModelKHR
1262 OpCapability VulkanMemoryModelDeviceScopeKHR
1263 OpCapability Linkage
1264 OpExtension "SPV_KHR_vulkan_memory_model"
1265 OpMemoryModel Logical VulkanKHR
1266 %void = OpTypeVoid
1267 %int = OpTypeInt 32 0
1268 %device = OpConstant %int 1
1269 %int_ptr_ssbo = OpTypePointer StorageBuffer %int
1270 %var1 = OpVariable %int_ptr_ssbo StorageBuffer
1271 %var2 = OpVariable %int_ptr_ssbo StorageBuffer
1272 %voidfn = OpTypeFunction %void
1273 %func = OpFunction %void None %voidfn
1274 %entry = OpLabel
1275 OpCopyMemory %var1 %var2 MakePointerAvailableKHR|NonPrivatePointerKHR %device
1276 OpReturn
1277 OpFunctionEnd
1278 )";
1279 
1280   CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
1281   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1282 }
1283 
TEST_F(ValidateMemory,VulkanMemoryModelDeviceScopeCopyMemoryGood2)1284 TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeCopyMemoryGood2) {
1285   const std::string spirv = R"(
1286 OpCapability Shader
1287 OpCapability VulkanMemoryModelKHR
1288 OpCapability VulkanMemoryModelDeviceScopeKHR
1289 OpCapability Linkage
1290 OpExtension "SPV_KHR_vulkan_memory_model"
1291 OpMemoryModel Logical VulkanKHR
1292 %void = OpTypeVoid
1293 %int = OpTypeInt 32 0
1294 %device = OpConstant %int 1
1295 %workgroup = OpConstant %int 2
1296 %int_ptr_ssbo = OpTypePointer StorageBuffer %int
1297 %var1 = OpVariable %int_ptr_ssbo StorageBuffer
1298 %var2 = OpVariable %int_ptr_ssbo StorageBuffer
1299 %voidfn = OpTypeFunction %void
1300 %func = OpFunction %void None %voidfn
1301 %entry = OpLabel
1302 OpCopyMemory %var1 %var2 Aligned|MakePointerVisibleKHR|MakePointerAvailableKHR|NonPrivatePointerKHR 4 %device %workgroup
1303 OpReturn
1304 OpFunctionEnd
1305 )";
1306 
1307   CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
1308   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1309 }
1310 
TEST_F(ValidateMemory,VulkanMemoryModelDeviceScopeCopyMemoryGood3)1311 TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeCopyMemoryGood3) {
1312   const std::string spirv = R"(
1313 OpCapability Shader
1314 OpCapability VulkanMemoryModelKHR
1315 OpCapability VulkanMemoryModelDeviceScopeKHR
1316 OpCapability Linkage
1317 OpExtension "SPV_KHR_vulkan_memory_model"
1318 OpMemoryModel Logical VulkanKHR
1319 %void = OpTypeVoid
1320 %int = OpTypeInt 32 0
1321 %device = OpConstant %int 1
1322 %workgroup = OpConstant %int 2
1323 %int_ptr_ssbo = OpTypePointer StorageBuffer %int
1324 %var1 = OpVariable %int_ptr_ssbo StorageBuffer
1325 %var2 = OpVariable %int_ptr_ssbo StorageBuffer
1326 %voidfn = OpTypeFunction %void
1327 %func = OpFunction %void None %voidfn
1328 %entry = OpLabel
1329 OpCopyMemory %var1 %var2 Aligned|MakePointerVisibleKHR|MakePointerAvailableKHR|NonPrivatePointerKHR 4 %workgroup %device
1330 OpReturn
1331 OpFunctionEnd
1332 )";
1333 
1334   CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
1335   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1336 }
1337 
TEST_F(ValidateMemory,VulkanMemoryModelDeviceScopeCopyMemorySizedBad1)1338 TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeCopyMemorySizedBad1) {
1339   const std::string spirv = R"(
1340 OpCapability Shader
1341 OpCapability VulkanMemoryModelKHR
1342 OpCapability Linkage
1343 OpCapability Addresses
1344 OpExtension "SPV_KHR_vulkan_memory_model"
1345 OpMemoryModel Logical VulkanKHR
1346 %void = OpTypeVoid
1347 %int = OpTypeInt 32 0
1348 %device = OpConstant %int 1
1349 %int_ptr_ssbo = OpTypePointer StorageBuffer %int
1350 %var1 = OpVariable %int_ptr_ssbo StorageBuffer
1351 %var2 = OpVariable %int_ptr_ssbo StorageBuffer
1352 %voidfn = OpTypeFunction %void
1353 %func = OpFunction %void None %voidfn
1354 %entry = OpLabel
1355 OpCopyMemorySized %var1 %var2 %device MakePointerAvailableKHR|NonPrivatePointerKHR %device
1356 OpReturn
1357 OpFunctionEnd
1358 )";
1359 
1360   CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
1361   EXPECT_EQ(SPV_ERROR_INVALID_DATA,
1362             ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1363   EXPECT_THAT(
1364       getDiagnosticString(),
1365       HasSubstr("Use of device scope with VulkanKHR memory model requires the "
1366                 "VulkanMemoryModelDeviceScopeKHR capability"));
1367 }
1368 
TEST_F(ValidateMemory,VulkanMemoryModelDeviceScopeCopyMemorySizedBad2)1369 TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeCopyMemorySizedBad2) {
1370   const std::string spirv = R"(
1371 OpCapability Shader
1372 OpCapability VulkanMemoryModelKHR
1373 OpCapability Linkage
1374 OpCapability Addresses
1375 OpExtension "SPV_KHR_vulkan_memory_model"
1376 OpMemoryModel Logical VulkanKHR
1377 %void = OpTypeVoid
1378 %int = OpTypeInt 32 0
1379 %device = OpConstant %int 1
1380 %workgroup = OpConstant %int 1
1381 %int_ptr_ssbo = OpTypePointer StorageBuffer %int
1382 %var1 = OpVariable %int_ptr_ssbo StorageBuffer
1383 %var2 = OpVariable %int_ptr_ssbo StorageBuffer
1384 %voidfn = OpTypeFunction %void
1385 %func = OpFunction %void None %voidfn
1386 %entry = OpLabel
1387 OpCopyMemorySized %var1 %var2 %device Aligned|MakePointerVisibleKHR|MakePointerAvailableKHR|NonPrivatePointerKHR 4 %device %workgroup
1388 OpReturn
1389 OpFunctionEnd
1390 )";
1391 
1392   CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
1393   EXPECT_EQ(SPV_ERROR_INVALID_DATA,
1394             ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1395   EXPECT_THAT(
1396       getDiagnosticString(),
1397       HasSubstr("Use of device scope with VulkanKHR memory model requires the "
1398                 "VulkanMemoryModelDeviceScopeKHR capability"));
1399 }
1400 
TEST_F(ValidateMemory,VulkanMemoryModelDeviceScopeCopyMemorySizedBad3)1401 TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeCopyMemorySizedBad3) {
1402   const std::string spirv = R"(
1403 OpCapability Shader
1404 OpCapability VulkanMemoryModelKHR
1405 OpCapability Linkage
1406 OpCapability Addresses
1407 OpExtension "SPV_KHR_vulkan_memory_model"
1408 OpMemoryModel Logical VulkanKHR
1409 %void = OpTypeVoid
1410 %int = OpTypeInt 32 0
1411 %device = OpConstant %int 1
1412 %workgroup = OpConstant %int 1
1413 %int_ptr_ssbo = OpTypePointer StorageBuffer %int
1414 %var1 = OpVariable %int_ptr_ssbo StorageBuffer
1415 %var2 = OpVariable %int_ptr_ssbo StorageBuffer
1416 %voidfn = OpTypeFunction %void
1417 %func = OpFunction %void None %voidfn
1418 %entry = OpLabel
1419 OpCopyMemorySized %var1 %var2 %device Aligned|MakePointerVisibleKHR|MakePointerAvailableKHR|NonPrivatePointerKHR 4 %workgroup %device
1420 OpReturn
1421 OpFunctionEnd
1422 )";
1423 
1424   CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
1425   EXPECT_EQ(SPV_ERROR_INVALID_DATA,
1426             ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1427   EXPECT_THAT(
1428       getDiagnosticString(),
1429       HasSubstr("Use of device scope with VulkanKHR memory model requires the "
1430                 "VulkanMemoryModelDeviceScopeKHR capability"));
1431 }
1432 
TEST_F(ValidateMemory,VulkanMemoryModelDeviceScopeCopyMemorySizedGood1)1433 TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeCopyMemorySizedGood1) {
1434   const std::string spirv = R"(
1435 OpCapability Shader
1436 OpCapability VulkanMemoryModelKHR
1437 OpCapability VulkanMemoryModelDeviceScopeKHR
1438 OpCapability Linkage
1439 OpCapability Addresses
1440 OpExtension "SPV_KHR_vulkan_memory_model"
1441 OpMemoryModel Logical VulkanKHR
1442 %void = OpTypeVoid
1443 %int = OpTypeInt 32 0
1444 %device = OpConstant %int 1
1445 %int_ptr_ssbo = OpTypePointer StorageBuffer %int
1446 %var1 = OpVariable %int_ptr_ssbo StorageBuffer
1447 %var2 = OpVariable %int_ptr_ssbo StorageBuffer
1448 %voidfn = OpTypeFunction %void
1449 %func = OpFunction %void None %voidfn
1450 %entry = OpLabel
1451 OpCopyMemorySized %var1 %var2 %device MakePointerAvailableKHR|NonPrivatePointerKHR %device
1452 OpReturn
1453 OpFunctionEnd
1454 )";
1455 
1456   CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
1457   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1458 }
1459 
TEST_F(ValidateMemory,VulkanMemoryModelDeviceScopeCopyMemorySizedGood2)1460 TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeCopyMemorySizedGood2) {
1461   const std::string spirv = R"(
1462 OpCapability Shader
1463 OpCapability VulkanMemoryModelKHR
1464 OpCapability VulkanMemoryModelDeviceScopeKHR
1465 OpCapability Linkage
1466 OpCapability Addresses
1467 OpExtension "SPV_KHR_vulkan_memory_model"
1468 OpMemoryModel Logical VulkanKHR
1469 %void = OpTypeVoid
1470 %int = OpTypeInt 32 0
1471 %device = OpConstant %int 1
1472 %workgroup = OpConstant %int 2
1473 %int_ptr_ssbo = OpTypePointer StorageBuffer %int
1474 %var1 = OpVariable %int_ptr_ssbo StorageBuffer
1475 %var2 = OpVariable %int_ptr_ssbo StorageBuffer
1476 %voidfn = OpTypeFunction %void
1477 %func = OpFunction %void None %voidfn
1478 %entry = OpLabel
1479 OpCopyMemorySized %var1 %var2 %device Aligned|MakePointerVisibleKHR|MakePointerAvailableKHR|NonPrivatePointerKHR 4 %device %workgroup
1480 OpReturn
1481 OpFunctionEnd
1482 )";
1483 
1484   CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
1485   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1486 }
1487 
TEST_F(ValidateMemory,VulkanMemoryModelDeviceScopeCopyMemorySizedGood3)1488 TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeCopyMemorySizedGood3) {
1489   const std::string spirv = R"(
1490 OpCapability Shader
1491 OpCapability VulkanMemoryModelKHR
1492 OpCapability VulkanMemoryModelDeviceScopeKHR
1493 OpCapability Linkage
1494 OpCapability Addresses
1495 OpExtension "SPV_KHR_vulkan_memory_model"
1496 OpMemoryModel Logical VulkanKHR
1497 %void = OpTypeVoid
1498 %int = OpTypeInt 32 0
1499 %device = OpConstant %int 1
1500 %workgroup = OpConstant %int 2
1501 %int_ptr_ssbo = OpTypePointer StorageBuffer %int
1502 %var1 = OpVariable %int_ptr_ssbo StorageBuffer
1503 %var2 = OpVariable %int_ptr_ssbo StorageBuffer
1504 %voidfn = OpTypeFunction %void
1505 %func = OpFunction %void None %voidfn
1506 %entry = OpLabel
1507 OpCopyMemorySized %var1 %var2 %device Aligned|MakePointerVisibleKHR|MakePointerAvailableKHR|NonPrivatePointerKHR 4 %workgroup %device
1508 OpReturn
1509 OpFunctionEnd
1510 )";
1511 
1512   CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
1513   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1514 }
1515 
1516 }  // namespace
1517 }  // namespace val
1518 }  // namespace spvtools
1519