Home | History | Annotate | Download | only in val
      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 
     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 
     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 
     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 
    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 
    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 
    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 // }
    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 // }
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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