1fd4e5da5Sopenharmony_ci// Copyright (c) 2018 Google Inc.
2fd4e5da5Sopenharmony_ci//
3fd4e5da5Sopenharmony_ci// Licensed under the Apache License, Version 2.0 (the "License");
4fd4e5da5Sopenharmony_ci// you may not use this file except in compliance with the License.
5fd4e5da5Sopenharmony_ci// You may obtain a copy of the License at
6fd4e5da5Sopenharmony_ci//
7fd4e5da5Sopenharmony_ci//     http://www.apache.org/licenses/LICENSE-2.0
8fd4e5da5Sopenharmony_ci//
9fd4e5da5Sopenharmony_ci// Unless required by applicable law or agreed to in writing, software
10fd4e5da5Sopenharmony_ci// distributed under the License is distributed on an "AS IS" BASIS,
11fd4e5da5Sopenharmony_ci// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12fd4e5da5Sopenharmony_ci// See the License for the specific language governing permissions and
13fd4e5da5Sopenharmony_ci// limitations under the License.
14fd4e5da5Sopenharmony_ci
15fd4e5da5Sopenharmony_ci// Validation tests for memory/storage
16fd4e5da5Sopenharmony_ci
17fd4e5da5Sopenharmony_ci#include <string>
18fd4e5da5Sopenharmony_ci#include <vector>
19fd4e5da5Sopenharmony_ci
20fd4e5da5Sopenharmony_ci#include "gmock/gmock.h"
21fd4e5da5Sopenharmony_ci#include "test/unit_spirv.h"
22fd4e5da5Sopenharmony_ci#include "test/val/val_code_generator.h"
23fd4e5da5Sopenharmony_ci#include "test/val/val_fixtures.h"
24fd4e5da5Sopenharmony_ci
25fd4e5da5Sopenharmony_ci// For pretty-printing tuples with spv_target_env.
26fd4e5da5Sopenharmony_cistd::ostream& operator<<(std::ostream& stream, spv_target_env target) {
27fd4e5da5Sopenharmony_ci  switch (target) {
28fd4e5da5Sopenharmony_ci    case SPV_ENV_UNIVERSAL_1_3:
29fd4e5da5Sopenharmony_ci      return stream << "SPV_ENV_UNIVERSAL_1_3";
30fd4e5da5Sopenharmony_ci    case SPV_ENV_UNIVERSAL_1_4:
31fd4e5da5Sopenharmony_ci      return stream << "SPV_ENV_UNIVERSAL_1_4";
32fd4e5da5Sopenharmony_ci    default:
33fd4e5da5Sopenharmony_ci      return stream << (unsigned)target;
34fd4e5da5Sopenharmony_ci  }
35fd4e5da5Sopenharmony_ci}
36fd4e5da5Sopenharmony_ci
37fd4e5da5Sopenharmony_cinamespace spvtools {
38fd4e5da5Sopenharmony_cinamespace val {
39fd4e5da5Sopenharmony_cinamespace {
40fd4e5da5Sopenharmony_ci
41fd4e5da5Sopenharmony_ciusing ::testing::Combine;
42fd4e5da5Sopenharmony_ciusing ::testing::Eq;
43fd4e5da5Sopenharmony_ciusing ::testing::HasSubstr;
44fd4e5da5Sopenharmony_ciusing ::testing::Values;
45fd4e5da5Sopenharmony_ci
46fd4e5da5Sopenharmony_ciusing ValidateMemory = spvtest::ValidateBase<bool>;
47fd4e5da5Sopenharmony_ci
48fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, VulkanUniformConstantOnNonOpaqueResourceBad) {
49fd4e5da5Sopenharmony_ci  std::string spirv = R"(
50fd4e5da5Sopenharmony_ciOpCapability Shader
51fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
52fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %func "func"
53fd4e5da5Sopenharmony_ciOpExecutionMode %func OriginUpperLeft
54fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
55fd4e5da5Sopenharmony_ci%float_ptr = OpTypePointer UniformConstant %float
56fd4e5da5Sopenharmony_ci%2 = OpVariable %float_ptr UniformConstant
57fd4e5da5Sopenharmony_ci%void = OpTypeVoid
58fd4e5da5Sopenharmony_ci%functy = OpTypeFunction %void
59fd4e5da5Sopenharmony_ci%func = OpFunction %void None %functy
60fd4e5da5Sopenharmony_ci%1 = OpLabel
61fd4e5da5Sopenharmony_ciOpReturn
62fd4e5da5Sopenharmony_ciOpFunctionEnd
63fd4e5da5Sopenharmony_ci)";
64fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
65fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
66fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
67fd4e5da5Sopenharmony_ci              AnyVUID("VUID-StandaloneSpirv-UniformConstant-04655"));
68fd4e5da5Sopenharmony_ci  EXPECT_THAT(
69fd4e5da5Sopenharmony_ci      getDiagnosticString(),
70fd4e5da5Sopenharmony_ci      HasSubstr("Variables identified with the UniformConstant storage class "
71fd4e5da5Sopenharmony_ci                "are used only as handles to refer to opaque resources. Such "
72fd4e5da5Sopenharmony_ci                "variables must be typed as OpTypeImage, OpTypeSampler, "
73fd4e5da5Sopenharmony_ci                "OpTypeSampledImage, OpTypeAccelerationStructureKHR, "
74fd4e5da5Sopenharmony_ci                "or an array of one of these types."));
75fd4e5da5Sopenharmony_ci}
76fd4e5da5Sopenharmony_ci
77fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, VulkanUniformConstantOnOpaqueResourceGood) {
78fd4e5da5Sopenharmony_ci  std::string spirv = R"(
79fd4e5da5Sopenharmony_ciOpCapability Shader
80fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
81fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %func "func"
82fd4e5da5Sopenharmony_ciOpExecutionMode %func OriginUpperLeft
83fd4e5da5Sopenharmony_ciOpDecorate %2 DescriptorSet 0
84fd4e5da5Sopenharmony_ciOpDecorate %2 Binding 0
85fd4e5da5Sopenharmony_ci%sampler = OpTypeSampler
86fd4e5da5Sopenharmony_ci%sampler_ptr = OpTypePointer UniformConstant %sampler
87fd4e5da5Sopenharmony_ci%2 = OpVariable %sampler_ptr UniformConstant
88fd4e5da5Sopenharmony_ci%void = OpTypeVoid
89fd4e5da5Sopenharmony_ci%functy = OpTypeFunction %void
90fd4e5da5Sopenharmony_ci%func = OpFunction %void None %functy
91fd4e5da5Sopenharmony_ci%1 = OpLabel
92fd4e5da5Sopenharmony_ciOpReturn
93fd4e5da5Sopenharmony_ciOpFunctionEnd
94fd4e5da5Sopenharmony_ci)";
95fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
96fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
97fd4e5da5Sopenharmony_ci}
98fd4e5da5Sopenharmony_ci
99fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, VulkanUniformConstantOnNonOpaqueResourceArrayBad) {
100fd4e5da5Sopenharmony_ci  std::string spirv = R"(
101fd4e5da5Sopenharmony_ciOpCapability Shader
102fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
103fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %func "func"
104fd4e5da5Sopenharmony_ciOpExecutionMode %func OriginUpperLeft
105fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
106fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
107fd4e5da5Sopenharmony_ci%array_size = OpConstant %uint 5
108fd4e5da5Sopenharmony_ci%array = OpTypeArray %float %array_size
109fd4e5da5Sopenharmony_ci%array_ptr = OpTypePointer UniformConstant %array
110fd4e5da5Sopenharmony_ci%2 = OpVariable %array_ptr UniformConstant
111fd4e5da5Sopenharmony_ci%void = OpTypeVoid
112fd4e5da5Sopenharmony_ci%functy = OpTypeFunction %void
113fd4e5da5Sopenharmony_ci%func = OpFunction %void None %functy
114fd4e5da5Sopenharmony_ci%1 = OpLabel
115fd4e5da5Sopenharmony_ciOpReturn
116fd4e5da5Sopenharmony_ciOpFunctionEnd
117fd4e5da5Sopenharmony_ci)";
118fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
119fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
120fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
121fd4e5da5Sopenharmony_ci              AnyVUID("VUID-StandaloneSpirv-UniformConstant-04655"));
122fd4e5da5Sopenharmony_ci  EXPECT_THAT(
123fd4e5da5Sopenharmony_ci      getDiagnosticString(),
124fd4e5da5Sopenharmony_ci      HasSubstr("Variables identified with the UniformConstant storage class "
125fd4e5da5Sopenharmony_ci                "are used only as handles to refer to opaque resources. Such "
126fd4e5da5Sopenharmony_ci                "variables must be typed as OpTypeImage, OpTypeSampler, "
127fd4e5da5Sopenharmony_ci                "OpTypeSampledImage, OpTypeAccelerationStructureKHR, "
128fd4e5da5Sopenharmony_ci                "or an array of one of these types."));
129fd4e5da5Sopenharmony_ci}
130fd4e5da5Sopenharmony_ci
131fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, VulkanUniformConstantOnOpaqueResourceArrayGood) {
132fd4e5da5Sopenharmony_ci  std::string spirv = R"(
133fd4e5da5Sopenharmony_ciOpCapability Shader
134fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
135fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %func "func"
136fd4e5da5Sopenharmony_ciOpExecutionMode %func OriginUpperLeft
137fd4e5da5Sopenharmony_ciOpDecorate %2 DescriptorSet 0
138fd4e5da5Sopenharmony_ciOpDecorate %2 Binding 0
139fd4e5da5Sopenharmony_ci%sampler = OpTypeSampler
140fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
141fd4e5da5Sopenharmony_ci%array_size = OpConstant %uint 5
142fd4e5da5Sopenharmony_ci%array = OpTypeArray %sampler %array_size
143fd4e5da5Sopenharmony_ci%array_ptr = OpTypePointer UniformConstant %array
144fd4e5da5Sopenharmony_ci%2 = OpVariable %array_ptr UniformConstant
145fd4e5da5Sopenharmony_ci%void = OpTypeVoid
146fd4e5da5Sopenharmony_ci%functy = OpTypeFunction %void
147fd4e5da5Sopenharmony_ci%func = OpFunction %void None %functy
148fd4e5da5Sopenharmony_ci%1 = OpLabel
149fd4e5da5Sopenharmony_ciOpReturn
150fd4e5da5Sopenharmony_ciOpFunctionEnd
151fd4e5da5Sopenharmony_ci)";
152fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
153fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
154fd4e5da5Sopenharmony_ci}
155fd4e5da5Sopenharmony_ci
156fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, VulkanUniformConstantOnOpaqueResourceRuntimeArrayGood) {
157fd4e5da5Sopenharmony_ci  std::string spirv = R"(
158fd4e5da5Sopenharmony_ciOpCapability RuntimeDescriptorArrayEXT
159fd4e5da5Sopenharmony_ciOpCapability Shader
160fd4e5da5Sopenharmony_ciOpExtension "SPV_EXT_descriptor_indexing"
161fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
162fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %func "func"
163fd4e5da5Sopenharmony_ciOpExecutionMode %func OriginUpperLeft
164fd4e5da5Sopenharmony_ciOpDecorate %2 DescriptorSet 0
165fd4e5da5Sopenharmony_ciOpDecorate %2 Binding 0
166fd4e5da5Sopenharmony_ci%sampler = OpTypeSampler
167fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
168fd4e5da5Sopenharmony_ci%array = OpTypeRuntimeArray %sampler
169fd4e5da5Sopenharmony_ci%array_ptr = OpTypePointer UniformConstant %array
170fd4e5da5Sopenharmony_ci%2 = OpVariable %array_ptr UniformConstant
171fd4e5da5Sopenharmony_ci%void = OpTypeVoid
172fd4e5da5Sopenharmony_ci%functy = OpTypeFunction %void
173fd4e5da5Sopenharmony_ci%func = OpFunction %void None %functy
174fd4e5da5Sopenharmony_ci%1 = OpLabel
175fd4e5da5Sopenharmony_ciOpReturn
176fd4e5da5Sopenharmony_ciOpFunctionEnd
177fd4e5da5Sopenharmony_ci)";
178fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
179fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
180fd4e5da5Sopenharmony_ci}
181fd4e5da5Sopenharmony_ci
182fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, VulkanUniformOnIntBad) {
183fd4e5da5Sopenharmony_ci  char src[] = R"(
184fd4e5da5Sopenharmony_ci            OpCapability Shader
185fd4e5da5Sopenharmony_ci            OpMemoryModel Logical GLSL450
186fd4e5da5Sopenharmony_ci            OpEntryPoint GLCompute %kernel "main"
187fd4e5da5Sopenharmony_ci            OpExecutionMode %kernel LocalSize 1 1 1
188fd4e5da5Sopenharmony_ci
189fd4e5da5Sopenharmony_ci            OpDecorate %var DescriptorSet 0
190fd4e5da5Sopenharmony_ci            OpDecorate %var Binding 0
191fd4e5da5Sopenharmony_ci
192fd4e5da5Sopenharmony_ci  %voidty = OpTypeVoid
193fd4e5da5Sopenharmony_ci%kernelty = OpTypeFunction %voidty
194fd4e5da5Sopenharmony_ci   %intty = OpTypeInt 32 0
195fd4e5da5Sopenharmony_ci   %varty = OpTypePointer Uniform %intty
196fd4e5da5Sopenharmony_ci   %value = OpConstant %intty 42
197fd4e5da5Sopenharmony_ci
198fd4e5da5Sopenharmony_ci     %var = OpVariable %varty Uniform
199fd4e5da5Sopenharmony_ci
200fd4e5da5Sopenharmony_ci  %kernel = OpFunction %voidty None %kernelty
201fd4e5da5Sopenharmony_ci   %label = OpLabel
202fd4e5da5Sopenharmony_ci            OpStore %var %value
203fd4e5da5Sopenharmony_ci            OpReturn
204fd4e5da5Sopenharmony_ci            OpFunctionEnd
205fd4e5da5Sopenharmony_ci)";
206fd4e5da5Sopenharmony_ci  CompileSuccessfully(src, SPV_ENV_VULKAN_1_1);
207fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
208fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
209fd4e5da5Sopenharmony_ci              AnyVUID("VUID-StandaloneSpirv-Uniform-06807"));
210fd4e5da5Sopenharmony_ci  EXPECT_THAT(
211fd4e5da5Sopenharmony_ci      getDiagnosticString(),
212fd4e5da5Sopenharmony_ci      HasSubstr("From Vulkan spec:\n"
213fd4e5da5Sopenharmony_ci                "Variables identified with the Uniform storage class are used "
214fd4e5da5Sopenharmony_ci                "to access transparent buffer backed resources. Such variables "
215fd4e5da5Sopenharmony_ci                "must be typed as OpTypeStruct, or an array of this type"));
216fd4e5da5Sopenharmony_ci}
217fd4e5da5Sopenharmony_ci
218fd4e5da5Sopenharmony_ci// #version 440
219fd4e5da5Sopenharmony_ci// #extension GL_EXT_nonuniform_qualifier : enable
220fd4e5da5Sopenharmony_ci// layout(binding = 1) uniform sampler2D s2d[][2];
221fd4e5da5Sopenharmony_ci// layout(location = 0) in nonuniformEXT int i;
222fd4e5da5Sopenharmony_ci// void main()
223fd4e5da5Sopenharmony_ci// {
224fd4e5da5Sopenharmony_ci//     vec4 v = texture(s2d[i][i], vec2(0.3));
225fd4e5da5Sopenharmony_ci// }
226fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, VulkanUniformOnRuntimeArrayOfArrayBad) {
227fd4e5da5Sopenharmony_ci  char src[] = R"(
228fd4e5da5Sopenharmony_ci               OpCapability Shader
229fd4e5da5Sopenharmony_ci               OpCapability ShaderNonUniformEXT
230fd4e5da5Sopenharmony_ci               OpCapability RuntimeDescriptorArrayEXT
231fd4e5da5Sopenharmony_ci               OpCapability SampledImageArrayNonUniformIndexingEXT
232fd4e5da5Sopenharmony_ci               OpExtension "SPV_EXT_descriptor_indexing"
233fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
234fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
235fd4e5da5Sopenharmony_ci               OpEntryPoint Vertex %main "main" %i
236fd4e5da5Sopenharmony_ci               OpSource GLSL 440
237fd4e5da5Sopenharmony_ci               OpSourceExtension "GL_EXT_nonuniform_qualifier"
238fd4e5da5Sopenharmony_ci               OpName %main "main"
239fd4e5da5Sopenharmony_ci               OpName %v "v"
240fd4e5da5Sopenharmony_ci               OpName %s2d "s2d"
241fd4e5da5Sopenharmony_ci               OpName %i "i"
242fd4e5da5Sopenharmony_ci               OpDecorate %s2d DescriptorSet 0
243fd4e5da5Sopenharmony_ci               OpDecorate %s2d Binding 1
244fd4e5da5Sopenharmony_ci               OpDecorate %i Location 0
245fd4e5da5Sopenharmony_ci               OpDecorate %i NonUniformEXT
246fd4e5da5Sopenharmony_ci               OpDecorate %21 NonUniformEXT
247fd4e5da5Sopenharmony_ci               OpDecorate %22 NonUniformEXT
248fd4e5da5Sopenharmony_ci               OpDecorate %25 NonUniformEXT
249fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
250fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %void
251fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
252fd4e5da5Sopenharmony_ci    %v4float = OpTypeVector %float 4
253fd4e5da5Sopenharmony_ci%_ptr_Function_v4float = OpTypePointer Function %v4float
254fd4e5da5Sopenharmony_ci         %10 = OpTypeImage %float 2D 0 0 0 1 Unknown
255fd4e5da5Sopenharmony_ci         %11 = OpTypeSampledImage %10
256fd4e5da5Sopenharmony_ci       %uint = OpTypeInt 32 0
257fd4e5da5Sopenharmony_ci     %uint_2 = OpConstant %uint 2
258fd4e5da5Sopenharmony_ci%_arr_11_uint_2 = OpTypeArray %11 %uint_2
259fd4e5da5Sopenharmony_ci%_runtimearr__arr_11_uint_2 = OpTypeRuntimeArray %_arr_11_uint_2
260fd4e5da5Sopenharmony_ci%_ptr_Uniform__runtimearr__arr_11_uint_2 = OpTypePointer Uniform %_runtimearr__arr_11_uint_2
261fd4e5da5Sopenharmony_ci        %s2d = OpVariable %_ptr_Uniform__runtimearr__arr_11_uint_2 Uniform
262fd4e5da5Sopenharmony_ci        %int = OpTypeInt 32 1
263fd4e5da5Sopenharmony_ci%_ptr_Input_int = OpTypePointer Input %int
264fd4e5da5Sopenharmony_ci          %i = OpVariable %_ptr_Input_int Input
265fd4e5da5Sopenharmony_ci%_ptr_Uniform_11 = OpTypePointer Uniform %11
266fd4e5da5Sopenharmony_ci    %v2float = OpTypeVector %float 2
267fd4e5da5Sopenharmony_ci%float_0_300000012 = OpConstant %float 0.300000012
268fd4e5da5Sopenharmony_ci         %28 = OpConstantComposite %v2float %float_0_300000012 %float_0_300000012
269fd4e5da5Sopenharmony_ci    %float_0 = OpConstant %float 0
270fd4e5da5Sopenharmony_ci       %main = OpFunction %void None %3
271fd4e5da5Sopenharmony_ci          %5 = OpLabel
272fd4e5da5Sopenharmony_ci          %v = OpVariable %_ptr_Function_v4float Function
273fd4e5da5Sopenharmony_ci         %21 = OpLoad %int %i
274fd4e5da5Sopenharmony_ci         %22 = OpLoad %int %i
275fd4e5da5Sopenharmony_ci         %24 = OpAccessChain %_ptr_Uniform_11 %s2d %21 %22
276fd4e5da5Sopenharmony_ci         %25 = OpLoad %11 %24
277fd4e5da5Sopenharmony_ci         %30 = OpImageSampleExplicitLod %v4float %25 %28 Lod %float_0
278fd4e5da5Sopenharmony_ci               OpStore %v %30
279fd4e5da5Sopenharmony_ci               OpReturn
280fd4e5da5Sopenharmony_ci               OpFunctionEnd
281fd4e5da5Sopenharmony_ci)";
282fd4e5da5Sopenharmony_ci  CompileSuccessfully(src, SPV_ENV_VULKAN_1_1);
283fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
284fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
285fd4e5da5Sopenharmony_ci              AnyVUID("VUID-StandaloneSpirv-Uniform-06807"));
286fd4e5da5Sopenharmony_ci  EXPECT_THAT(
287fd4e5da5Sopenharmony_ci      getDiagnosticString(),
288fd4e5da5Sopenharmony_ci      HasSubstr("From Vulkan spec:\n"
289fd4e5da5Sopenharmony_ci                "Variables identified with the Uniform storage class are used "
290fd4e5da5Sopenharmony_ci                "to access transparent buffer backed resources. Such variables "
291fd4e5da5Sopenharmony_ci                "must be typed as OpTypeStruct, or an array of this type"));
292fd4e5da5Sopenharmony_ci}
293fd4e5da5Sopenharmony_ci
294fd4e5da5Sopenharmony_ci// #version 440
295fd4e5da5Sopenharmony_ci// layout (set=1, binding=1) uniform sampler2D variableName[2][2];
296fd4e5da5Sopenharmony_ci// void main() {
297fd4e5da5Sopenharmony_ci// }
298fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, VulkanUniformOnArrayOfArrayBad) {
299fd4e5da5Sopenharmony_ci  char src[] = R"(
300fd4e5da5Sopenharmony_ci               OpCapability Shader
301fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
302fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
303fd4e5da5Sopenharmony_ci               OpEntryPoint Vertex %main "main"
304fd4e5da5Sopenharmony_ci               OpSource GLSL 440
305fd4e5da5Sopenharmony_ci               OpName %main "main"
306fd4e5da5Sopenharmony_ci               OpName %variableName "variableName"
307fd4e5da5Sopenharmony_ci               OpDecorate %variableName DescriptorSet 1
308fd4e5da5Sopenharmony_ci               OpDecorate %variableName Binding 1
309fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
310fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %void
311fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
312fd4e5da5Sopenharmony_ci          %7 = OpTypeImage %float 2D 0 0 0 1 Unknown
313fd4e5da5Sopenharmony_ci          %8 = OpTypeSampledImage %7
314fd4e5da5Sopenharmony_ci       %uint = OpTypeInt 32 0
315fd4e5da5Sopenharmony_ci     %uint_2 = OpConstant %uint 2
316fd4e5da5Sopenharmony_ci%_arr_8_uint_2 = OpTypeArray %8 %uint_2
317fd4e5da5Sopenharmony_ci%_arr__arr_8_uint_2_uint_2 = OpTypeArray %_arr_8_uint_2 %uint_2
318fd4e5da5Sopenharmony_ci%_ptr_Uniform__arr__arr_8_uint_2_uint_2 = OpTypePointer Uniform %_arr__arr_8_uint_2_uint_2
319fd4e5da5Sopenharmony_ci%variableName = OpVariable %_ptr_Uniform__arr__arr_8_uint_2_uint_2 Uniform
320fd4e5da5Sopenharmony_ci       %main = OpFunction %void None %3
321fd4e5da5Sopenharmony_ci          %5 = OpLabel
322fd4e5da5Sopenharmony_ci               OpReturn
323fd4e5da5Sopenharmony_ci               OpFunctionEnd
324fd4e5da5Sopenharmony_ci)";
325fd4e5da5Sopenharmony_ci  CompileSuccessfully(src, SPV_ENV_VULKAN_1_1);
326fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
327fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
328fd4e5da5Sopenharmony_ci              AnyVUID("VUID-StandaloneSpirv-Uniform-06807"));
329fd4e5da5Sopenharmony_ci  EXPECT_THAT(
330fd4e5da5Sopenharmony_ci      getDiagnosticString(),
331fd4e5da5Sopenharmony_ci      HasSubstr("From Vulkan spec:\n"
332fd4e5da5Sopenharmony_ci                "Variables identified with the Uniform storage class are used "
333fd4e5da5Sopenharmony_ci                "to access transparent buffer backed resources. Such variables "
334fd4e5da5Sopenharmony_ci                "must be typed as OpTypeStruct, or an array of this type"));
335fd4e5da5Sopenharmony_ci}
336fd4e5da5Sopenharmony_ci
337fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, MismatchingStorageClassesBad) {
338fd4e5da5Sopenharmony_ci  std::string spirv = R"(
339fd4e5da5Sopenharmony_ciOpCapability Shader
340fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
341fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %func "func"
342fd4e5da5Sopenharmony_ciOpExecutionMode %func OriginUpperLeft
343fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
344fd4e5da5Sopenharmony_ci%float_ptr = OpTypePointer Uniform %float
345fd4e5da5Sopenharmony_ci%void = OpTypeVoid
346fd4e5da5Sopenharmony_ci%functy = OpTypeFunction %void
347fd4e5da5Sopenharmony_ci%func = OpFunction %void None %functy
348fd4e5da5Sopenharmony_ci%1 = OpLabel
349fd4e5da5Sopenharmony_ci%2 = OpVariable %float_ptr Function
350fd4e5da5Sopenharmony_ciOpReturn
351fd4e5da5Sopenharmony_ciOpFunctionEnd
352fd4e5da5Sopenharmony_ci)";
353fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv.c_str());
354fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
355fd4e5da5Sopenharmony_ci  EXPECT_THAT(
356fd4e5da5Sopenharmony_ci      getDiagnosticString(),
357fd4e5da5Sopenharmony_ci      HasSubstr(
358fd4e5da5Sopenharmony_ci          "From SPIR-V spec, section 3.32.8 on OpVariable:\n"
359fd4e5da5Sopenharmony_ci          "Its Storage Class operand must be the same as the Storage Class "
360fd4e5da5Sopenharmony_ci          "operand of the result type."));
361fd4e5da5Sopenharmony_ci}
362fd4e5da5Sopenharmony_ci
363fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, MatchingStorageClassesGood) {
364fd4e5da5Sopenharmony_ci  std::string spirv = R"(
365fd4e5da5Sopenharmony_ciOpCapability Shader
366fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
367fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %func "func"
368fd4e5da5Sopenharmony_ciOpExecutionMode %func OriginUpperLeft
369fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
370fd4e5da5Sopenharmony_ci%float_ptr = OpTypePointer Function %float
371fd4e5da5Sopenharmony_ci%void = OpTypeVoid
372fd4e5da5Sopenharmony_ci%functy = OpTypeFunction %void
373fd4e5da5Sopenharmony_ci%func = OpFunction %void None %functy
374fd4e5da5Sopenharmony_ci%1 = OpLabel
375fd4e5da5Sopenharmony_ci%2 = OpVariable %float_ptr Function
376fd4e5da5Sopenharmony_ciOpReturn
377fd4e5da5Sopenharmony_ciOpFunctionEnd
378fd4e5da5Sopenharmony_ci)";
379fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv.c_str());
380fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
381fd4e5da5Sopenharmony_ci}
382fd4e5da5Sopenharmony_ci
383fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, VulkanInitializerWithOutputStorageClassesGood) {
384fd4e5da5Sopenharmony_ci  std::string spirv = R"(
385fd4e5da5Sopenharmony_ciOpCapability Shader
386fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
387fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %func "func"
388fd4e5da5Sopenharmony_ciOpExecutionMode %func OriginUpperLeft
389fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
390fd4e5da5Sopenharmony_ci%float_ptr = OpTypePointer Output %float
391fd4e5da5Sopenharmony_ci%init_val = OpConstant %float 1.0
392fd4e5da5Sopenharmony_ci%1 = OpVariable %float_ptr Output %init_val
393fd4e5da5Sopenharmony_ci%void = OpTypeVoid
394fd4e5da5Sopenharmony_ci%functy = OpTypeFunction %void
395fd4e5da5Sopenharmony_ci%func = OpFunction %void None %functy
396fd4e5da5Sopenharmony_ci%2 = OpLabel
397fd4e5da5Sopenharmony_ciOpReturn
398fd4e5da5Sopenharmony_ciOpFunctionEnd
399fd4e5da5Sopenharmony_ci)";
400fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
401fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
402fd4e5da5Sopenharmony_ci}
403fd4e5da5Sopenharmony_ci
404fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, VulkanInitializerWithFunctionStorageClassesGood) {
405fd4e5da5Sopenharmony_ci  std::string spirv = R"(
406fd4e5da5Sopenharmony_ciOpCapability Shader
407fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
408fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %func "func"
409fd4e5da5Sopenharmony_ciOpExecutionMode %func OriginUpperLeft
410fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
411fd4e5da5Sopenharmony_ci%float_ptr = OpTypePointer Function %float
412fd4e5da5Sopenharmony_ci%init_val = OpConstant %float 1.0
413fd4e5da5Sopenharmony_ci%void = OpTypeVoid
414fd4e5da5Sopenharmony_ci%functy = OpTypeFunction %void
415fd4e5da5Sopenharmony_ci%func = OpFunction %void None %functy
416fd4e5da5Sopenharmony_ci%1 = OpLabel
417fd4e5da5Sopenharmony_ci%2 = OpVariable %float_ptr Function %init_val
418fd4e5da5Sopenharmony_ciOpReturn
419fd4e5da5Sopenharmony_ciOpFunctionEnd
420fd4e5da5Sopenharmony_ci)";
421fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
422fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
423fd4e5da5Sopenharmony_ci}
424fd4e5da5Sopenharmony_ci
425fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, VulkanInitializerWithPrivateStorageClassesGood) {
426fd4e5da5Sopenharmony_ci  std::string spirv = R"(
427fd4e5da5Sopenharmony_ciOpCapability Shader
428fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
429fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %func "func"
430fd4e5da5Sopenharmony_ciOpExecutionMode %func OriginUpperLeft
431fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
432fd4e5da5Sopenharmony_ci%float_ptr = OpTypePointer Private %float
433fd4e5da5Sopenharmony_ci%init_val = OpConstant %float 1.0
434fd4e5da5Sopenharmony_ci%1 = OpVariable %float_ptr Private %init_val
435fd4e5da5Sopenharmony_ci%void = OpTypeVoid
436fd4e5da5Sopenharmony_ci%functy = OpTypeFunction %void
437fd4e5da5Sopenharmony_ci%func = OpFunction %void None %functy
438fd4e5da5Sopenharmony_ci%2 = OpLabel
439fd4e5da5Sopenharmony_ciOpReturn
440fd4e5da5Sopenharmony_ciOpFunctionEnd
441fd4e5da5Sopenharmony_ci)";
442fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
443fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
444fd4e5da5Sopenharmony_ci}
445fd4e5da5Sopenharmony_ci
446fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, VulkanInitializerWithDisallowedStorageClassesBad) {
447fd4e5da5Sopenharmony_ci  std::string spirv = R"(
448fd4e5da5Sopenharmony_ciOpCapability Shader
449fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
450fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %func "func"
451fd4e5da5Sopenharmony_ciOpExecutionMode %func OriginUpperLeft
452fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
453fd4e5da5Sopenharmony_ci%float_ptr = OpTypePointer Input %float
454fd4e5da5Sopenharmony_ci%init_val = OpConstant %float 1.0
455fd4e5da5Sopenharmony_ci%1 = OpVariable %float_ptr Input %init_val
456fd4e5da5Sopenharmony_ci%void = OpTypeVoid
457fd4e5da5Sopenharmony_ci%functy = OpTypeFunction %void
458fd4e5da5Sopenharmony_ci%func = OpFunction %void None %functy
459fd4e5da5Sopenharmony_ci%2 = OpLabel
460fd4e5da5Sopenharmony_ciOpReturn
461fd4e5da5Sopenharmony_ciOpFunctionEnd
462fd4e5da5Sopenharmony_ci)";
463fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
464fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
465fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
466fd4e5da5Sopenharmony_ci              AnyVUID("VUID-StandaloneSpirv-OpVariable-04651"));
467fd4e5da5Sopenharmony_ci  EXPECT_THAT(
468fd4e5da5Sopenharmony_ci      getDiagnosticString(),
469fd4e5da5Sopenharmony_ci      HasSubstr("OpVariable, <id> '5[%5]', has a disallowed initializer & "
470fd4e5da5Sopenharmony_ci                "storage class combination.\nFrom Vulkan spec:\nVariable "
471fd4e5da5Sopenharmony_ci                "declarations that include initializers must have one of the "
472fd4e5da5Sopenharmony_ci                "following storage classes: Output, Private, Function or "
473fd4e5da5Sopenharmony_ci                "Workgroup\n  %5 "
474fd4e5da5Sopenharmony_ci                "= OpVariable %_ptr_Input_float Input %float_1\n"));
475fd4e5da5Sopenharmony_ci}
476fd4e5da5Sopenharmony_ci
477fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, UniversalInitializerWithDisallowedStorageClassesBad) {
478fd4e5da5Sopenharmony_ci  std::string spirv = R"(
479fd4e5da5Sopenharmony_ciOpCapability Shader
480fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
481fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %func "func"
482fd4e5da5Sopenharmony_ciOpExecutionMode %func OriginUpperLeft
483fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
484fd4e5da5Sopenharmony_ci%float_ptr = OpTypePointer Input %float
485fd4e5da5Sopenharmony_ci%init_val = OpConstant %float 1.0
486fd4e5da5Sopenharmony_ci%1 = OpVariable %float_ptr Input %init_val
487fd4e5da5Sopenharmony_ci%void = OpTypeVoid
488fd4e5da5Sopenharmony_ci%functy = OpTypeFunction %void
489fd4e5da5Sopenharmony_ci%func = OpFunction %void None %functy
490fd4e5da5Sopenharmony_ci%2 = OpLabel
491fd4e5da5Sopenharmony_ciOpReturn
492fd4e5da5Sopenharmony_ciOpFunctionEnd
493fd4e5da5Sopenharmony_ci)";
494fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv.c_str(), SPV_ENV_UNIVERSAL_1_3);
495fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
496fd4e5da5Sopenharmony_ci  EXPECT_THAT(
497fd4e5da5Sopenharmony_ci      getDiagnosticString(),
498fd4e5da5Sopenharmony_ci      HasSubstr(
499fd4e5da5Sopenharmony_ci          "OpVariable, <id> '5[%5]', initializer are not allowed for Input"));
500fd4e5da5Sopenharmony_ci}
501fd4e5da5Sopenharmony_ci
502fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, InitializerWithTaskPayloadWorkgroupEXT) {
503fd4e5da5Sopenharmony_ci  std::string spirv = R"(
504fd4e5da5Sopenharmony_ci               OpCapability MeshShadingEXT
505fd4e5da5Sopenharmony_ci               OpExtension "SPV_EXT_mesh_shader"
506fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
507fd4e5da5Sopenharmony_ci               OpEntryPoint TaskEXT %main "main" %payload
508fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
509fd4e5da5Sopenharmony_ci       %func = OpTypeFunction %void
510fd4e5da5Sopenharmony_ci       %uint = OpTypeInt 32 0
511fd4e5da5Sopenharmony_ci%_ptr_TaskPayloadWorkgroupEXT = OpTypePointer TaskPayloadWorkgroupEXT %uint
512fd4e5da5Sopenharmony_ci     %uint_1 = OpConstant %uint 1
513fd4e5da5Sopenharmony_ci    %payload = OpVariable %_ptr_TaskPayloadWorkgroupEXT TaskPayloadWorkgroupEXT %uint_1
514fd4e5da5Sopenharmony_ci       %main = OpFunction %void None %func
515fd4e5da5Sopenharmony_ci      %label = OpLabel
516fd4e5da5Sopenharmony_ci               OpReturn
517fd4e5da5Sopenharmony_ci               OpFunctionEnd
518fd4e5da5Sopenharmony_ci)";
519fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv.c_str(), SPV_ENV_UNIVERSAL_1_5);
520fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
521fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
522fd4e5da5Sopenharmony_ci              HasSubstr("OpVariable, <id> '2[%2]', initializer are not allowed "
523fd4e5da5Sopenharmony_ci                        "for TaskPayloadWorkgroupEXT"));
524fd4e5da5Sopenharmony_ci}
525fd4e5da5Sopenharmony_ci
526fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, ArrayLenCorrectResultType) {
527fd4e5da5Sopenharmony_ci  std::string spirv = R"(
528fd4e5da5Sopenharmony_ci               OpCapability Shader
529fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
530fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %1 "main"
531fd4e5da5Sopenharmony_ci               OpExecutionMode %1 OriginUpperLeft
532fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
533fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %void
534fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
535fd4e5da5Sopenharmony_ci     %uint = OpTypeInt 32 0
536fd4e5da5Sopenharmony_ci%_runtimearr_float = OpTypeRuntimeArray %float
537fd4e5da5Sopenharmony_ci  %_struct_7 = OpTypeStruct %_runtimearr_float
538fd4e5da5Sopenharmony_ci%_ptr_Function__struct_7 = OpTypePointer Function %_struct_7
539fd4e5da5Sopenharmony_ci          %1 = OpFunction %void None %3
540fd4e5da5Sopenharmony_ci          %9 = OpLabel
541fd4e5da5Sopenharmony_ci         %10 = OpVariable %_ptr_Function__struct_7 Function
542fd4e5da5Sopenharmony_ci         %11 = OpArrayLength %uint %10 0
543fd4e5da5Sopenharmony_ci               OpReturn
544fd4e5da5Sopenharmony_ci               OpFunctionEnd
545fd4e5da5Sopenharmony_ci
546fd4e5da5Sopenharmony_ci)";
547fd4e5da5Sopenharmony_ci
548fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv.c_str());
549fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
550fd4e5da5Sopenharmony_ci}
551fd4e5da5Sopenharmony_ci
552fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, ArrayLenIndexCorrectWith2Members) {
553fd4e5da5Sopenharmony_ci  std::string spirv = R"(
554fd4e5da5Sopenharmony_ci               OpCapability Shader
555fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
556fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %1 "main"
557fd4e5da5Sopenharmony_ci               OpExecutionMode %1 OriginUpperLeft
558fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
559fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %void
560fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
561fd4e5da5Sopenharmony_ci     %uint = OpTypeInt 32 0
562fd4e5da5Sopenharmony_ci%_runtimearr_float = OpTypeRuntimeArray %float
563fd4e5da5Sopenharmony_ci  %_struct_7 = OpTypeStruct %float %_runtimearr_float
564fd4e5da5Sopenharmony_ci%_ptr_Function__struct_7  = OpTypePointer Function %_struct_7
565fd4e5da5Sopenharmony_ci          %1 = OpFunction %void None %3
566fd4e5da5Sopenharmony_ci          %9 = OpLabel
567fd4e5da5Sopenharmony_ci         %10 = OpVariable %_ptr_Function__struct_7  Function
568fd4e5da5Sopenharmony_ci         %11 = OpArrayLength %uint %10 1
569fd4e5da5Sopenharmony_ci               OpReturn
570fd4e5da5Sopenharmony_ci               OpFunctionEnd
571fd4e5da5Sopenharmony_ci
572fd4e5da5Sopenharmony_ci)";
573fd4e5da5Sopenharmony_ci
574fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv.c_str());
575fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
576fd4e5da5Sopenharmony_ci}
577fd4e5da5Sopenharmony_ci
578fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, ArrayLenResultNotIntType) {
579fd4e5da5Sopenharmony_ci  std::string spirv = R"(
580fd4e5da5Sopenharmony_ci               OpCapability Shader
581fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
582fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %1 "main"
583fd4e5da5Sopenharmony_ci               OpExecutionMode %1 OriginUpperLeft
584fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
585fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %void
586fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
587fd4e5da5Sopenharmony_ci%_runtimearr_float = OpTypeRuntimeArray %float
588fd4e5da5Sopenharmony_ci  %_struct_6 = OpTypeStruct %_runtimearr_float
589fd4e5da5Sopenharmony_ci%_ptr_Function__struct_6 = OpTypePointer Function %_struct_6
590fd4e5da5Sopenharmony_ci          %1 = OpFunction %void None %3
591fd4e5da5Sopenharmony_ci          %8 = OpLabel
592fd4e5da5Sopenharmony_ci          %9 = OpVariable %_ptr_Function__struct_6 Function
593fd4e5da5Sopenharmony_ci         %10 = OpArrayLength %float %9 0
594fd4e5da5Sopenharmony_ci               OpReturn
595fd4e5da5Sopenharmony_ci               OpFunctionEnd
596fd4e5da5Sopenharmony_ci)";
597fd4e5da5Sopenharmony_ci
598fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv.c_str());
599fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
600fd4e5da5Sopenharmony_ci  EXPECT_THAT(
601fd4e5da5Sopenharmony_ci      getDiagnosticString(),
602fd4e5da5Sopenharmony_ci      HasSubstr(
603fd4e5da5Sopenharmony_ci          "The Result Type of OpArrayLength <id> '10[%10]' must be OpTypeInt "
604fd4e5da5Sopenharmony_ci          "with width 32 and signedness 0.\n  %10 = OpArrayLength %float %9 "
605fd4e5da5Sopenharmony_ci          "0\n"));
606fd4e5da5Sopenharmony_ci}
607fd4e5da5Sopenharmony_ci
608fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, ArrayLenResultNot32bits) {
609fd4e5da5Sopenharmony_ci  std::string spirv = R"(
610fd4e5da5Sopenharmony_ci               OpCapability Shader
611fd4e5da5Sopenharmony_ci               OpCapability Int16
612fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
613fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %1 "main"
614fd4e5da5Sopenharmony_ci               OpExecutionMode %1 OriginUpperLeft
615fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
616fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %void
617fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
618fd4e5da5Sopenharmony_ci     %ushort = OpTypeInt 16 0
619fd4e5da5Sopenharmony_ci%_runtimearr_float = OpTypeRuntimeArray %float
620fd4e5da5Sopenharmony_ci  %_struct_7 = OpTypeStruct %_runtimearr_float
621fd4e5da5Sopenharmony_ci%_ptr_Function__struct_7 = OpTypePointer Function %_struct_7
622fd4e5da5Sopenharmony_ci          %1 = OpFunction %void None %3
623fd4e5da5Sopenharmony_ci          %9 = OpLabel
624fd4e5da5Sopenharmony_ci         %10 = OpVariable %_ptr_Function__struct_7 Function
625fd4e5da5Sopenharmony_ci         %11 = OpArrayLength %ushort %10 0
626fd4e5da5Sopenharmony_ci               OpReturn
627fd4e5da5Sopenharmony_ci               OpFunctionEnd
628fd4e5da5Sopenharmony_ci
629fd4e5da5Sopenharmony_ci)";
630fd4e5da5Sopenharmony_ci
631fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv.c_str());
632fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
633fd4e5da5Sopenharmony_ci  EXPECT_THAT(
634fd4e5da5Sopenharmony_ci      getDiagnosticString(),
635fd4e5da5Sopenharmony_ci      HasSubstr(
636fd4e5da5Sopenharmony_ci          "The Result Type of OpArrayLength <id> '11[%11]' must be OpTypeInt "
637fd4e5da5Sopenharmony_ci          "with width 32 and signedness 0.\n  %11 = OpArrayLength %ushort %10 "
638fd4e5da5Sopenharmony_ci          "0\n"));
639fd4e5da5Sopenharmony_ci}
640fd4e5da5Sopenharmony_ci
641fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, ArrayLenResultSigned) {
642fd4e5da5Sopenharmony_ci  std::string spirv = R"(
643fd4e5da5Sopenharmony_ci               OpCapability Shader
644fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
645fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %1 "main"
646fd4e5da5Sopenharmony_ci               OpExecutionMode %1 OriginUpperLeft
647fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
648fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %void
649fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
650fd4e5da5Sopenharmony_ci     %int = OpTypeInt 32 1
651fd4e5da5Sopenharmony_ci%_runtimearr_float = OpTypeRuntimeArray %float
652fd4e5da5Sopenharmony_ci  %_struct_7 = OpTypeStruct %_runtimearr_float
653fd4e5da5Sopenharmony_ci%_ptr_Function__struct_7 = OpTypePointer Function %_struct_7
654fd4e5da5Sopenharmony_ci          %1 = OpFunction %void None %3
655fd4e5da5Sopenharmony_ci          %9 = OpLabel
656fd4e5da5Sopenharmony_ci         %10 = OpVariable %_ptr_Function__struct_7 Function
657fd4e5da5Sopenharmony_ci         %11 = OpArrayLength %int %10 0
658fd4e5da5Sopenharmony_ci               OpReturn
659fd4e5da5Sopenharmony_ci               OpFunctionEnd
660fd4e5da5Sopenharmony_ci
661fd4e5da5Sopenharmony_ci)";
662fd4e5da5Sopenharmony_ci
663fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv.c_str());
664fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
665fd4e5da5Sopenharmony_ci  EXPECT_THAT(
666fd4e5da5Sopenharmony_ci      getDiagnosticString(),
667fd4e5da5Sopenharmony_ci      HasSubstr(
668fd4e5da5Sopenharmony_ci          "The Result Type of OpArrayLength <id> '11[%11]' must be OpTypeInt "
669fd4e5da5Sopenharmony_ci          "with width 32 and signedness 0.\n  %11 = OpArrayLength %int %10 "
670fd4e5da5Sopenharmony_ci          "0\n"));
671fd4e5da5Sopenharmony_ci}
672fd4e5da5Sopenharmony_ci
673fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, ArrayLenInputNotStruct) {
674fd4e5da5Sopenharmony_ci  std::string spirv = R"(
675fd4e5da5Sopenharmony_ci               OpCapability Shader
676fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
677fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %1 "main"
678fd4e5da5Sopenharmony_ci               OpExecutionMode %1 OriginUpperLeft
679fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
680fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %void
681fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
682fd4e5da5Sopenharmony_ci     %uint = OpTypeInt 32 0
683fd4e5da5Sopenharmony_ci%_runtimearr_float = OpTypeRuntimeArray %float
684fd4e5da5Sopenharmony_ci  %_struct_7 = OpTypeStruct %_runtimearr_float
685fd4e5da5Sopenharmony_ci%_ptr_Function_float = OpTypePointer Function %float
686fd4e5da5Sopenharmony_ci          %1 = OpFunction %void None %3
687fd4e5da5Sopenharmony_ci          %9 = OpLabel
688fd4e5da5Sopenharmony_ci         %10 = OpVariable %_ptr_Function_float Function
689fd4e5da5Sopenharmony_ci         %11 = OpArrayLength %uint %10 0
690fd4e5da5Sopenharmony_ci               OpReturn
691fd4e5da5Sopenharmony_ci               OpFunctionEnd
692fd4e5da5Sopenharmony_ci
693fd4e5da5Sopenharmony_ci)";
694fd4e5da5Sopenharmony_ci
695fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv.c_str());
696fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
697fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
698fd4e5da5Sopenharmony_ci              HasSubstr("The Structure's type in OpArrayLength <id> '11[%11]' "
699fd4e5da5Sopenharmony_ci                        "must be a pointer to an OpTypeStruct."));
700fd4e5da5Sopenharmony_ci}
701fd4e5da5Sopenharmony_ci
702fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, ArrayLenInputLastMemberNoRTA) {
703fd4e5da5Sopenharmony_ci  std::string spirv = R"(
704fd4e5da5Sopenharmony_ci               OpCapability Shader
705fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
706fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %1 "main"
707fd4e5da5Sopenharmony_ci               OpExecutionMode %1 OriginUpperLeft
708fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
709fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %void
710fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
711fd4e5da5Sopenharmony_ci     %uint = OpTypeInt 32 0
712fd4e5da5Sopenharmony_ci%_runtimearr_float = OpTypeRuntimeArray %float
713fd4e5da5Sopenharmony_ci  %_struct_7 = OpTypeStruct %float
714fd4e5da5Sopenharmony_ci%_ptr_Function__struct_7  = OpTypePointer Function %_struct_7
715fd4e5da5Sopenharmony_ci          %1 = OpFunction %void None %3
716fd4e5da5Sopenharmony_ci          %9 = OpLabel
717fd4e5da5Sopenharmony_ci         %10 = OpVariable %_ptr_Function__struct_7  Function
718fd4e5da5Sopenharmony_ci         %11 = OpArrayLength %uint %10 0
719fd4e5da5Sopenharmony_ci               OpReturn
720fd4e5da5Sopenharmony_ci               OpFunctionEnd
721fd4e5da5Sopenharmony_ci
722fd4e5da5Sopenharmony_ci)";
723fd4e5da5Sopenharmony_ci
724fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv.c_str());
725fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
726fd4e5da5Sopenharmony_ci  EXPECT_THAT(
727fd4e5da5Sopenharmony_ci      getDiagnosticString(),
728fd4e5da5Sopenharmony_ci      HasSubstr("The Structure's last member in OpArrayLength <id> '11[%11]' "
729fd4e5da5Sopenharmony_ci                "must be an OpTypeRuntimeArray.\n  %11 = OpArrayLength %uint "
730fd4e5da5Sopenharmony_ci                "%10 0\n"));
731fd4e5da5Sopenharmony_ci}
732fd4e5da5Sopenharmony_ci
733fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, ArrayLenInputLastMemberNoRTA2) {
734fd4e5da5Sopenharmony_ci  std::string spirv = R"(
735fd4e5da5Sopenharmony_ci               OpCapability Shader
736fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
737fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %1 "main"
738fd4e5da5Sopenharmony_ci               OpExecutionMode %1 OriginUpperLeft
739fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
740fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %void
741fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
742fd4e5da5Sopenharmony_ci     %uint = OpTypeInt 32 0
743fd4e5da5Sopenharmony_ci%_runtimearr_float = OpTypeRuntimeArray %float
744fd4e5da5Sopenharmony_ci  %_struct_7 = OpTypeStruct %_runtimearr_float %float
745fd4e5da5Sopenharmony_ci%_ptr_Function__struct_7  = OpTypePointer Function %_struct_7
746fd4e5da5Sopenharmony_ci          %1 = OpFunction %void None %3
747fd4e5da5Sopenharmony_ci          %9 = OpLabel
748fd4e5da5Sopenharmony_ci         %10 = OpVariable %_ptr_Function__struct_7  Function
749fd4e5da5Sopenharmony_ci         %11 = OpArrayLength %uint %10 1
750fd4e5da5Sopenharmony_ci               OpReturn
751fd4e5da5Sopenharmony_ci               OpFunctionEnd
752fd4e5da5Sopenharmony_ci
753fd4e5da5Sopenharmony_ci)";
754fd4e5da5Sopenharmony_ci
755fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv.c_str());
756fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
757fd4e5da5Sopenharmony_ci  EXPECT_THAT(
758fd4e5da5Sopenharmony_ci      getDiagnosticString(),
759fd4e5da5Sopenharmony_ci      HasSubstr("The Structure's last member in OpArrayLength <id> '11[%11]' "
760fd4e5da5Sopenharmony_ci                "must be an OpTypeRuntimeArray.\n  %11 = OpArrayLength %uint "
761fd4e5da5Sopenharmony_ci                "%10 1\n"));
762fd4e5da5Sopenharmony_ci}
763fd4e5da5Sopenharmony_ci
764fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, ArrayLenIndexNotLastMember) {
765fd4e5da5Sopenharmony_ci  std::string spirv = R"(
766fd4e5da5Sopenharmony_ci               OpCapability Shader
767fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
768fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %1 "main"
769fd4e5da5Sopenharmony_ci               OpExecutionMode %1 OriginUpperLeft
770fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
771fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %void
772fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
773fd4e5da5Sopenharmony_ci     %uint = OpTypeInt 32 0
774fd4e5da5Sopenharmony_ci%_runtimearr_float = OpTypeRuntimeArray %float
775fd4e5da5Sopenharmony_ci  %_struct_7 = OpTypeStruct %float %_runtimearr_float
776fd4e5da5Sopenharmony_ci%_ptr_Function__struct_7  = OpTypePointer Function %_struct_7
777fd4e5da5Sopenharmony_ci          %1 = OpFunction %void None %3
778fd4e5da5Sopenharmony_ci          %9 = OpLabel
779fd4e5da5Sopenharmony_ci         %10 = OpVariable %_ptr_Function__struct_7  Function
780fd4e5da5Sopenharmony_ci         %11 = OpArrayLength %uint %10 0
781fd4e5da5Sopenharmony_ci               OpReturn
782fd4e5da5Sopenharmony_ci               OpFunctionEnd
783fd4e5da5Sopenharmony_ci
784fd4e5da5Sopenharmony_ci)";
785fd4e5da5Sopenharmony_ci
786fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv.c_str());
787fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
788fd4e5da5Sopenharmony_ci  EXPECT_THAT(
789fd4e5da5Sopenharmony_ci      getDiagnosticString(),
790fd4e5da5Sopenharmony_ci      HasSubstr(
791fd4e5da5Sopenharmony_ci          "The array member in OpArrayLength <id> '11[%11]' must be an the "
792fd4e5da5Sopenharmony_ci          "last member of the struct.\n  %11 = OpArrayLength %uint %10 0\n"));
793fd4e5da5Sopenharmony_ci}
794fd4e5da5Sopenharmony_ci
795fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, ArrayLenIndexNotPointerToStruct) {
796fd4e5da5Sopenharmony_ci  std::string spirv = R"(
797fd4e5da5Sopenharmony_ci               OpCapability Shader
798fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
799fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %1 "main"
800fd4e5da5Sopenharmony_ci               OpExecutionMode %1 OriginUpperLeft
801fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
802fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %void
803fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
804fd4e5da5Sopenharmony_ci     %uint = OpTypeInt 32 0
805fd4e5da5Sopenharmony_ci%_runtimearr_float = OpTypeRuntimeArray %float
806fd4e5da5Sopenharmony_ci  %_struct_7 = OpTypeStruct %float
807fd4e5da5Sopenharmony_ci%_ptr_Function__struct_7  = OpTypePointer Function %_struct_7
808fd4e5da5Sopenharmony_ci          %1 = OpFunction %void None %3
809fd4e5da5Sopenharmony_ci          %9 = OpLabel
810fd4e5da5Sopenharmony_ci         %10 = OpVariable %_ptr_Function__struct_7  Function
811fd4e5da5Sopenharmony_ci         %11 = OpLoad %_struct_7 %10
812fd4e5da5Sopenharmony_ci         %12 = OpArrayLength %uint %11 0
813fd4e5da5Sopenharmony_ci               OpReturn
814fd4e5da5Sopenharmony_ci               OpFunctionEnd
815fd4e5da5Sopenharmony_ci
816fd4e5da5Sopenharmony_ci)";
817fd4e5da5Sopenharmony_ci
818fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv.c_str());
819fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
820fd4e5da5Sopenharmony_ci  EXPECT_THAT(
821fd4e5da5Sopenharmony_ci      getDiagnosticString(),
822fd4e5da5Sopenharmony_ci      HasSubstr(
823fd4e5da5Sopenharmony_ci          "The Structure's type in OpArrayLength <id> '12[%12]' must be a "
824fd4e5da5Sopenharmony_ci          "pointer to an OpTypeStruct.\n  %12 = OpArrayLength %uint %11 0\n"));
825fd4e5da5Sopenharmony_ci}
826fd4e5da5Sopenharmony_ci
827fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, ArrayLenPointerIsAType) {
828fd4e5da5Sopenharmony_ci  std::string spirv = R"(
829fd4e5da5Sopenharmony_ci               OpCapability Shader
830fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
831fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %1 "main"
832fd4e5da5Sopenharmony_ci               OpExecutionMode %1 OriginUpperLeft
833fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
834fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %void
835fd4e5da5Sopenharmony_ci      %float = OpTypeFloat 32
836fd4e5da5Sopenharmony_ci       %uint = OpTypeInt 32 0
837fd4e5da5Sopenharmony_ci          %1 = OpFunction %void None %3
838fd4e5da5Sopenharmony_ci          %9 = OpLabel
839fd4e5da5Sopenharmony_ci         %12 = OpArrayLength %uint %float 0
840fd4e5da5Sopenharmony_ci               OpReturn
841fd4e5da5Sopenharmony_ci               OpFunctionEnd
842fd4e5da5Sopenharmony_ci
843fd4e5da5Sopenharmony_ci)";
844fd4e5da5Sopenharmony_ci
845fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv.c_str());
846fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
847fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
848fd4e5da5Sopenharmony_ci              HasSubstr("Operand '4[%float]' cannot be a "
849fd4e5da5Sopenharmony_ci                        "type"));
850fd4e5da5Sopenharmony_ci}
851fd4e5da5Sopenharmony_ci
852fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, PushConstantNotStructGood) {
853fd4e5da5Sopenharmony_ci  std::string spirv = R"(
854fd4e5da5Sopenharmony_ci            OpCapability Shader
855fd4e5da5Sopenharmony_ci            OpMemoryModel Logical GLSL450
856fd4e5da5Sopenharmony_ci            OpEntryPoint Fragment %1 "main"
857fd4e5da5Sopenharmony_ci            OpExecutionMode %1 OriginUpperLeft
858fd4e5da5Sopenharmony_ci
859fd4e5da5Sopenharmony_ci    %void = OpTypeVoid
860fd4e5da5Sopenharmony_ci  %voidfn = OpTypeFunction %void
861fd4e5da5Sopenharmony_ci   %float = OpTypeFloat 32
862fd4e5da5Sopenharmony_ci     %ptr = OpTypePointer PushConstant %float
863fd4e5da5Sopenharmony_ci      %pc = OpVariable %ptr PushConstant
864fd4e5da5Sopenharmony_ci
865fd4e5da5Sopenharmony_ci       %1 = OpFunction %void None %voidfn
866fd4e5da5Sopenharmony_ci   %label = OpLabel
867fd4e5da5Sopenharmony_ci            OpReturn
868fd4e5da5Sopenharmony_ci            OpFunctionEnd
869fd4e5da5Sopenharmony_ci)";
870fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv);
871fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
872fd4e5da5Sopenharmony_ci}
873fd4e5da5Sopenharmony_ci
874fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, VulkanPushConstantNotStructBad) {
875fd4e5da5Sopenharmony_ci  std::string spirv = R"(
876fd4e5da5Sopenharmony_ci            OpCapability Shader
877fd4e5da5Sopenharmony_ci            OpMemoryModel Logical GLSL450
878fd4e5da5Sopenharmony_ci            OpEntryPoint Fragment %1 "main"
879fd4e5da5Sopenharmony_ci            OpExecutionMode %1 OriginUpperLeft
880fd4e5da5Sopenharmony_ci
881fd4e5da5Sopenharmony_ci    %void = OpTypeVoid
882fd4e5da5Sopenharmony_ci  %voidfn = OpTypeFunction %void
883fd4e5da5Sopenharmony_ci   %float = OpTypeFloat 32
884fd4e5da5Sopenharmony_ci     %ptr = OpTypePointer PushConstant %float
885fd4e5da5Sopenharmony_ci      %pc = OpVariable %ptr PushConstant
886fd4e5da5Sopenharmony_ci
887fd4e5da5Sopenharmony_ci       %1 = OpFunction %void None %voidfn
888fd4e5da5Sopenharmony_ci   %label = OpLabel
889fd4e5da5Sopenharmony_ci            OpReturn
890fd4e5da5Sopenharmony_ci            OpFunctionEnd
891fd4e5da5Sopenharmony_ci)";
892fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
893fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
894fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
895fd4e5da5Sopenharmony_ci              AnyVUID("VUID-StandaloneSpirv-PushConstant-06808"));
896fd4e5da5Sopenharmony_ci  EXPECT_THAT(
897fd4e5da5Sopenharmony_ci      getDiagnosticString(),
898fd4e5da5Sopenharmony_ci      HasSubstr("PushConstant OpVariable <id> '6[%6]' has illegal "
899fd4e5da5Sopenharmony_ci                "type.\nFrom Vulkan spec, Push Constant Interface section:\n"
900fd4e5da5Sopenharmony_ci                "Such variables must be typed as OpTypeStruct"));
901fd4e5da5Sopenharmony_ci}
902fd4e5da5Sopenharmony_ci
903fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, VulkanPushConstantArrayOfStructBad) {
904fd4e5da5Sopenharmony_ci  std::string spirv = R"(
905fd4e5da5Sopenharmony_ci            OpCapability Shader
906fd4e5da5Sopenharmony_ci            OpMemoryModel Logical GLSL450
907fd4e5da5Sopenharmony_ci            OpEntryPoint Fragment %1 "main"
908fd4e5da5Sopenharmony_ci            OpExecutionMode %1 OriginUpperLeft
909fd4e5da5Sopenharmony_ci
910fd4e5da5Sopenharmony_ci            OpDecorate %struct Block
911fd4e5da5Sopenharmony_ci            OpMemberDecorate %struct 0 Offset 0
912fd4e5da5Sopenharmony_ci
913fd4e5da5Sopenharmony_ci    %void = OpTypeVoid
914fd4e5da5Sopenharmony_ci  %voidfn = OpTypeFunction %void
915fd4e5da5Sopenharmony_ci   %float = OpTypeFloat 32
916fd4e5da5Sopenharmony_ci     %int = OpTypeInt 32 0
917fd4e5da5Sopenharmony_ci   %int_1 = OpConstant %int 1
918fd4e5da5Sopenharmony_ci  %struct = OpTypeStruct %float
919fd4e5da5Sopenharmony_ci   %array = OpTypeArray %struct %int_1
920fd4e5da5Sopenharmony_ci     %ptr = OpTypePointer PushConstant %array
921fd4e5da5Sopenharmony_ci      %pc = OpVariable %ptr PushConstant
922fd4e5da5Sopenharmony_ci
923fd4e5da5Sopenharmony_ci       %1 = OpFunction %void None %voidfn
924fd4e5da5Sopenharmony_ci   %label = OpLabel
925fd4e5da5Sopenharmony_ci            OpReturn
926fd4e5da5Sopenharmony_ci            OpFunctionEnd
927fd4e5da5Sopenharmony_ci)";
928fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
929fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
930fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
931fd4e5da5Sopenharmony_ci              AnyVUID("VUID-StandaloneSpirv-PushConstant-06808"));
932fd4e5da5Sopenharmony_ci  EXPECT_THAT(
933fd4e5da5Sopenharmony_ci      getDiagnosticString(),
934fd4e5da5Sopenharmony_ci      HasSubstr("PushConstant OpVariable <id> '10[%10]' has illegal "
935fd4e5da5Sopenharmony_ci                "type.\nFrom Vulkan spec, Push Constant Interface section:\n"
936fd4e5da5Sopenharmony_ci                "Such variables must be typed as OpTypeStruct"));
937fd4e5da5Sopenharmony_ci}
938fd4e5da5Sopenharmony_ci
939fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, VulkanPushConstant) {
940fd4e5da5Sopenharmony_ci  std::string spirv = R"(
941fd4e5da5Sopenharmony_ci            OpCapability Shader
942fd4e5da5Sopenharmony_ci            OpMemoryModel Logical GLSL450
943fd4e5da5Sopenharmony_ci            OpEntryPoint Fragment %1 "main"
944fd4e5da5Sopenharmony_ci            OpExecutionMode %1 OriginUpperLeft
945fd4e5da5Sopenharmony_ci
946fd4e5da5Sopenharmony_ci            OpDecorate %struct Block
947fd4e5da5Sopenharmony_ci            OpMemberDecorate %struct 0 Offset 0
948fd4e5da5Sopenharmony_ci
949fd4e5da5Sopenharmony_ci    %void = OpTypeVoid
950fd4e5da5Sopenharmony_ci  %voidfn = OpTypeFunction %void
951fd4e5da5Sopenharmony_ci   %float = OpTypeFloat 32
952fd4e5da5Sopenharmony_ci  %struct = OpTypeStruct %float
953fd4e5da5Sopenharmony_ci     %ptr = OpTypePointer PushConstant %struct
954fd4e5da5Sopenharmony_ci      %pc = OpVariable %ptr PushConstant
955fd4e5da5Sopenharmony_ci
956fd4e5da5Sopenharmony_ci       %1 = OpFunction %void None %voidfn
957fd4e5da5Sopenharmony_ci   %label = OpLabel
958fd4e5da5Sopenharmony_ci            OpReturn
959fd4e5da5Sopenharmony_ci            OpFunctionEnd
960fd4e5da5Sopenharmony_ci)";
961fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
962fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
963fd4e5da5Sopenharmony_ci}
964fd4e5da5Sopenharmony_ci
965fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeLoadBad1) {
966fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
967fd4e5da5Sopenharmony_ciOpCapability Shader
968fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR
969fd4e5da5Sopenharmony_ciOpCapability Linkage
970fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model"
971fd4e5da5Sopenharmony_ciOpMemoryModel Logical VulkanKHR
972fd4e5da5Sopenharmony_ci%void = OpTypeVoid
973fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
974fd4e5da5Sopenharmony_ci%device = OpConstant %int 1
975fd4e5da5Sopenharmony_ci%int_ptr_ssbo = OpTypePointer StorageBuffer %int
976fd4e5da5Sopenharmony_ci%var = OpVariable %int_ptr_ssbo StorageBuffer
977fd4e5da5Sopenharmony_ci%voidfn = OpTypeFunction %void
978fd4e5da5Sopenharmony_ci%func = OpFunction %void None %voidfn
979fd4e5da5Sopenharmony_ci%entry = OpLabel
980fd4e5da5Sopenharmony_ci%load = OpLoad %int %var MakePointerVisibleKHR|NonPrivatePointerKHR %device
981fd4e5da5Sopenharmony_ciOpReturn
982fd4e5da5Sopenharmony_ciOpFunctionEnd
983fd4e5da5Sopenharmony_ci)";
984fd4e5da5Sopenharmony_ci
985fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
986fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_DATA,
987fd4e5da5Sopenharmony_ci            ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
988fd4e5da5Sopenharmony_ci  EXPECT_THAT(
989fd4e5da5Sopenharmony_ci      getDiagnosticString(),
990fd4e5da5Sopenharmony_ci      HasSubstr("Use of device scope with VulkanKHR memory model requires the "
991fd4e5da5Sopenharmony_ci                "VulkanMemoryModelDeviceScopeKHR capability"));
992fd4e5da5Sopenharmony_ci}
993fd4e5da5Sopenharmony_ci
994fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeLoadBad2) {
995fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
996fd4e5da5Sopenharmony_ciOpCapability Shader
997fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR
998fd4e5da5Sopenharmony_ciOpCapability Linkage
999fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model"
1000fd4e5da5Sopenharmony_ciOpMemoryModel Logical VulkanKHR
1001fd4e5da5Sopenharmony_ci%void = OpTypeVoid
1002fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
1003fd4e5da5Sopenharmony_ci%device = OpConstant %int 1
1004fd4e5da5Sopenharmony_ci%int_ptr_ssbo = OpTypePointer StorageBuffer %int
1005fd4e5da5Sopenharmony_ci%var = OpVariable %int_ptr_ssbo StorageBuffer
1006fd4e5da5Sopenharmony_ci%voidfn = OpTypeFunction %void
1007fd4e5da5Sopenharmony_ci%func = OpFunction %void None %voidfn
1008fd4e5da5Sopenharmony_ci%entry = OpLabel
1009fd4e5da5Sopenharmony_ci%load = OpLoad %int %var Aligned|MakePointerVisibleKHR|NonPrivatePointerKHR 4 %device
1010fd4e5da5Sopenharmony_ciOpReturn
1011fd4e5da5Sopenharmony_ciOpFunctionEnd
1012fd4e5da5Sopenharmony_ci)";
1013fd4e5da5Sopenharmony_ci
1014fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
1015fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_DATA,
1016fd4e5da5Sopenharmony_ci            ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1017fd4e5da5Sopenharmony_ci  EXPECT_THAT(
1018fd4e5da5Sopenharmony_ci      getDiagnosticString(),
1019fd4e5da5Sopenharmony_ci      HasSubstr("Use of device scope with VulkanKHR memory model requires the "
1020fd4e5da5Sopenharmony_ci                "VulkanMemoryModelDeviceScopeKHR capability"));
1021fd4e5da5Sopenharmony_ci}
1022fd4e5da5Sopenharmony_ci
1023fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeLoadGood1) {
1024fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
1025fd4e5da5Sopenharmony_ciOpCapability Shader
1026fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR
1027fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelDeviceScopeKHR
1028fd4e5da5Sopenharmony_ciOpCapability Linkage
1029fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model"
1030fd4e5da5Sopenharmony_ciOpMemoryModel Logical VulkanKHR
1031fd4e5da5Sopenharmony_ci%void = OpTypeVoid
1032fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
1033fd4e5da5Sopenharmony_ci%device = OpConstant %int 1
1034fd4e5da5Sopenharmony_ci%int_ptr_ssbo = OpTypePointer StorageBuffer %int
1035fd4e5da5Sopenharmony_ci%var = OpVariable %int_ptr_ssbo StorageBuffer
1036fd4e5da5Sopenharmony_ci%voidfn = OpTypeFunction %void
1037fd4e5da5Sopenharmony_ci%func = OpFunction %void None %voidfn
1038fd4e5da5Sopenharmony_ci%entry = OpLabel
1039fd4e5da5Sopenharmony_ci%load = OpLoad %int %var MakePointerVisibleKHR|NonPrivatePointerKHR %device
1040fd4e5da5Sopenharmony_ciOpReturn
1041fd4e5da5Sopenharmony_ciOpFunctionEnd
1042fd4e5da5Sopenharmony_ci)";
1043fd4e5da5Sopenharmony_ci
1044fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
1045fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1046fd4e5da5Sopenharmony_ci}
1047fd4e5da5Sopenharmony_ci
1048fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeLoadGood2) {
1049fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
1050fd4e5da5Sopenharmony_ciOpCapability Shader
1051fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR
1052fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelDeviceScopeKHR
1053fd4e5da5Sopenharmony_ciOpCapability Linkage
1054fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model"
1055fd4e5da5Sopenharmony_ciOpMemoryModel Logical VulkanKHR
1056fd4e5da5Sopenharmony_ci%void = OpTypeVoid
1057fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
1058fd4e5da5Sopenharmony_ci%device = OpConstant %int 1
1059fd4e5da5Sopenharmony_ci%int_ptr_ssbo = OpTypePointer StorageBuffer %int
1060fd4e5da5Sopenharmony_ci%var = OpVariable %int_ptr_ssbo StorageBuffer
1061fd4e5da5Sopenharmony_ci%voidfn = OpTypeFunction %void
1062fd4e5da5Sopenharmony_ci%func = OpFunction %void None %voidfn
1063fd4e5da5Sopenharmony_ci%entry = OpLabel
1064fd4e5da5Sopenharmony_ci%load = OpLoad %int %var Aligned|MakePointerVisibleKHR|NonPrivatePointerKHR 4 %device
1065fd4e5da5Sopenharmony_ciOpReturn
1066fd4e5da5Sopenharmony_ciOpFunctionEnd
1067fd4e5da5Sopenharmony_ci)";
1068fd4e5da5Sopenharmony_ci
1069fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
1070fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1071fd4e5da5Sopenharmony_ci}
1072fd4e5da5Sopenharmony_ci
1073fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeStoreBad1) {
1074fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
1075fd4e5da5Sopenharmony_ciOpCapability Shader
1076fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR
1077fd4e5da5Sopenharmony_ciOpCapability Linkage
1078fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model"
1079fd4e5da5Sopenharmony_ciOpMemoryModel Logical VulkanKHR
1080fd4e5da5Sopenharmony_ci%void = OpTypeVoid
1081fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
1082fd4e5da5Sopenharmony_ci%device = OpConstant %int 1
1083fd4e5da5Sopenharmony_ci%int_ptr_ssbo = OpTypePointer StorageBuffer %int
1084fd4e5da5Sopenharmony_ci%var = OpVariable %int_ptr_ssbo StorageBuffer
1085fd4e5da5Sopenharmony_ci%voidfn = OpTypeFunction %void
1086fd4e5da5Sopenharmony_ci%func = OpFunction %void None %voidfn
1087fd4e5da5Sopenharmony_ci%entry = OpLabel
1088fd4e5da5Sopenharmony_ciOpStore %var %device MakePointerAvailableKHR|NonPrivatePointerKHR %device
1089fd4e5da5Sopenharmony_ciOpReturn
1090fd4e5da5Sopenharmony_ciOpFunctionEnd
1091fd4e5da5Sopenharmony_ci)";
1092fd4e5da5Sopenharmony_ci
1093fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
1094fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_DATA,
1095fd4e5da5Sopenharmony_ci            ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1096fd4e5da5Sopenharmony_ci  EXPECT_THAT(
1097fd4e5da5Sopenharmony_ci      getDiagnosticString(),
1098fd4e5da5Sopenharmony_ci      HasSubstr("Use of device scope with VulkanKHR memory model requires the "
1099fd4e5da5Sopenharmony_ci                "VulkanMemoryModelDeviceScopeKHR capability"));
1100fd4e5da5Sopenharmony_ci}
1101fd4e5da5Sopenharmony_ci
1102fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeStoreBad2) {
1103fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
1104fd4e5da5Sopenharmony_ciOpCapability Shader
1105fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR
1106fd4e5da5Sopenharmony_ciOpCapability Linkage
1107fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model"
1108fd4e5da5Sopenharmony_ciOpMemoryModel Logical VulkanKHR
1109fd4e5da5Sopenharmony_ci%void = OpTypeVoid
1110fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
1111fd4e5da5Sopenharmony_ci%device = OpConstant %int 1
1112fd4e5da5Sopenharmony_ci%int_ptr_ssbo = OpTypePointer StorageBuffer %int
1113fd4e5da5Sopenharmony_ci%var = OpVariable %int_ptr_ssbo StorageBuffer
1114fd4e5da5Sopenharmony_ci%voidfn = OpTypeFunction %void
1115fd4e5da5Sopenharmony_ci%func = OpFunction %void None %voidfn
1116fd4e5da5Sopenharmony_ci%entry = OpLabel
1117fd4e5da5Sopenharmony_ciOpStore %var %device Aligned|MakePointerAvailableKHR|NonPrivatePointerKHR 4 %device
1118fd4e5da5Sopenharmony_ciOpReturn
1119fd4e5da5Sopenharmony_ciOpFunctionEnd
1120fd4e5da5Sopenharmony_ci)";
1121fd4e5da5Sopenharmony_ci
1122fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
1123fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_DATA,
1124fd4e5da5Sopenharmony_ci            ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1125fd4e5da5Sopenharmony_ci  EXPECT_THAT(
1126fd4e5da5Sopenharmony_ci      getDiagnosticString(),
1127fd4e5da5Sopenharmony_ci      HasSubstr("Use of device scope with VulkanKHR memory model requires the "
1128fd4e5da5Sopenharmony_ci                "VulkanMemoryModelDeviceScopeKHR capability"));
1129fd4e5da5Sopenharmony_ci}
1130fd4e5da5Sopenharmony_ci
1131fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeStoreGood1) {
1132fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
1133fd4e5da5Sopenharmony_ciOpCapability Shader
1134fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR
1135fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelDeviceScopeKHR
1136fd4e5da5Sopenharmony_ciOpCapability Linkage
1137fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model"
1138fd4e5da5Sopenharmony_ciOpMemoryModel Logical VulkanKHR
1139fd4e5da5Sopenharmony_ci%void = OpTypeVoid
1140fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
1141fd4e5da5Sopenharmony_ci%device = OpConstant %int 1
1142fd4e5da5Sopenharmony_ci%int_ptr_ssbo = OpTypePointer StorageBuffer %int
1143fd4e5da5Sopenharmony_ci%var = OpVariable %int_ptr_ssbo StorageBuffer
1144fd4e5da5Sopenharmony_ci%voidfn = OpTypeFunction %void
1145fd4e5da5Sopenharmony_ci%func = OpFunction %void None %voidfn
1146fd4e5da5Sopenharmony_ci%entry = OpLabel
1147fd4e5da5Sopenharmony_ciOpStore %var %device MakePointerAvailableKHR|NonPrivatePointerKHR %device
1148fd4e5da5Sopenharmony_ciOpReturn
1149fd4e5da5Sopenharmony_ciOpFunctionEnd
1150fd4e5da5Sopenharmony_ci)";
1151fd4e5da5Sopenharmony_ci
1152fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
1153fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1154fd4e5da5Sopenharmony_ci}
1155fd4e5da5Sopenharmony_ci
1156fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeStoreGood2) {
1157fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
1158fd4e5da5Sopenharmony_ciOpCapability Shader
1159fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR
1160fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelDeviceScopeKHR
1161fd4e5da5Sopenharmony_ciOpCapability Linkage
1162fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model"
1163fd4e5da5Sopenharmony_ciOpMemoryModel Logical VulkanKHR
1164fd4e5da5Sopenharmony_ci%void = OpTypeVoid
1165fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
1166fd4e5da5Sopenharmony_ci%device = OpConstant %int 1
1167fd4e5da5Sopenharmony_ci%int_ptr_ssbo = OpTypePointer StorageBuffer %int
1168fd4e5da5Sopenharmony_ci%var = OpVariable %int_ptr_ssbo StorageBuffer
1169fd4e5da5Sopenharmony_ci%voidfn = OpTypeFunction %void
1170fd4e5da5Sopenharmony_ci%func = OpFunction %void None %voidfn
1171fd4e5da5Sopenharmony_ci%entry = OpLabel
1172fd4e5da5Sopenharmony_ciOpStore %var %device Aligned|MakePointerAvailableKHR|NonPrivatePointerKHR 4 %device
1173fd4e5da5Sopenharmony_ciOpReturn
1174fd4e5da5Sopenharmony_ciOpFunctionEnd
1175fd4e5da5Sopenharmony_ci)";
1176fd4e5da5Sopenharmony_ci
1177fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
1178fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1179fd4e5da5Sopenharmony_ci}
1180fd4e5da5Sopenharmony_ci
1181fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeCopyMemoryBad1) {
1182fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
1183fd4e5da5Sopenharmony_ciOpCapability Shader
1184fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR
1185fd4e5da5Sopenharmony_ciOpCapability Linkage
1186fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model"
1187fd4e5da5Sopenharmony_ciOpMemoryModel Logical VulkanKHR
1188fd4e5da5Sopenharmony_ci%void = OpTypeVoid
1189fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
1190fd4e5da5Sopenharmony_ci%device = OpConstant %int 1
1191fd4e5da5Sopenharmony_ci%int_ptr_ssbo = OpTypePointer StorageBuffer %int
1192fd4e5da5Sopenharmony_ci%var1 = OpVariable %int_ptr_ssbo StorageBuffer
1193fd4e5da5Sopenharmony_ci%var2 = OpVariable %int_ptr_ssbo StorageBuffer
1194fd4e5da5Sopenharmony_ci%voidfn = OpTypeFunction %void
1195fd4e5da5Sopenharmony_ci%func = OpFunction %void None %voidfn
1196fd4e5da5Sopenharmony_ci%entry = OpLabel
1197fd4e5da5Sopenharmony_ciOpCopyMemory %var1 %var2 MakePointerAvailableKHR|NonPrivatePointerKHR %device
1198fd4e5da5Sopenharmony_ciOpReturn
1199fd4e5da5Sopenharmony_ciOpFunctionEnd
1200fd4e5da5Sopenharmony_ci)";
1201fd4e5da5Sopenharmony_ci
1202fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
1203fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_DATA,
1204fd4e5da5Sopenharmony_ci            ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1205fd4e5da5Sopenharmony_ci  EXPECT_THAT(
1206fd4e5da5Sopenharmony_ci      getDiagnosticString(),
1207fd4e5da5Sopenharmony_ci      HasSubstr("Use of device scope with VulkanKHR memory model requires the "
1208fd4e5da5Sopenharmony_ci                "VulkanMemoryModelDeviceScopeKHR capability"));
1209fd4e5da5Sopenharmony_ci}
1210fd4e5da5Sopenharmony_ci
1211fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeCopyMemoryBad2) {
1212fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
1213fd4e5da5Sopenharmony_ciOpCapability Shader
1214fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR
1215fd4e5da5Sopenharmony_ciOpCapability Linkage
1216fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model"
1217fd4e5da5Sopenharmony_ciOpMemoryModel Logical VulkanKHR
1218fd4e5da5Sopenharmony_ci%void = OpTypeVoid
1219fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
1220fd4e5da5Sopenharmony_ci%device = OpConstant %int 1
1221fd4e5da5Sopenharmony_ci%workgroup = OpConstant %int 1
1222fd4e5da5Sopenharmony_ci%int_ptr_ssbo = OpTypePointer StorageBuffer %int
1223fd4e5da5Sopenharmony_ci%var1 = OpVariable %int_ptr_ssbo StorageBuffer
1224fd4e5da5Sopenharmony_ci%var2 = OpVariable %int_ptr_ssbo StorageBuffer
1225fd4e5da5Sopenharmony_ci%voidfn = OpTypeFunction %void
1226fd4e5da5Sopenharmony_ci%func = OpFunction %void None %voidfn
1227fd4e5da5Sopenharmony_ci%entry = OpLabel
1228fd4e5da5Sopenharmony_ciOpCopyMemory %var1 %var2 Aligned|MakePointerVisibleKHR|MakePointerAvailableKHR|NonPrivatePointerKHR 4 %device %workgroup
1229fd4e5da5Sopenharmony_ciOpReturn
1230fd4e5da5Sopenharmony_ciOpFunctionEnd
1231fd4e5da5Sopenharmony_ci)";
1232fd4e5da5Sopenharmony_ci
1233fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
1234fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_DATA,
1235fd4e5da5Sopenharmony_ci            ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1236fd4e5da5Sopenharmony_ci  EXPECT_THAT(
1237fd4e5da5Sopenharmony_ci      getDiagnosticString(),
1238fd4e5da5Sopenharmony_ci      HasSubstr("Use of device scope with VulkanKHR memory model requires the "
1239fd4e5da5Sopenharmony_ci                "VulkanMemoryModelDeviceScopeKHR capability"));
1240fd4e5da5Sopenharmony_ci}
1241fd4e5da5Sopenharmony_ci
1242fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeCopyMemoryBad3) {
1243fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
1244fd4e5da5Sopenharmony_ciOpCapability Shader
1245fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR
1246fd4e5da5Sopenharmony_ciOpCapability Linkage
1247fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model"
1248fd4e5da5Sopenharmony_ciOpMemoryModel Logical VulkanKHR
1249fd4e5da5Sopenharmony_ci%void = OpTypeVoid
1250fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
1251fd4e5da5Sopenharmony_ci%device = OpConstant %int 1
1252fd4e5da5Sopenharmony_ci%workgroup = OpConstant %int 1
1253fd4e5da5Sopenharmony_ci%int_ptr_ssbo = OpTypePointer StorageBuffer %int
1254fd4e5da5Sopenharmony_ci%var1 = OpVariable %int_ptr_ssbo StorageBuffer
1255fd4e5da5Sopenharmony_ci%var2 = OpVariable %int_ptr_ssbo StorageBuffer
1256fd4e5da5Sopenharmony_ci%voidfn = OpTypeFunction %void
1257fd4e5da5Sopenharmony_ci%func = OpFunction %void None %voidfn
1258fd4e5da5Sopenharmony_ci%entry = OpLabel
1259fd4e5da5Sopenharmony_ciOpCopyMemory %var1 %var2 Aligned|MakePointerVisibleKHR|MakePointerAvailableKHR|NonPrivatePointerKHR 4 %workgroup %device
1260fd4e5da5Sopenharmony_ciOpReturn
1261fd4e5da5Sopenharmony_ciOpFunctionEnd
1262fd4e5da5Sopenharmony_ci)";
1263fd4e5da5Sopenharmony_ci
1264fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
1265fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_DATA,
1266fd4e5da5Sopenharmony_ci            ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1267fd4e5da5Sopenharmony_ci  EXPECT_THAT(
1268fd4e5da5Sopenharmony_ci      getDiagnosticString(),
1269fd4e5da5Sopenharmony_ci      HasSubstr("Use of device scope with VulkanKHR memory model requires the "
1270fd4e5da5Sopenharmony_ci                "VulkanMemoryModelDeviceScopeKHR capability"));
1271fd4e5da5Sopenharmony_ci}
1272fd4e5da5Sopenharmony_ci
1273fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeCopyMemoryGood2) {
1274fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
1275fd4e5da5Sopenharmony_ciOpCapability Shader
1276fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR
1277fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelDeviceScopeKHR
1278fd4e5da5Sopenharmony_ciOpCapability Linkage
1279fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model"
1280fd4e5da5Sopenharmony_ciOpMemoryModel Logical VulkanKHR
1281fd4e5da5Sopenharmony_ci%void = OpTypeVoid
1282fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
1283fd4e5da5Sopenharmony_ci%device = OpConstant %int 1
1284fd4e5da5Sopenharmony_ci%workgroup = OpConstant %int 2
1285fd4e5da5Sopenharmony_ci%int_ptr_ssbo = OpTypePointer StorageBuffer %int
1286fd4e5da5Sopenharmony_ci%var1 = OpVariable %int_ptr_ssbo StorageBuffer
1287fd4e5da5Sopenharmony_ci%var2 = OpVariable %int_ptr_ssbo StorageBuffer
1288fd4e5da5Sopenharmony_ci%voidfn = OpTypeFunction %void
1289fd4e5da5Sopenharmony_ci%func = OpFunction %void None %voidfn
1290fd4e5da5Sopenharmony_ci%entry = OpLabel
1291fd4e5da5Sopenharmony_ciOpCopyMemory %var1 %var2 Aligned|MakePointerVisibleKHR|MakePointerAvailableKHR|NonPrivatePointerKHR 4 %device %workgroup
1292fd4e5da5Sopenharmony_ciOpReturn
1293fd4e5da5Sopenharmony_ciOpFunctionEnd
1294fd4e5da5Sopenharmony_ci)";
1295fd4e5da5Sopenharmony_ci
1296fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
1297fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1298fd4e5da5Sopenharmony_ci}
1299fd4e5da5Sopenharmony_ci
1300fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeCopyMemoryGood3) {
1301fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
1302fd4e5da5Sopenharmony_ciOpCapability Shader
1303fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR
1304fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelDeviceScopeKHR
1305fd4e5da5Sopenharmony_ciOpCapability Linkage
1306fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model"
1307fd4e5da5Sopenharmony_ciOpMemoryModel Logical VulkanKHR
1308fd4e5da5Sopenharmony_ci%void = OpTypeVoid
1309fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
1310fd4e5da5Sopenharmony_ci%device = OpConstant %int 1
1311fd4e5da5Sopenharmony_ci%workgroup = OpConstant %int 2
1312fd4e5da5Sopenharmony_ci%int_ptr_ssbo = OpTypePointer StorageBuffer %int
1313fd4e5da5Sopenharmony_ci%var1 = OpVariable %int_ptr_ssbo StorageBuffer
1314fd4e5da5Sopenharmony_ci%var2 = OpVariable %int_ptr_ssbo StorageBuffer
1315fd4e5da5Sopenharmony_ci%voidfn = OpTypeFunction %void
1316fd4e5da5Sopenharmony_ci%func = OpFunction %void None %voidfn
1317fd4e5da5Sopenharmony_ci%entry = OpLabel
1318fd4e5da5Sopenharmony_ciOpCopyMemory %var1 %var2 Aligned|MakePointerVisibleKHR|MakePointerAvailableKHR|NonPrivatePointerKHR 4 %workgroup %device
1319fd4e5da5Sopenharmony_ciOpReturn
1320fd4e5da5Sopenharmony_ciOpFunctionEnd
1321fd4e5da5Sopenharmony_ci)";
1322fd4e5da5Sopenharmony_ci
1323fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
1324fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1325fd4e5da5Sopenharmony_ci}
1326fd4e5da5Sopenharmony_ci
1327fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, VulkanMemoryModelCopyMemoryTwoAccessAvVisBadBinaryV13) {
1328fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
1329fd4e5da5Sopenharmony_ciOpCapability Shader
1330fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR
1331fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelDeviceScopeKHR
1332fd4e5da5Sopenharmony_ciOpCapability Linkage
1333fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model"
1334fd4e5da5Sopenharmony_ciOpMemoryModel Logical VulkanKHR
1335fd4e5da5Sopenharmony_ci%void = OpTypeVoid
1336fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
1337fd4e5da5Sopenharmony_ci%device = OpConstant %int 1
1338fd4e5da5Sopenharmony_ci%int_ptr_ssbo = OpTypePointer StorageBuffer %int
1339fd4e5da5Sopenharmony_ci%var1 = OpVariable %int_ptr_ssbo StorageBuffer
1340fd4e5da5Sopenharmony_ci%var2 = OpVariable %int_ptr_ssbo StorageBuffer
1341fd4e5da5Sopenharmony_ci%voidfn = OpTypeFunction %void
1342fd4e5da5Sopenharmony_ci%func = OpFunction %void None %voidfn
1343fd4e5da5Sopenharmony_ci%entry = OpLabel
1344fd4e5da5Sopenharmony_ciOpCopyMemory %var1 %var2
1345fd4e5da5Sopenharmony_ci  MakePointerAvailableKHR|NonPrivatePointerKHR %device
1346fd4e5da5Sopenharmony_ci  MakePointerVisibleKHR|NonPrivatePointerKHR %device
1347fd4e5da5Sopenharmony_ciOpReturn
1348fd4e5da5Sopenharmony_ciOpFunctionEnd
1349fd4e5da5Sopenharmony_ci)";
1350fd4e5da5Sopenharmony_ci
1351fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
1352fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_DATA,
1353fd4e5da5Sopenharmony_ci            ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
1354fd4e5da5Sopenharmony_ci  EXPECT_THAT(
1355fd4e5da5Sopenharmony_ci      getDiagnosticString(),
1356fd4e5da5Sopenharmony_ci      HasSubstr(
1357fd4e5da5Sopenharmony_ci          "with two memory access operands requires SPIR-V 1.4 or later"));
1358fd4e5da5Sopenharmony_ci}
1359fd4e5da5Sopenharmony_ci
1360fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, VulkanMemoryModelCopyMemoryTwoAccessAvVisGood) {
1361fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
1362fd4e5da5Sopenharmony_ciOpCapability Shader
1363fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR
1364fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelDeviceScopeKHR
1365fd4e5da5Sopenharmony_ciOpCapability Linkage
1366fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model"
1367fd4e5da5Sopenharmony_ciOpMemoryModel Logical VulkanKHR
1368fd4e5da5Sopenharmony_ci%void = OpTypeVoid
1369fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
1370fd4e5da5Sopenharmony_ci%device = OpConstant %int 1
1371fd4e5da5Sopenharmony_ci%int_ptr_ssbo = OpTypePointer StorageBuffer %int
1372fd4e5da5Sopenharmony_ci%var1 = OpVariable %int_ptr_ssbo StorageBuffer
1373fd4e5da5Sopenharmony_ci%var2 = OpVariable %int_ptr_ssbo StorageBuffer
1374fd4e5da5Sopenharmony_ci%voidfn = OpTypeFunction %void
1375fd4e5da5Sopenharmony_ci%func = OpFunction %void None %voidfn
1376fd4e5da5Sopenharmony_ci%entry = OpLabel
1377fd4e5da5Sopenharmony_ciOpCopyMemory %var1 %var2
1378fd4e5da5Sopenharmony_ci  MakePointerAvailableKHR|NonPrivatePointerKHR %device
1379fd4e5da5Sopenharmony_ci  MakePointerVisibleKHR|NonPrivatePointerKHR %device
1380fd4e5da5Sopenharmony_ciOpReturn
1381fd4e5da5Sopenharmony_ciOpFunctionEnd
1382fd4e5da5Sopenharmony_ci)";
1383fd4e5da5Sopenharmony_ci
1384fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
1385fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
1386fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(), Eq(""));
1387fd4e5da5Sopenharmony_ci}
1388fd4e5da5Sopenharmony_ci
1389fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, VulkanMemoryModelCopyMemoryTwoAccessFirstWithAvBad) {
1390fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
1391fd4e5da5Sopenharmony_ciOpCapability Shader
1392fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR
1393fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelDeviceScopeKHR
1394fd4e5da5Sopenharmony_ciOpCapability Linkage
1395fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model"
1396fd4e5da5Sopenharmony_ciOpMemoryModel Logical VulkanKHR
1397fd4e5da5Sopenharmony_ci%void = OpTypeVoid
1398fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
1399fd4e5da5Sopenharmony_ci%device = OpConstant %int 1
1400fd4e5da5Sopenharmony_ci%int_ptr_ssbo = OpTypePointer StorageBuffer %int
1401fd4e5da5Sopenharmony_ci%var1 = OpVariable %int_ptr_ssbo StorageBuffer
1402fd4e5da5Sopenharmony_ci%var2 = OpVariable %int_ptr_ssbo StorageBuffer
1403fd4e5da5Sopenharmony_ci%voidfn = OpTypeFunction %void
1404fd4e5da5Sopenharmony_ci%func = OpFunction %void None %voidfn
1405fd4e5da5Sopenharmony_ci%entry = OpLabel
1406fd4e5da5Sopenharmony_ciOpCopyMemory %var1 %var2
1407fd4e5da5Sopenharmony_ci  MakePointerAvailableKHR|NonPrivatePointerKHR %device
1408fd4e5da5Sopenharmony_ci  MakePointerAvailableKHR|NonPrivatePointerKHR %device
1409fd4e5da5Sopenharmony_ciOpReturn
1410fd4e5da5Sopenharmony_ciOpFunctionEnd
1411fd4e5da5Sopenharmony_ci)";
1412fd4e5da5Sopenharmony_ci
1413fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
1414fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_DATA,
1415fd4e5da5Sopenharmony_ci            ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
1416fd4e5da5Sopenharmony_ci  EXPECT_THAT(
1417fd4e5da5Sopenharmony_ci      getDiagnosticString(),
1418fd4e5da5Sopenharmony_ci      HasSubstr(
1419fd4e5da5Sopenharmony_ci          "Source memory access must not include MakePointerAvailableKHR\n"
1420fd4e5da5Sopenharmony_ci          "  OpCopyMemory %5 %6 MakePointerAvailable|NonPrivatePointer"
1421fd4e5da5Sopenharmony_ci          " %uint_1 MakePointerAvailable|NonPrivatePointer %uint_1"));
1422fd4e5da5Sopenharmony_ci}
1423fd4e5da5Sopenharmony_ci
1424fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, VulkanMemoryModelCopyMemoryTwoAccessSecondWithVisBad) {
1425fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
1426fd4e5da5Sopenharmony_ciOpCapability Shader
1427fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR
1428fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelDeviceScopeKHR
1429fd4e5da5Sopenharmony_ciOpCapability Linkage
1430fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model"
1431fd4e5da5Sopenharmony_ciOpMemoryModel Logical VulkanKHR
1432fd4e5da5Sopenharmony_ci%void = OpTypeVoid
1433fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
1434fd4e5da5Sopenharmony_ci%device = OpConstant %int 1
1435fd4e5da5Sopenharmony_ci%int_ptr_ssbo = OpTypePointer StorageBuffer %int
1436fd4e5da5Sopenharmony_ci%var1 = OpVariable %int_ptr_ssbo StorageBuffer
1437fd4e5da5Sopenharmony_ci%var2 = OpVariable %int_ptr_ssbo StorageBuffer
1438fd4e5da5Sopenharmony_ci%voidfn = OpTypeFunction %void
1439fd4e5da5Sopenharmony_ci%func = OpFunction %void None %voidfn
1440fd4e5da5Sopenharmony_ci%entry = OpLabel
1441fd4e5da5Sopenharmony_ciOpCopyMemory %var1 %var2
1442fd4e5da5Sopenharmony_ci  MakePointerVisibleKHR|NonPrivatePointerKHR %device
1443fd4e5da5Sopenharmony_ci  MakePointerVisibleKHR|NonPrivatePointerKHR %device
1444fd4e5da5Sopenharmony_ciOpReturn
1445fd4e5da5Sopenharmony_ciOpFunctionEnd
1446fd4e5da5Sopenharmony_ci)";
1447fd4e5da5Sopenharmony_ci
1448fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
1449fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_DATA,
1450fd4e5da5Sopenharmony_ci            ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
1451fd4e5da5Sopenharmony_ci  EXPECT_THAT(
1452fd4e5da5Sopenharmony_ci      getDiagnosticString(),
1453fd4e5da5Sopenharmony_ci      HasSubstr("Target memory access must not include MakePointerVisibleKHR\n"
1454fd4e5da5Sopenharmony_ci                "  OpCopyMemory %5 %6 MakePointerVisible|NonPrivatePointer"
1455fd4e5da5Sopenharmony_ci                " %uint_1 MakePointerVisible|NonPrivatePointer %uint_1"));
1456fd4e5da5Sopenharmony_ci}
1457fd4e5da5Sopenharmony_ci
1458fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeCopyMemorySizedBad1) {
1459fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
1460fd4e5da5Sopenharmony_ciOpCapability Shader
1461fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR
1462fd4e5da5Sopenharmony_ciOpCapability Linkage
1463fd4e5da5Sopenharmony_ciOpCapability Addresses
1464fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model"
1465fd4e5da5Sopenharmony_ciOpMemoryModel Logical VulkanKHR
1466fd4e5da5Sopenharmony_ci%void = OpTypeVoid
1467fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
1468fd4e5da5Sopenharmony_ci%device = OpConstant %int 1
1469fd4e5da5Sopenharmony_ci%int_ptr_ssbo = OpTypePointer StorageBuffer %int
1470fd4e5da5Sopenharmony_ci%var1 = OpVariable %int_ptr_ssbo StorageBuffer
1471fd4e5da5Sopenharmony_ci%var2 = OpVariable %int_ptr_ssbo StorageBuffer
1472fd4e5da5Sopenharmony_ci%voidfn = OpTypeFunction %void
1473fd4e5da5Sopenharmony_ci%func = OpFunction %void None %voidfn
1474fd4e5da5Sopenharmony_ci%entry = OpLabel
1475fd4e5da5Sopenharmony_ciOpCopyMemorySized %var1 %var2 %device MakePointerAvailableKHR|NonPrivatePointerKHR %device
1476fd4e5da5Sopenharmony_ciOpReturn
1477fd4e5da5Sopenharmony_ciOpFunctionEnd
1478fd4e5da5Sopenharmony_ci)";
1479fd4e5da5Sopenharmony_ci
1480fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
1481fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_DATA,
1482fd4e5da5Sopenharmony_ci            ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1483fd4e5da5Sopenharmony_ci  EXPECT_THAT(
1484fd4e5da5Sopenharmony_ci      getDiagnosticString(),
1485fd4e5da5Sopenharmony_ci      HasSubstr("Use of device scope with VulkanKHR memory model requires the "
1486fd4e5da5Sopenharmony_ci                "VulkanMemoryModelDeviceScopeKHR capability"));
1487fd4e5da5Sopenharmony_ci}
1488fd4e5da5Sopenharmony_ci
1489fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeCopyMemorySizedBad2) {
1490fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
1491fd4e5da5Sopenharmony_ciOpCapability Shader
1492fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR
1493fd4e5da5Sopenharmony_ciOpCapability Linkage
1494fd4e5da5Sopenharmony_ciOpCapability Addresses
1495fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model"
1496fd4e5da5Sopenharmony_ciOpMemoryModel Logical VulkanKHR
1497fd4e5da5Sopenharmony_ci%void = OpTypeVoid
1498fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
1499fd4e5da5Sopenharmony_ci%device = OpConstant %int 1
1500fd4e5da5Sopenharmony_ci%workgroup = OpConstant %int 1
1501fd4e5da5Sopenharmony_ci%int_ptr_ssbo = OpTypePointer StorageBuffer %int
1502fd4e5da5Sopenharmony_ci%var1 = OpVariable %int_ptr_ssbo StorageBuffer
1503fd4e5da5Sopenharmony_ci%var2 = OpVariable %int_ptr_ssbo StorageBuffer
1504fd4e5da5Sopenharmony_ci%voidfn = OpTypeFunction %void
1505fd4e5da5Sopenharmony_ci%func = OpFunction %void None %voidfn
1506fd4e5da5Sopenharmony_ci%entry = OpLabel
1507fd4e5da5Sopenharmony_ciOpCopyMemorySized %var1 %var2 %device Aligned|MakePointerVisibleKHR|MakePointerAvailableKHR|NonPrivatePointerKHR 4 %device %workgroup
1508fd4e5da5Sopenharmony_ciOpReturn
1509fd4e5da5Sopenharmony_ciOpFunctionEnd
1510fd4e5da5Sopenharmony_ci)";
1511fd4e5da5Sopenharmony_ci
1512fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
1513fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_DATA,
1514fd4e5da5Sopenharmony_ci            ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1515fd4e5da5Sopenharmony_ci  EXPECT_THAT(
1516fd4e5da5Sopenharmony_ci      getDiagnosticString(),
1517fd4e5da5Sopenharmony_ci      HasSubstr("Use of device scope with VulkanKHR memory model requires the "
1518fd4e5da5Sopenharmony_ci                "VulkanMemoryModelDeviceScopeKHR capability"));
1519fd4e5da5Sopenharmony_ci}
1520fd4e5da5Sopenharmony_ci
1521fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeCopyMemorySizedBad3) {
1522fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
1523fd4e5da5Sopenharmony_ciOpCapability Shader
1524fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR
1525fd4e5da5Sopenharmony_ciOpCapability Linkage
1526fd4e5da5Sopenharmony_ciOpCapability Addresses
1527fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model"
1528fd4e5da5Sopenharmony_ciOpMemoryModel Logical VulkanKHR
1529fd4e5da5Sopenharmony_ci%void = OpTypeVoid
1530fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
1531fd4e5da5Sopenharmony_ci%device = OpConstant %int 1
1532fd4e5da5Sopenharmony_ci%workgroup = OpConstant %int 1
1533fd4e5da5Sopenharmony_ci%int_ptr_ssbo = OpTypePointer StorageBuffer %int
1534fd4e5da5Sopenharmony_ci%var1 = OpVariable %int_ptr_ssbo StorageBuffer
1535fd4e5da5Sopenharmony_ci%var2 = OpVariable %int_ptr_ssbo StorageBuffer
1536fd4e5da5Sopenharmony_ci%voidfn = OpTypeFunction %void
1537fd4e5da5Sopenharmony_ci%func = OpFunction %void None %voidfn
1538fd4e5da5Sopenharmony_ci%entry = OpLabel
1539fd4e5da5Sopenharmony_ciOpCopyMemorySized %var1 %var2 %device Aligned|MakePointerVisibleKHR|MakePointerAvailableKHR|NonPrivatePointerKHR 4 %workgroup %device
1540fd4e5da5Sopenharmony_ciOpReturn
1541fd4e5da5Sopenharmony_ciOpFunctionEnd
1542fd4e5da5Sopenharmony_ci)";
1543fd4e5da5Sopenharmony_ci
1544fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
1545fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_DATA,
1546fd4e5da5Sopenharmony_ci            ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1547fd4e5da5Sopenharmony_ci  EXPECT_THAT(
1548fd4e5da5Sopenharmony_ci      getDiagnosticString(),
1549fd4e5da5Sopenharmony_ci      HasSubstr("Use of device scope with VulkanKHR memory model requires the "
1550fd4e5da5Sopenharmony_ci                "VulkanMemoryModelDeviceScopeKHR capability"));
1551fd4e5da5Sopenharmony_ci}
1552fd4e5da5Sopenharmony_ci
1553fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeCopyMemorySizedGood1) {
1554fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
1555fd4e5da5Sopenharmony_ciOpCapability Shader
1556fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR
1557fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelDeviceScopeKHR
1558fd4e5da5Sopenharmony_ciOpCapability Linkage
1559fd4e5da5Sopenharmony_ciOpCapability Addresses
1560fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model"
1561fd4e5da5Sopenharmony_ciOpMemoryModel Logical VulkanKHR
1562fd4e5da5Sopenharmony_ci%void = OpTypeVoid
1563fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
1564fd4e5da5Sopenharmony_ci%device = OpConstant %int 1
1565fd4e5da5Sopenharmony_ci%int_ptr_ssbo = OpTypePointer StorageBuffer %int
1566fd4e5da5Sopenharmony_ci%var1 = OpVariable %int_ptr_ssbo StorageBuffer
1567fd4e5da5Sopenharmony_ci%var2 = OpVariable %int_ptr_ssbo StorageBuffer
1568fd4e5da5Sopenharmony_ci%voidfn = OpTypeFunction %void
1569fd4e5da5Sopenharmony_ci%func = OpFunction %void None %voidfn
1570fd4e5da5Sopenharmony_ci%entry = OpLabel
1571fd4e5da5Sopenharmony_ciOpCopyMemorySized %var1 %var2 %device MakePointerAvailableKHR|NonPrivatePointerKHR %device
1572fd4e5da5Sopenharmony_ciOpReturn
1573fd4e5da5Sopenharmony_ciOpFunctionEnd
1574fd4e5da5Sopenharmony_ci)";
1575fd4e5da5Sopenharmony_ci
1576fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
1577fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1578fd4e5da5Sopenharmony_ci}
1579fd4e5da5Sopenharmony_ci
1580fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeCopyMemorySizedGood2) {
1581fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
1582fd4e5da5Sopenharmony_ciOpCapability Shader
1583fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR
1584fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelDeviceScopeKHR
1585fd4e5da5Sopenharmony_ciOpCapability Linkage
1586fd4e5da5Sopenharmony_ciOpCapability Addresses
1587fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model"
1588fd4e5da5Sopenharmony_ciOpMemoryModel Logical VulkanKHR
1589fd4e5da5Sopenharmony_ci%void = OpTypeVoid
1590fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
1591fd4e5da5Sopenharmony_ci%device = OpConstant %int 1
1592fd4e5da5Sopenharmony_ci%workgroup = OpConstant %int 2
1593fd4e5da5Sopenharmony_ci%int_ptr_ssbo = OpTypePointer StorageBuffer %int
1594fd4e5da5Sopenharmony_ci%var1 = OpVariable %int_ptr_ssbo StorageBuffer
1595fd4e5da5Sopenharmony_ci%var2 = OpVariable %int_ptr_ssbo StorageBuffer
1596fd4e5da5Sopenharmony_ci%voidfn = OpTypeFunction %void
1597fd4e5da5Sopenharmony_ci%func = OpFunction %void None %voidfn
1598fd4e5da5Sopenharmony_ci%entry = OpLabel
1599fd4e5da5Sopenharmony_ciOpCopyMemorySized %var1 %var2 %device Aligned|MakePointerVisibleKHR|MakePointerAvailableKHR|NonPrivatePointerKHR 4 %device %workgroup
1600fd4e5da5Sopenharmony_ciOpReturn
1601fd4e5da5Sopenharmony_ciOpFunctionEnd
1602fd4e5da5Sopenharmony_ci)";
1603fd4e5da5Sopenharmony_ci
1604fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
1605fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1606fd4e5da5Sopenharmony_ci}
1607fd4e5da5Sopenharmony_ci
1608fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeCopyMemorySizedGood3) {
1609fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
1610fd4e5da5Sopenharmony_ciOpCapability Shader
1611fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR
1612fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelDeviceScopeKHR
1613fd4e5da5Sopenharmony_ciOpCapability Linkage
1614fd4e5da5Sopenharmony_ciOpCapability Addresses
1615fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model"
1616fd4e5da5Sopenharmony_ciOpMemoryModel Logical VulkanKHR
1617fd4e5da5Sopenharmony_ci%void = OpTypeVoid
1618fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
1619fd4e5da5Sopenharmony_ci%device = OpConstant %int 1
1620fd4e5da5Sopenharmony_ci%workgroup = OpConstant %int 2
1621fd4e5da5Sopenharmony_ci%int_ptr_ssbo = OpTypePointer StorageBuffer %int
1622fd4e5da5Sopenharmony_ci%var1 = OpVariable %int_ptr_ssbo StorageBuffer
1623fd4e5da5Sopenharmony_ci%var2 = OpVariable %int_ptr_ssbo StorageBuffer
1624fd4e5da5Sopenharmony_ci%voidfn = OpTypeFunction %void
1625fd4e5da5Sopenharmony_ci%func = OpFunction %void None %voidfn
1626fd4e5da5Sopenharmony_ci%entry = OpLabel
1627fd4e5da5Sopenharmony_ciOpCopyMemorySized %var1 %var2 %device Aligned|MakePointerVisibleKHR|MakePointerAvailableKHR|NonPrivatePointerKHR 4 %workgroup %device
1628fd4e5da5Sopenharmony_ciOpReturn
1629fd4e5da5Sopenharmony_ciOpFunctionEnd
1630fd4e5da5Sopenharmony_ci)";
1631fd4e5da5Sopenharmony_ci
1632fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
1633fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1634fd4e5da5Sopenharmony_ci}
1635fd4e5da5Sopenharmony_ci
1636fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, ArrayLengthStructIsLabel) {
1637fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
1638fd4e5da5Sopenharmony_ciOpCapability Tessellation
1639fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
1640fd4e5da5Sopenharmony_ciOpName %20 "incorrect"
1641fd4e5da5Sopenharmony_ci%void = OpTypeVoid
1642fd4e5da5Sopenharmony_ci%3 = OpTypeFunction %void
1643fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
1644fd4e5da5Sopenharmony_ci%v4float = OpTypeVector %float 4
1645fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
1646fd4e5da5Sopenharmony_ci%4 = OpFunction %void None %3
1647fd4e5da5Sopenharmony_ci%20 = OpLabel
1648fd4e5da5Sopenharmony_ci%24 = OpArrayLength %uint %20 0
1649fd4e5da5Sopenharmony_ci%25 = OpLoad %v4float %24
1650fd4e5da5Sopenharmony_ciOpReturnValue %25
1651fd4e5da5Sopenharmony_ciOpFunctionEnd
1652fd4e5da5Sopenharmony_ci)";
1653fd4e5da5Sopenharmony_ci
1654fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv);
1655fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
1656fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
1657fd4e5da5Sopenharmony_ci              HasSubstr("Operand '1[%incorrect]' requires a type"));
1658fd4e5da5Sopenharmony_ci}
1659fd4e5da5Sopenharmony_ci
1660fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, PSBLoadAlignedSuccess) {
1661fd4e5da5Sopenharmony_ci  const std::string body = R"(
1662fd4e5da5Sopenharmony_ciOpCapability PhysicalStorageBufferAddresses
1663fd4e5da5Sopenharmony_ciOpCapability Int64
1664fd4e5da5Sopenharmony_ciOpCapability Shader
1665fd4e5da5Sopenharmony_ciOpExtension "SPV_EXT_physical_storage_buffer"
1666fd4e5da5Sopenharmony_ciOpMemoryModel PhysicalStorageBuffer64 GLSL450
1667fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main"
1668fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
1669fd4e5da5Sopenharmony_ciOpDecorate %val1 AliasedPointer
1670fd4e5da5Sopenharmony_ci%uint64 = OpTypeInt 64 0
1671fd4e5da5Sopenharmony_ci%ptr = OpTypePointer PhysicalStorageBuffer %uint64
1672fd4e5da5Sopenharmony_ci%pptr_f = OpTypePointer Function %ptr
1673fd4e5da5Sopenharmony_ci%void = OpTypeVoid
1674fd4e5da5Sopenharmony_ci%voidfn = OpTypeFunction %void
1675fd4e5da5Sopenharmony_ci%main = OpFunction %void None %voidfn
1676fd4e5da5Sopenharmony_ci%entry = OpLabel
1677fd4e5da5Sopenharmony_ci%val1 = OpVariable %pptr_f Function
1678fd4e5da5Sopenharmony_ci%val2 = OpLoad %ptr %val1
1679fd4e5da5Sopenharmony_ci%val3 = OpLoad %uint64 %val2 Aligned 8
1680fd4e5da5Sopenharmony_ciOpReturn
1681fd4e5da5Sopenharmony_ciOpFunctionEnd
1682fd4e5da5Sopenharmony_ci)";
1683fd4e5da5Sopenharmony_ci
1684fd4e5da5Sopenharmony_ci  CompileSuccessfully(body.c_str(), SPV_ENV_VULKAN_1_2);
1685fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
1686fd4e5da5Sopenharmony_ci}
1687fd4e5da5Sopenharmony_ci
1688fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, PSBLoadAlignedMissing) {
1689fd4e5da5Sopenharmony_ci  const std::string body = R"(
1690fd4e5da5Sopenharmony_ciOpCapability PhysicalStorageBufferAddresses
1691fd4e5da5Sopenharmony_ciOpCapability Int64
1692fd4e5da5Sopenharmony_ciOpCapability Shader
1693fd4e5da5Sopenharmony_ciOpExtension "SPV_EXT_physical_storage_buffer"
1694fd4e5da5Sopenharmony_ciOpMemoryModel PhysicalStorageBuffer64 GLSL450
1695fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main"
1696fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
1697fd4e5da5Sopenharmony_ciOpDecorate %val1 AliasedPointer
1698fd4e5da5Sopenharmony_ci%uint64 = OpTypeInt 64 0
1699fd4e5da5Sopenharmony_ci%ptr = OpTypePointer PhysicalStorageBuffer %uint64
1700fd4e5da5Sopenharmony_ci%pptr_f = OpTypePointer Function %ptr
1701fd4e5da5Sopenharmony_ci%void = OpTypeVoid
1702fd4e5da5Sopenharmony_ci%voidfn = OpTypeFunction %void
1703fd4e5da5Sopenharmony_ci%main = OpFunction %void None %voidfn
1704fd4e5da5Sopenharmony_ci%entry = OpLabel
1705fd4e5da5Sopenharmony_ci%val1 = OpVariable %pptr_f Function
1706fd4e5da5Sopenharmony_ci%val2 = OpLoad %ptr %val1
1707fd4e5da5Sopenharmony_ci%val3 = OpLoad %uint64 %val2
1708fd4e5da5Sopenharmony_ciOpReturn
1709fd4e5da5Sopenharmony_ciOpFunctionEnd
1710fd4e5da5Sopenharmony_ci)";
1711fd4e5da5Sopenharmony_ci
1712fd4e5da5Sopenharmony_ci  CompileSuccessfully(body.c_str(), SPV_ENV_VULKAN_1_2);
1713fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_2));
1714fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
1715fd4e5da5Sopenharmony_ci              AnyVUID("VUID-StandaloneSpirv-PhysicalStorageBuffer64-04708"));
1716fd4e5da5Sopenharmony_ci  EXPECT_THAT(
1717fd4e5da5Sopenharmony_ci      getDiagnosticString(),
1718fd4e5da5Sopenharmony_ci      HasSubstr("Memory accesses with PhysicalStorageBuffer must use Aligned"));
1719fd4e5da5Sopenharmony_ci}
1720fd4e5da5Sopenharmony_ci
1721fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, PSBLoadAlignedMissingWithOtherOperand) {
1722fd4e5da5Sopenharmony_ci  const std::string body = R"(
1723fd4e5da5Sopenharmony_ciOpCapability PhysicalStorageBufferAddresses
1724fd4e5da5Sopenharmony_ciOpCapability Int64
1725fd4e5da5Sopenharmony_ciOpCapability Shader
1726fd4e5da5Sopenharmony_ciOpExtension "SPV_EXT_physical_storage_buffer"
1727fd4e5da5Sopenharmony_ciOpMemoryModel PhysicalStorageBuffer64 GLSL450
1728fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main"
1729fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
1730fd4e5da5Sopenharmony_ciOpDecorate %val1 AliasedPointer
1731fd4e5da5Sopenharmony_ci%uint64 = OpTypeInt 64 0
1732fd4e5da5Sopenharmony_ci%ptr = OpTypePointer PhysicalStorageBuffer %uint64
1733fd4e5da5Sopenharmony_ci%pptr_f = OpTypePointer Function %ptr
1734fd4e5da5Sopenharmony_ci%void = OpTypeVoid
1735fd4e5da5Sopenharmony_ci%voidfn = OpTypeFunction %void
1736fd4e5da5Sopenharmony_ci%main = OpFunction %void None %voidfn
1737fd4e5da5Sopenharmony_ci%entry = OpLabel
1738fd4e5da5Sopenharmony_ci%val1 = OpVariable %pptr_f Function
1739fd4e5da5Sopenharmony_ci%val2 = OpLoad %ptr %val1
1740fd4e5da5Sopenharmony_ci%val3 = OpLoad %uint64 %val2 Volatile
1741fd4e5da5Sopenharmony_ciOpReturn
1742fd4e5da5Sopenharmony_ciOpFunctionEnd
1743fd4e5da5Sopenharmony_ci)";
1744fd4e5da5Sopenharmony_ci
1745fd4e5da5Sopenharmony_ci  CompileSuccessfully(body.c_str(), SPV_ENV_VULKAN_1_2);
1746fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_2));
1747fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
1748fd4e5da5Sopenharmony_ci              AnyVUID("VUID-StandaloneSpirv-PhysicalStorageBuffer64-04708"));
1749fd4e5da5Sopenharmony_ci  EXPECT_THAT(
1750fd4e5da5Sopenharmony_ci      getDiagnosticString(),
1751fd4e5da5Sopenharmony_ci      HasSubstr("Memory accesses with PhysicalStorageBuffer must use Aligned"));
1752fd4e5da5Sopenharmony_ci}
1753fd4e5da5Sopenharmony_ci
1754fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, PSBStoreAlignedSuccess) {
1755fd4e5da5Sopenharmony_ci  const std::string body = R"(
1756fd4e5da5Sopenharmony_ciOpCapability PhysicalStorageBufferAddresses
1757fd4e5da5Sopenharmony_ciOpCapability Int64
1758fd4e5da5Sopenharmony_ciOpCapability Shader
1759fd4e5da5Sopenharmony_ciOpExtension "SPV_EXT_physical_storage_buffer"
1760fd4e5da5Sopenharmony_ciOpMemoryModel PhysicalStorageBuffer64 GLSL450
1761fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main"
1762fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
1763fd4e5da5Sopenharmony_ciOpDecorate %val1 AliasedPointer
1764fd4e5da5Sopenharmony_ci%uint64 = OpTypeInt 64 0
1765fd4e5da5Sopenharmony_ci%u64_1 = OpConstant %uint64 1
1766fd4e5da5Sopenharmony_ci%ptr = OpTypePointer PhysicalStorageBuffer %uint64
1767fd4e5da5Sopenharmony_ci%pptr_f = OpTypePointer Function %ptr
1768fd4e5da5Sopenharmony_ci%void = OpTypeVoid
1769fd4e5da5Sopenharmony_ci%voidfn = OpTypeFunction %void
1770fd4e5da5Sopenharmony_ci%main = OpFunction %void None %voidfn
1771fd4e5da5Sopenharmony_ci%entry = OpLabel
1772fd4e5da5Sopenharmony_ci%val1 = OpVariable %pptr_f Function
1773fd4e5da5Sopenharmony_ci%val2 = OpLoad %ptr %val1
1774fd4e5da5Sopenharmony_ciOpStore %val2 %u64_1 Aligned 8
1775fd4e5da5Sopenharmony_ciOpReturn
1776fd4e5da5Sopenharmony_ciOpFunctionEnd
1777fd4e5da5Sopenharmony_ci)";
1778fd4e5da5Sopenharmony_ci
1779fd4e5da5Sopenharmony_ci  CompileSuccessfully(body.c_str(), SPV_ENV_VULKAN_1_2);
1780fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
1781fd4e5da5Sopenharmony_ci}
1782fd4e5da5Sopenharmony_ci
1783fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, PSBStoreAlignedMissing) {
1784fd4e5da5Sopenharmony_ci  const std::string body = R"(
1785fd4e5da5Sopenharmony_ciOpCapability PhysicalStorageBufferAddresses
1786fd4e5da5Sopenharmony_ciOpCapability Int64
1787fd4e5da5Sopenharmony_ciOpCapability Shader
1788fd4e5da5Sopenharmony_ciOpExtension "SPV_EXT_physical_storage_buffer"
1789fd4e5da5Sopenharmony_ciOpMemoryModel PhysicalStorageBuffer64 GLSL450
1790fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main"
1791fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
1792fd4e5da5Sopenharmony_ciOpDecorate %val1 AliasedPointer
1793fd4e5da5Sopenharmony_ci%uint64 = OpTypeInt 64 0
1794fd4e5da5Sopenharmony_ci%u64_1 = OpConstant %uint64 1
1795fd4e5da5Sopenharmony_ci%ptr = OpTypePointer PhysicalStorageBuffer %uint64
1796fd4e5da5Sopenharmony_ci%pptr_f = OpTypePointer Function %ptr
1797fd4e5da5Sopenharmony_ci%void = OpTypeVoid
1798fd4e5da5Sopenharmony_ci%voidfn = OpTypeFunction %void
1799fd4e5da5Sopenharmony_ci%main = OpFunction %void None %voidfn
1800fd4e5da5Sopenharmony_ci%entry = OpLabel
1801fd4e5da5Sopenharmony_ci%val1 = OpVariable %pptr_f Function
1802fd4e5da5Sopenharmony_ci%val2 = OpLoad %ptr %val1
1803fd4e5da5Sopenharmony_ciOpStore %val2 %u64_1 None
1804fd4e5da5Sopenharmony_ciOpReturn
1805fd4e5da5Sopenharmony_ciOpFunctionEnd
1806fd4e5da5Sopenharmony_ci)";
1807fd4e5da5Sopenharmony_ci
1808fd4e5da5Sopenharmony_ci  CompileSuccessfully(body.c_str(), SPV_ENV_VULKAN_1_2);
1809fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_2));
1810fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
1811fd4e5da5Sopenharmony_ci              AnyVUID("VUID-StandaloneSpirv-PhysicalStorageBuffer64-04708"));
1812fd4e5da5Sopenharmony_ci  EXPECT_THAT(
1813fd4e5da5Sopenharmony_ci      getDiagnosticString(),
1814fd4e5da5Sopenharmony_ci      HasSubstr("Memory accesses with PhysicalStorageBuffer must use Aligned"));
1815fd4e5da5Sopenharmony_ci}
1816fd4e5da5Sopenharmony_ci
1817fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, PSBCopyMemoryAlignedSuccess) {
1818fd4e5da5Sopenharmony_ci  const std::string body = R"(
1819fd4e5da5Sopenharmony_ciOpCapability PhysicalStorageBufferAddresses
1820fd4e5da5Sopenharmony_ciOpCapability Int64
1821fd4e5da5Sopenharmony_ciOpCapability Shader
1822fd4e5da5Sopenharmony_ciOpExtension "SPV_EXT_physical_storage_buffer"
1823fd4e5da5Sopenharmony_ciOpMemoryModel PhysicalStorageBuffer64 GLSL450
1824fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main"
1825fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
1826fd4e5da5Sopenharmony_ciOpDecorate %val1 AliasedPointer
1827fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
1828fd4e5da5Sopenharmony_ci%uint64 = OpTypeInt 64 0
1829fd4e5da5Sopenharmony_ci%u64_1 = OpConstant %uint64 1
1830fd4e5da5Sopenharmony_ci%ptr = OpTypePointer PhysicalStorageBuffer %uint64
1831fd4e5da5Sopenharmony_ci%pptr_f = OpTypePointer Function %ptr
1832fd4e5da5Sopenharmony_ci%void = OpTypeVoid
1833fd4e5da5Sopenharmony_ci%voidfn = OpTypeFunction %void
1834fd4e5da5Sopenharmony_ci%main = OpFunction %void None %voidfn
1835fd4e5da5Sopenharmony_ci%entry = OpLabel
1836fd4e5da5Sopenharmony_ci%val1 = OpVariable %pptr_f Function
1837fd4e5da5Sopenharmony_ci%val2 = OpLoad %ptr %val1
1838fd4e5da5Sopenharmony_ci%val3 = OpLoad %ptr %val1
1839fd4e5da5Sopenharmony_ciOpCopyMemory %val2 %val3 Aligned 4
1840fd4e5da5Sopenharmony_ciOpCopyMemory %val3 %val2 Aligned 4 Aligned 4
1841fd4e5da5Sopenharmony_ciOpReturn
1842fd4e5da5Sopenharmony_ciOpFunctionEnd
1843fd4e5da5Sopenharmony_ci)";
1844fd4e5da5Sopenharmony_ci
1845fd4e5da5Sopenharmony_ci  CompileSuccessfully(body.c_str(), SPV_ENV_VULKAN_1_2);
1846fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
1847fd4e5da5Sopenharmony_ci}
1848fd4e5da5Sopenharmony_ci
1849fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, PSBCopyMemoryAlignedMissingTarget) {
1850fd4e5da5Sopenharmony_ci  const std::string body = R"(
1851fd4e5da5Sopenharmony_ciOpCapability PhysicalStorageBufferAddresses
1852fd4e5da5Sopenharmony_ciOpCapability Int64
1853fd4e5da5Sopenharmony_ciOpCapability Shader
1854fd4e5da5Sopenharmony_ciOpExtension "SPV_EXT_physical_storage_buffer"
1855fd4e5da5Sopenharmony_ciOpMemoryModel PhysicalStorageBuffer64 GLSL450
1856fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main"
1857fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
1858fd4e5da5Sopenharmony_ciOpDecorate %val1 AliasedPointer
1859fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
1860fd4e5da5Sopenharmony_ci%uint64 = OpTypeInt 64 0
1861fd4e5da5Sopenharmony_ci%u64_1 = OpConstant %uint64 1
1862fd4e5da5Sopenharmony_ci%ptr = OpTypePointer PhysicalStorageBuffer %uint64
1863fd4e5da5Sopenharmony_ci%pptr_f = OpTypePointer Function %ptr
1864fd4e5da5Sopenharmony_ci%void = OpTypeVoid
1865fd4e5da5Sopenharmony_ci%voidfn = OpTypeFunction %void
1866fd4e5da5Sopenharmony_ci%main = OpFunction %void None %voidfn
1867fd4e5da5Sopenharmony_ci%entry = OpLabel
1868fd4e5da5Sopenharmony_ci%val1 = OpVariable %pptr_f Function
1869fd4e5da5Sopenharmony_ci%val2 = OpLoad %ptr %val1
1870fd4e5da5Sopenharmony_ci%val3 = OpLoad %ptr %val1
1871fd4e5da5Sopenharmony_ciOpCopyMemory %val2 %val3 Volatile Aligned 4
1872fd4e5da5Sopenharmony_ciOpReturn
1873fd4e5da5Sopenharmony_ciOpFunctionEnd
1874fd4e5da5Sopenharmony_ci)";
1875fd4e5da5Sopenharmony_ci
1876fd4e5da5Sopenharmony_ci  CompileSuccessfully(body.c_str(), SPV_ENV_VULKAN_1_2);
1877fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_2));
1878fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
1879fd4e5da5Sopenharmony_ci              AnyVUID("VUID-StandaloneSpirv-PhysicalStorageBuffer64-04708"));
1880fd4e5da5Sopenharmony_ci  EXPECT_THAT(
1881fd4e5da5Sopenharmony_ci      getDiagnosticString(),
1882fd4e5da5Sopenharmony_ci      HasSubstr("Memory accesses with PhysicalStorageBuffer must use Aligned"));
1883fd4e5da5Sopenharmony_ci}
1884fd4e5da5Sopenharmony_ci
1885fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, PSBCopyMemoryAlignedMissingSource) {
1886fd4e5da5Sopenharmony_ci  const std::string body = R"(
1887fd4e5da5Sopenharmony_ciOpCapability PhysicalStorageBufferAddresses
1888fd4e5da5Sopenharmony_ciOpCapability Int64
1889fd4e5da5Sopenharmony_ciOpCapability Shader
1890fd4e5da5Sopenharmony_ciOpExtension "SPV_EXT_physical_storage_buffer"
1891fd4e5da5Sopenharmony_ciOpMemoryModel PhysicalStorageBuffer64 GLSL450
1892fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main"
1893fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
1894fd4e5da5Sopenharmony_ciOpDecorate %val1 AliasedPointer
1895fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
1896fd4e5da5Sopenharmony_ci%uint64 = OpTypeInt 64 0
1897fd4e5da5Sopenharmony_ci%u64_1 = OpConstant %uint64 1
1898fd4e5da5Sopenharmony_ci%ptr = OpTypePointer PhysicalStorageBuffer %uint64
1899fd4e5da5Sopenharmony_ci%pptr_f = OpTypePointer Function %ptr
1900fd4e5da5Sopenharmony_ci%void = OpTypeVoid
1901fd4e5da5Sopenharmony_ci%voidfn = OpTypeFunction %void
1902fd4e5da5Sopenharmony_ci%main = OpFunction %void None %voidfn
1903fd4e5da5Sopenharmony_ci%entry = OpLabel
1904fd4e5da5Sopenharmony_ci%val1 = OpVariable %pptr_f Function
1905fd4e5da5Sopenharmony_ci%val2 = OpLoad %ptr %val1
1906fd4e5da5Sopenharmony_ci%val3 = OpLoad %ptr %val1
1907fd4e5da5Sopenharmony_ciOpCopyMemory %val2 %val3 Aligned 4 Volatile
1908fd4e5da5Sopenharmony_ciOpReturn
1909fd4e5da5Sopenharmony_ciOpFunctionEnd
1910fd4e5da5Sopenharmony_ci)";
1911fd4e5da5Sopenharmony_ci
1912fd4e5da5Sopenharmony_ci  CompileSuccessfully(body.c_str(), SPV_ENV_VULKAN_1_2);
1913fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_2));
1914fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
1915fd4e5da5Sopenharmony_ci              AnyVUID("VUID-StandaloneSpirv-PhysicalStorageBuffer64-04708"));
1916fd4e5da5Sopenharmony_ci  EXPECT_THAT(
1917fd4e5da5Sopenharmony_ci      getDiagnosticString(),
1918fd4e5da5Sopenharmony_ci      HasSubstr("Memory accesses with PhysicalStorageBuffer must use Aligned"));
1919fd4e5da5Sopenharmony_ci}
1920fd4e5da5Sopenharmony_ci
1921fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, PSBCopyMemoryAlignedMissingBoth) {
1922fd4e5da5Sopenharmony_ci  const std::string body = R"(
1923fd4e5da5Sopenharmony_ciOpCapability PhysicalStorageBufferAddresses
1924fd4e5da5Sopenharmony_ciOpCapability Int64
1925fd4e5da5Sopenharmony_ciOpCapability Shader
1926fd4e5da5Sopenharmony_ciOpExtension "SPV_EXT_physical_storage_buffer"
1927fd4e5da5Sopenharmony_ciOpMemoryModel PhysicalStorageBuffer64 GLSL450
1928fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main"
1929fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
1930fd4e5da5Sopenharmony_ciOpDecorate %val1 AliasedPointer
1931fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
1932fd4e5da5Sopenharmony_ci%uint64 = OpTypeInt 64 0
1933fd4e5da5Sopenharmony_ci%u64_1 = OpConstant %uint64 1
1934fd4e5da5Sopenharmony_ci%ptr = OpTypePointer PhysicalStorageBuffer %uint64
1935fd4e5da5Sopenharmony_ci%pptr_f = OpTypePointer Function %ptr
1936fd4e5da5Sopenharmony_ci%void = OpTypeVoid
1937fd4e5da5Sopenharmony_ci%voidfn = OpTypeFunction %void
1938fd4e5da5Sopenharmony_ci%main = OpFunction %void None %voidfn
1939fd4e5da5Sopenharmony_ci%entry = OpLabel
1940fd4e5da5Sopenharmony_ci%val1 = OpVariable %pptr_f Function
1941fd4e5da5Sopenharmony_ci%val2 = OpLoad %ptr %val1
1942fd4e5da5Sopenharmony_ci%val3 = OpLoad %ptr %val1
1943fd4e5da5Sopenharmony_ciOpCopyMemory %val2 %val3 Volatile
1944fd4e5da5Sopenharmony_ciOpReturn
1945fd4e5da5Sopenharmony_ciOpFunctionEnd
1946fd4e5da5Sopenharmony_ci)";
1947fd4e5da5Sopenharmony_ci
1948fd4e5da5Sopenharmony_ci  CompileSuccessfully(body.c_str(), SPV_ENV_VULKAN_1_2);
1949fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_2));
1950fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
1951fd4e5da5Sopenharmony_ci              AnyVUID("VUID-StandaloneSpirv-PhysicalStorageBuffer64-04708"));
1952fd4e5da5Sopenharmony_ci  EXPECT_THAT(
1953fd4e5da5Sopenharmony_ci      getDiagnosticString(),
1954fd4e5da5Sopenharmony_ci      HasSubstr("Memory accesses with PhysicalStorageBuffer must use Aligned"));
1955fd4e5da5Sopenharmony_ci}
1956fd4e5da5Sopenharmony_ci
1957fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, PSBVariable) {
1958fd4e5da5Sopenharmony_ci  const std::string body = R"(
1959fd4e5da5Sopenharmony_ciOpCapability PhysicalStorageBufferAddresses
1960fd4e5da5Sopenharmony_ciOpCapability Int64
1961fd4e5da5Sopenharmony_ciOpCapability Shader
1962fd4e5da5Sopenharmony_ciOpExtension "SPV_EXT_physical_storage_buffer"
1963fd4e5da5Sopenharmony_ciOpMemoryModel PhysicalStorageBuffer64 GLSL450
1964fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main"
1965fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
1966fd4e5da5Sopenharmony_ciOpDecorate %val1 AliasedPointer
1967fd4e5da5Sopenharmony_ci%uint64 = OpTypeInt 64 0
1968fd4e5da5Sopenharmony_ci%ptr = OpTypePointer PhysicalStorageBuffer %uint64
1969fd4e5da5Sopenharmony_ci%val1 = OpVariable %ptr PhysicalStorageBuffer
1970fd4e5da5Sopenharmony_ci%void = OpTypeVoid
1971fd4e5da5Sopenharmony_ci%voidfn = OpTypeFunction %void
1972fd4e5da5Sopenharmony_ci%main = OpFunction %void None %voidfn
1973fd4e5da5Sopenharmony_ci%entry = OpLabel
1974fd4e5da5Sopenharmony_ciOpReturn
1975fd4e5da5Sopenharmony_ciOpFunctionEnd
1976fd4e5da5Sopenharmony_ci)";
1977fd4e5da5Sopenharmony_ci
1978fd4e5da5Sopenharmony_ci  CompileSuccessfully(body);
1979fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
1980fd4e5da5Sopenharmony_ci  EXPECT_THAT(
1981fd4e5da5Sopenharmony_ci      getDiagnosticString(),
1982fd4e5da5Sopenharmony_ci      HasSubstr("PhysicalStorageBuffer must not be used with OpVariable"));
1983fd4e5da5Sopenharmony_ci}
1984fd4e5da5Sopenharmony_ci
1985fd4e5da5Sopenharmony_cistd::string GenCoopMatLoadStoreShader(const std::string& storeMemoryAccess,
1986fd4e5da5Sopenharmony_ci                                      const std::string& loadMemoryAccess) {
1987fd4e5da5Sopenharmony_ci  std::string s = R"(
1988fd4e5da5Sopenharmony_ciOpCapability Shader
1989fd4e5da5Sopenharmony_ciOpCapability GroupNonUniform
1990fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR
1991fd4e5da5Sopenharmony_ciOpCapability CooperativeMatrixNV
1992fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model"
1993fd4e5da5Sopenharmony_ciOpExtension "SPV_NV_cooperative_matrix"
1994fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450"
1995fd4e5da5Sopenharmony_ciOpMemoryModel Logical VulkanKHR
1996fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %4 "main" %11 %21
1997fd4e5da5Sopenharmony_ciOpExecutionMode %4 LocalSize 1 1 1
1998fd4e5da5Sopenharmony_ciOpDecorate %11 BuiltIn SubgroupId
1999fd4e5da5Sopenharmony_ciOpDecorate %21 BuiltIn WorkgroupId
2000fd4e5da5Sopenharmony_ciOpDecorate %74 ArrayStride 4
2001fd4e5da5Sopenharmony_ciOpMemberDecorate %75 0 Offset 0
2002fd4e5da5Sopenharmony_ciOpDecorate %75 Block
2003fd4e5da5Sopenharmony_ciOpDecorate %77 DescriptorSet 0
2004fd4e5da5Sopenharmony_ciOpDecorate %77 Binding 0
2005fd4e5da5Sopenharmony_ciOpDecorate %92 ArrayStride 4
2006fd4e5da5Sopenharmony_ciOpMemberDecorate %93 0 Offset 0
2007fd4e5da5Sopenharmony_ciOpDecorate %93 Block
2008fd4e5da5Sopenharmony_ciOpDecorate %95 DescriptorSet 0
2009fd4e5da5Sopenharmony_ciOpDecorate %95 Binding 1
2010fd4e5da5Sopenharmony_ciOpDecorate %102 ArrayStride 4
2011fd4e5da5Sopenharmony_ciOpMemberDecorate %103 0 Offset 0
2012fd4e5da5Sopenharmony_ciOpDecorate %103 Block
2013fd4e5da5Sopenharmony_ciOpDecorate %105 DescriptorSet 0
2014fd4e5da5Sopenharmony_ciOpDecorate %105 Binding 2
2015fd4e5da5Sopenharmony_ciOpDecorate %117 ArrayStride 4
2016fd4e5da5Sopenharmony_ciOpMemberDecorate %118 0 Offset 0
2017fd4e5da5Sopenharmony_ciOpDecorate %118 Block
2018fd4e5da5Sopenharmony_ciOpDecorate %120 DescriptorSet 0
2019fd4e5da5Sopenharmony_ciOpDecorate %120 Binding 3
2020fd4e5da5Sopenharmony_ciOpDecorate %123 SpecId 2
2021fd4e5da5Sopenharmony_ciOpDecorate %124 SpecId 3
2022fd4e5da5Sopenharmony_ciOpDecorate %125 SpecId 4
2023fd4e5da5Sopenharmony_ciOpDecorate %126 SpecId 5
2024fd4e5da5Sopenharmony_ciOpDecorate %127 SpecId 0
2025fd4e5da5Sopenharmony_ciOpDecorate %128 SpecId 1
2026fd4e5da5Sopenharmony_ciOpDecorate %129 BuiltIn WorkgroupSize
2027fd4e5da5Sopenharmony_ci%2 = OpTypeVoid
2028fd4e5da5Sopenharmony_ci%3 = OpTypeFunction %2
2029fd4e5da5Sopenharmony_ci%6 = OpTypeInt 32 0
2030fd4e5da5Sopenharmony_ci%7 = OpTypeVector %6 2
2031fd4e5da5Sopenharmony_ci%8 = OpTypePointer Function %7
2032fd4e5da5Sopenharmony_ci%10 = OpTypePointer Input %6
2033fd4e5da5Sopenharmony_ci%11 = OpVariable %10 Input
2034fd4e5da5Sopenharmony_ci%13 = OpConstant %6 2
2035fd4e5da5Sopenharmony_ci%19 = OpTypeVector %6 3
2036fd4e5da5Sopenharmony_ci%20 = OpTypePointer Input %19
2037fd4e5da5Sopenharmony_ci%21 = OpVariable %20 Input
2038fd4e5da5Sopenharmony_ci%27 = OpConstantComposite %7 %13 %13
2039fd4e5da5Sopenharmony_ci%31 = OpTypePointer Function %6
2040fd4e5da5Sopenharmony_ci%33 = OpConstant %6 1024
2041fd4e5da5Sopenharmony_ci%34 = OpConstant %6 1
2042fd4e5da5Sopenharmony_ci%38 = OpConstant %6 8
2043fd4e5da5Sopenharmony_ci%39 = OpConstant %6 0
2044fd4e5da5Sopenharmony_ci%68 = OpTypeFloat 32
2045fd4e5da5Sopenharmony_ci%69 = OpConstant %6 16
2046fd4e5da5Sopenharmony_ci%70 = OpConstant %6 3
2047fd4e5da5Sopenharmony_ci%71 = OpTypeCooperativeMatrixNV %68 %70 %69 %38
2048fd4e5da5Sopenharmony_ci%72 = OpTypePointer Function %71
2049fd4e5da5Sopenharmony_ci%74 = OpTypeRuntimeArray %68
2050fd4e5da5Sopenharmony_ci%75 = OpTypeStruct %74
2051fd4e5da5Sopenharmony_ci%76 = OpTypePointer StorageBuffer %75
2052fd4e5da5Sopenharmony_ci%77 = OpVariable %76 StorageBuffer
2053fd4e5da5Sopenharmony_ci%78 = OpTypeInt 32 1
2054fd4e5da5Sopenharmony_ci%79 = OpConstant %78 0
2055fd4e5da5Sopenharmony_ci%81 = OpConstant %6 5
2056fd4e5da5Sopenharmony_ci%82 = OpTypePointer StorageBuffer %68
2057fd4e5da5Sopenharmony_ci%84 = OpConstant %6 64
2058fd4e5da5Sopenharmony_ci%85 = OpTypeBool
2059fd4e5da5Sopenharmony_ci%86 = OpConstantFalse %85
2060fd4e5da5Sopenharmony_ci%88 = OpTypePointer Private %71
2061fd4e5da5Sopenharmony_ci%89 = OpVariable %88 Private
2062fd4e5da5Sopenharmony_ci%92 = OpTypeRuntimeArray %68
2063fd4e5da5Sopenharmony_ci%93 = OpTypeStruct %92
2064fd4e5da5Sopenharmony_ci%94 = OpTypePointer StorageBuffer %93
2065fd4e5da5Sopenharmony_ci%95 = OpVariable %94 StorageBuffer
2066fd4e5da5Sopenharmony_ci%99 = OpVariable %88 Private
2067fd4e5da5Sopenharmony_ci%102 = OpTypeRuntimeArray %68
2068fd4e5da5Sopenharmony_ci%103 = OpTypeStruct %102
2069fd4e5da5Sopenharmony_ci%104 = OpTypePointer StorageBuffer %103
2070fd4e5da5Sopenharmony_ci%105 = OpVariable %104 StorageBuffer
2071fd4e5da5Sopenharmony_ci%109 = OpVariable %88 Private
2072fd4e5da5Sopenharmony_ci%111 = OpVariable %88 Private
2073fd4e5da5Sopenharmony_ci%112 = OpSpecConstantOp %6 CooperativeMatrixLengthNV %71
2074fd4e5da5Sopenharmony_ci%113 = OpSpecConstantOp %78 IAdd %112 %79
2075fd4e5da5Sopenharmony_ci%117 = OpTypeRuntimeArray %68
2076fd4e5da5Sopenharmony_ci%118 = OpTypeStruct %117
2077fd4e5da5Sopenharmony_ci%119 = OpTypePointer StorageBuffer %118
2078fd4e5da5Sopenharmony_ci%120 = OpVariable %119 StorageBuffer
2079fd4e5da5Sopenharmony_ci%123 = OpSpecConstant %78 1
2080fd4e5da5Sopenharmony_ci%124 = OpSpecConstant %78 1
2081fd4e5da5Sopenharmony_ci%125 = OpSpecConstant %78 1
2082fd4e5da5Sopenharmony_ci%126 = OpSpecConstant %78 1
2083fd4e5da5Sopenharmony_ci%127 = OpSpecConstant %6 1
2084fd4e5da5Sopenharmony_ci%128 = OpSpecConstant %6 1
2085fd4e5da5Sopenharmony_ci%129 = OpSpecConstantComposite %19 %127 %128 %34
2086fd4e5da5Sopenharmony_ci%4 = OpFunction %2 None %3
2087fd4e5da5Sopenharmony_ci%5 = OpLabel
2088fd4e5da5Sopenharmony_ci%9 = OpVariable %8 Function
2089fd4e5da5Sopenharmony_ci%18 = OpVariable %8 Function
2090fd4e5da5Sopenharmony_ci%32 = OpVariable %31 Function
2091fd4e5da5Sopenharmony_ci%44 = OpVariable %31 Function
2092fd4e5da5Sopenharmony_ci%52 = OpVariable %31 Function
2093fd4e5da5Sopenharmony_ci%60 = OpVariable %31 Function
2094fd4e5da5Sopenharmony_ci%73 = OpVariable %72 Function
2095fd4e5da5Sopenharmony_ci%91 = OpVariable %72 Function
2096fd4e5da5Sopenharmony_ci%101 = OpVariable %72 Function
2097fd4e5da5Sopenharmony_ci%12 = OpLoad %6 %11
2098fd4e5da5Sopenharmony_ci%14 = OpUMod %6 %12 %13
2099fd4e5da5Sopenharmony_ci%15 = OpLoad %6 %11
2100fd4e5da5Sopenharmony_ci%16 = OpUDiv %6 %15 %13
2101fd4e5da5Sopenharmony_ci%17 = OpCompositeConstruct %7 %14 %16
2102fd4e5da5Sopenharmony_ciOpStore %9 %17
2103fd4e5da5Sopenharmony_ci%22 = OpLoad %19 %21
2104fd4e5da5Sopenharmony_ci%23 = OpVectorShuffle %7 %22 %22 0 1
2105fd4e5da5Sopenharmony_ci%24 = OpCompositeExtract %6 %23 0
2106fd4e5da5Sopenharmony_ci%25 = OpCompositeExtract %6 %23 1
2107fd4e5da5Sopenharmony_ci%26 = OpCompositeConstruct %7 %24 %25
2108fd4e5da5Sopenharmony_ci%28 = OpIMul %7 %26 %27
2109fd4e5da5Sopenharmony_ci%29 = OpLoad %7 %9
2110fd4e5da5Sopenharmony_ci%30 = OpIAdd %7 %28 %29
2111fd4e5da5Sopenharmony_ciOpStore %18 %30
2112fd4e5da5Sopenharmony_ci%35 = OpAccessChain %31 %18 %34
2113fd4e5da5Sopenharmony_ci%36 = OpLoad %6 %35
2114fd4e5da5Sopenharmony_ci%37 = OpIMul %6 %33 %36
2115fd4e5da5Sopenharmony_ci%40 = OpAccessChain %31 %18 %39
2116fd4e5da5Sopenharmony_ci%41 = OpLoad %6 %40
2117fd4e5da5Sopenharmony_ci%42 = OpIMul %6 %38 %41
2118fd4e5da5Sopenharmony_ci%43 = OpIAdd %6 %37 %42
2119fd4e5da5Sopenharmony_ciOpStore %32 %43
2120fd4e5da5Sopenharmony_ci%45 = OpAccessChain %31 %18 %34
2121fd4e5da5Sopenharmony_ci%46 = OpLoad %6 %45
2122fd4e5da5Sopenharmony_ci%47 = OpIMul %6 %33 %46
2123fd4e5da5Sopenharmony_ci%48 = OpAccessChain %31 %18 %39
2124fd4e5da5Sopenharmony_ci%49 = OpLoad %6 %48
2125fd4e5da5Sopenharmony_ci%50 = OpIMul %6 %38 %49
2126fd4e5da5Sopenharmony_ci%51 = OpIAdd %6 %47 %50
2127fd4e5da5Sopenharmony_ciOpStore %44 %51
2128fd4e5da5Sopenharmony_ci%53 = OpAccessChain %31 %18 %34
2129fd4e5da5Sopenharmony_ci%54 = OpLoad %6 %53
2130fd4e5da5Sopenharmony_ci%55 = OpIMul %6 %33 %54
2131fd4e5da5Sopenharmony_ci%56 = OpAccessChain %31 %18 %39
2132fd4e5da5Sopenharmony_ci%57 = OpLoad %6 %56
2133fd4e5da5Sopenharmony_ci%58 = OpIMul %6 %38 %57
2134fd4e5da5Sopenharmony_ci%59 = OpIAdd %6 %55 %58
2135fd4e5da5Sopenharmony_ciOpStore %52 %59
2136fd4e5da5Sopenharmony_ci%61 = OpAccessChain %31 %18 %34
2137fd4e5da5Sopenharmony_ci%62 = OpLoad %6 %61
2138fd4e5da5Sopenharmony_ci%63 = OpIMul %6 %33 %62
2139fd4e5da5Sopenharmony_ci%64 = OpAccessChain %31 %18 %39
2140fd4e5da5Sopenharmony_ci%65 = OpLoad %6 %64
2141fd4e5da5Sopenharmony_ci%66 = OpIMul %6 %38 %65
2142fd4e5da5Sopenharmony_ci%67 = OpIAdd %6 %63 %66
2143fd4e5da5Sopenharmony_ciOpStore %60 %67
2144fd4e5da5Sopenharmony_ci%80 = OpLoad %6 %32
2145fd4e5da5Sopenharmony_ci%83 = OpAccessChain %82 %77 %79 %80
2146fd4e5da5Sopenharmony_ci%87 = OpCooperativeMatrixLoadNV %71 %83 %84 %86 )" +
2147fd4e5da5Sopenharmony_ci                  loadMemoryAccess + R"( %81
2148fd4e5da5Sopenharmony_ciOpStore %73 %87
2149fd4e5da5Sopenharmony_ci%90 = OpLoad %71 %73
2150fd4e5da5Sopenharmony_ciOpStore %89 %90
2151fd4e5da5Sopenharmony_ci%96 = OpLoad %6 %44
2152fd4e5da5Sopenharmony_ci%97 = OpAccessChain %82 %95 %79 %96
2153fd4e5da5Sopenharmony_ci%98 = OpCooperativeMatrixLoadNV %71 %97 %84 %86 MakePointerVisibleKHR|NonPrivatePointerKHR %81
2154fd4e5da5Sopenharmony_ciOpStore %91 %98
2155fd4e5da5Sopenharmony_ci%100 = OpLoad %71 %91
2156fd4e5da5Sopenharmony_ciOpStore %99 %100
2157fd4e5da5Sopenharmony_ci%106 = OpLoad %6 %52
2158fd4e5da5Sopenharmony_ci%107 = OpAccessChain %82 %105 %79 %106
2159fd4e5da5Sopenharmony_ci%108 = OpCooperativeMatrixLoadNV %71 %107 %84 %86 MakePointerVisibleKHR|NonPrivatePointerKHR %81
2160fd4e5da5Sopenharmony_ciOpStore %101 %108
2161fd4e5da5Sopenharmony_ci%110 = OpLoad %71 %101
2162fd4e5da5Sopenharmony_ciOpStore %109 %110
2163fd4e5da5Sopenharmony_ci%114 = OpConvertSToF %68 %113
2164fd4e5da5Sopenharmony_ci%115 = OpCompositeConstruct %71 %114
2165fd4e5da5Sopenharmony_ciOpStore %111 %115
2166fd4e5da5Sopenharmony_ci%116 = OpLoad %71 %111
2167fd4e5da5Sopenharmony_ci%121 = OpLoad %6 %60
2168fd4e5da5Sopenharmony_ci%122 = OpAccessChain %82 %120 %79 %121
2169fd4e5da5Sopenharmony_ciOpCooperativeMatrixStoreNV %122 %116 %84 %86 )" + storeMemoryAccess + R"( %81
2170fd4e5da5Sopenharmony_ciOpReturn
2171fd4e5da5Sopenharmony_ciOpFunctionEnd
2172fd4e5da5Sopenharmony_ci)";
2173fd4e5da5Sopenharmony_ci
2174fd4e5da5Sopenharmony_ci  return s;
2175fd4e5da5Sopenharmony_ci}
2176fd4e5da5Sopenharmony_ci
2177fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, CoopMatLoadStoreSuccess) {
2178fd4e5da5Sopenharmony_ci  std::string spirv =
2179fd4e5da5Sopenharmony_ci      GenCoopMatLoadStoreShader("MakePointerAvailableKHR|NonPrivatePointerKHR",
2180fd4e5da5Sopenharmony_ci                                "MakePointerVisibleKHR|NonPrivatePointerKHR");
2181fd4e5da5Sopenharmony_ci
2182fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
2183fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
2184fd4e5da5Sopenharmony_ci}
2185fd4e5da5Sopenharmony_ci
2186fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, CoopMatStoreMemoryAccessFail) {
2187fd4e5da5Sopenharmony_ci  std::string spirv =
2188fd4e5da5Sopenharmony_ci      GenCoopMatLoadStoreShader("MakePointerVisibleKHR|NonPrivatePointerKHR",
2189fd4e5da5Sopenharmony_ci                                "MakePointerVisibleKHR|NonPrivatePointerKHR");
2190fd4e5da5Sopenharmony_ci
2191fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
2192fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
2193fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
2194fd4e5da5Sopenharmony_ci              HasSubstr("MakePointerVisibleKHR cannot be used with OpStore"));
2195fd4e5da5Sopenharmony_ci}
2196fd4e5da5Sopenharmony_ci
2197fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, CoopMatLoadMemoryAccessFail) {
2198fd4e5da5Sopenharmony_ci  std::string spirv =
2199fd4e5da5Sopenharmony_ci      GenCoopMatLoadStoreShader("MakePointerAvailableKHR|NonPrivatePointerKHR",
2200fd4e5da5Sopenharmony_ci                                "MakePointerAvailableKHR|NonPrivatePointerKHR");
2201fd4e5da5Sopenharmony_ci
2202fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
2203fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
2204fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
2205fd4e5da5Sopenharmony_ci              HasSubstr("MakePointerAvailableKHR cannot be used with OpLoad"));
2206fd4e5da5Sopenharmony_ci}
2207fd4e5da5Sopenharmony_ci
2208fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, CoopMatInvalidStorageClassFail) {
2209fd4e5da5Sopenharmony_ci  const std::string body =
2210fd4e5da5Sopenharmony_ci      R"(
2211fd4e5da5Sopenharmony_ciOpCapability Shader
2212fd4e5da5Sopenharmony_ciOpCapability Float16
2213fd4e5da5Sopenharmony_ciOpCapability CooperativeMatrixNV
2214fd4e5da5Sopenharmony_ciOpExtension "SPV_NV_cooperative_matrix"
2215fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
2216fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %main "main"
2217fd4e5da5Sopenharmony_ci%void = OpTypeVoid
2218fd4e5da5Sopenharmony_ci%func = OpTypeFunction %void
2219fd4e5da5Sopenharmony_ci%f16 = OpTypeFloat 16
2220fd4e5da5Sopenharmony_ci%u32 = OpTypeInt 32 0
2221fd4e5da5Sopenharmony_ci
2222fd4e5da5Sopenharmony_ci%u32_8 = OpConstant %u32 8
2223fd4e5da5Sopenharmony_ci%subgroup = OpConstant %u32 3
2224fd4e5da5Sopenharmony_ci
2225fd4e5da5Sopenharmony_ci%f16mat = OpTypeCooperativeMatrixNV %f16 %subgroup %u32_8 %u32_8
2226fd4e5da5Sopenharmony_ci
2227fd4e5da5Sopenharmony_ci%str = OpTypeStruct %f16mat
2228fd4e5da5Sopenharmony_ci%str_ptr = OpTypePointer Workgroup %str
2229fd4e5da5Sopenharmony_ci%sh = OpVariable %str_ptr Workgroup
2230fd4e5da5Sopenharmony_ci
2231fd4e5da5Sopenharmony_ci%main = OpFunction %void None %func
2232fd4e5da5Sopenharmony_ci%main_entry = OpLabel
2233fd4e5da5Sopenharmony_ci
2234fd4e5da5Sopenharmony_ciOpReturn
2235fd4e5da5Sopenharmony_ciOpFunctionEnd)";
2236fd4e5da5Sopenharmony_ci
2237fd4e5da5Sopenharmony_ci  CompileSuccessfully(body.c_str());
2238fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
2239fd4e5da5Sopenharmony_ci  EXPECT_THAT(
2240fd4e5da5Sopenharmony_ci      getDiagnosticString(),
2241fd4e5da5Sopenharmony_ci      HasSubstr(
2242fd4e5da5Sopenharmony_ci          "Cooperative matrix types (or types containing them) can only be "
2243fd4e5da5Sopenharmony_ci          "allocated in Function or Private storage classes or as function "
2244fd4e5da5Sopenharmony_ci          "parameters"));
2245fd4e5da5Sopenharmony_ci}
2246fd4e5da5Sopenharmony_ci
2247fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, CoopMatMatrixLengthResultTypeBad) {
2248fd4e5da5Sopenharmony_ci  const std::string body =
2249fd4e5da5Sopenharmony_ci      R"(
2250fd4e5da5Sopenharmony_ciOpCapability Shader
2251fd4e5da5Sopenharmony_ciOpCapability Float16
2252fd4e5da5Sopenharmony_ciOpCapability CooperativeMatrixNV
2253fd4e5da5Sopenharmony_ciOpExtension "SPV_NV_cooperative_matrix"
2254fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
2255fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %main "main"
2256fd4e5da5Sopenharmony_ci%void = OpTypeVoid
2257fd4e5da5Sopenharmony_ci%func = OpTypeFunction %void
2258fd4e5da5Sopenharmony_ci%f16 = OpTypeFloat 16
2259fd4e5da5Sopenharmony_ci%u32 = OpTypeInt 32 0
2260fd4e5da5Sopenharmony_ci%i32 = OpTypeInt 32 1
2261fd4e5da5Sopenharmony_ci
2262fd4e5da5Sopenharmony_ci%u32_8 = OpConstant %u32 8
2263fd4e5da5Sopenharmony_ci%subgroup = OpConstant %u32 3
2264fd4e5da5Sopenharmony_ci
2265fd4e5da5Sopenharmony_ci%f16mat = OpTypeCooperativeMatrixNV %f16 %subgroup %u32_8 %u32_8
2266fd4e5da5Sopenharmony_ci
2267fd4e5da5Sopenharmony_ci%main = OpFunction %void None %func
2268fd4e5da5Sopenharmony_ci%main_entry = OpLabel
2269fd4e5da5Sopenharmony_ci
2270fd4e5da5Sopenharmony_ci%1 = OpCooperativeMatrixLengthNV %i32 %f16mat
2271fd4e5da5Sopenharmony_ci
2272fd4e5da5Sopenharmony_ciOpReturn
2273fd4e5da5Sopenharmony_ciOpFunctionEnd)";
2274fd4e5da5Sopenharmony_ci
2275fd4e5da5Sopenharmony_ci  CompileSuccessfully(body.c_str());
2276fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
2277fd4e5da5Sopenharmony_ci  EXPECT_THAT(
2278fd4e5da5Sopenharmony_ci      getDiagnosticString(),
2279fd4e5da5Sopenharmony_ci      HasSubstr("The Result Type of OpCooperativeMatrixLengthNV <id> "
2280fd4e5da5Sopenharmony_ci                "'11[%11]' must be OpTypeInt with width 32 and signedness 0"));
2281fd4e5da5Sopenharmony_ci}
2282fd4e5da5Sopenharmony_ci
2283fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, CoopMatMatrixLengthOperandTypeBad) {
2284fd4e5da5Sopenharmony_ci  const std::string body =
2285fd4e5da5Sopenharmony_ci      R"(
2286fd4e5da5Sopenharmony_ciOpCapability Shader
2287fd4e5da5Sopenharmony_ciOpCapability Float16
2288fd4e5da5Sopenharmony_ciOpCapability CooperativeMatrixNV
2289fd4e5da5Sopenharmony_ciOpExtension "SPV_NV_cooperative_matrix"
2290fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
2291fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %main "main"
2292fd4e5da5Sopenharmony_ci%void = OpTypeVoid
2293fd4e5da5Sopenharmony_ci%func = OpTypeFunction %void
2294fd4e5da5Sopenharmony_ci%f16 = OpTypeFloat 16
2295fd4e5da5Sopenharmony_ci%u32 = OpTypeInt 32 0
2296fd4e5da5Sopenharmony_ci%i32 = OpTypeInt 32 1
2297fd4e5da5Sopenharmony_ci
2298fd4e5da5Sopenharmony_ci%u32_8 = OpConstant %u32 8
2299fd4e5da5Sopenharmony_ci%subgroup = OpConstant %u32 3
2300fd4e5da5Sopenharmony_ci
2301fd4e5da5Sopenharmony_ci%f16mat = OpTypeCooperativeMatrixNV %f16 %subgroup %u32_8 %u32_8
2302fd4e5da5Sopenharmony_ci
2303fd4e5da5Sopenharmony_ci%main = OpFunction %void None %func
2304fd4e5da5Sopenharmony_ci%main_entry = OpLabel
2305fd4e5da5Sopenharmony_ci
2306fd4e5da5Sopenharmony_ci%1 = OpCooperativeMatrixLengthNV %u32 %u32
2307fd4e5da5Sopenharmony_ci
2308fd4e5da5Sopenharmony_ciOpReturn
2309fd4e5da5Sopenharmony_ciOpFunctionEnd)";
2310fd4e5da5Sopenharmony_ci
2311fd4e5da5Sopenharmony_ci  CompileSuccessfully(body.c_str());
2312fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
2313fd4e5da5Sopenharmony_ci  EXPECT_THAT(
2314fd4e5da5Sopenharmony_ci      getDiagnosticString(),
2315fd4e5da5Sopenharmony_ci      HasSubstr("The type in OpCooperativeMatrixLengthNV <id> '5[%uint]' "
2316fd4e5da5Sopenharmony_ci                "must be OpTypeCooperativeMatrixNV"));
2317fd4e5da5Sopenharmony_ci}
2318fd4e5da5Sopenharmony_ci
2319fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, CoopMatMatrixLengthGood) {
2320fd4e5da5Sopenharmony_ci  const std::string body =
2321fd4e5da5Sopenharmony_ci      R"(
2322fd4e5da5Sopenharmony_ciOpCapability Shader
2323fd4e5da5Sopenharmony_ciOpCapability Float16
2324fd4e5da5Sopenharmony_ciOpCapability CooperativeMatrixNV
2325fd4e5da5Sopenharmony_ciOpExtension "SPV_NV_cooperative_matrix"
2326fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
2327fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %main "main"
2328fd4e5da5Sopenharmony_ci%void = OpTypeVoid
2329fd4e5da5Sopenharmony_ci%func = OpTypeFunction %void
2330fd4e5da5Sopenharmony_ci%f16 = OpTypeFloat 16
2331fd4e5da5Sopenharmony_ci%u32 = OpTypeInt 32 0
2332fd4e5da5Sopenharmony_ci%i32 = OpTypeInt 32 1
2333fd4e5da5Sopenharmony_ci
2334fd4e5da5Sopenharmony_ci%u32_8 = OpConstant %u32 8
2335fd4e5da5Sopenharmony_ci%subgroup = OpConstant %u32 3
2336fd4e5da5Sopenharmony_ci
2337fd4e5da5Sopenharmony_ci%f16mat = OpTypeCooperativeMatrixNV %f16 %subgroup %u32_8 %u32_8
2338fd4e5da5Sopenharmony_ci
2339fd4e5da5Sopenharmony_ci%main = OpFunction %void None %func
2340fd4e5da5Sopenharmony_ci%main_entry = OpLabel
2341fd4e5da5Sopenharmony_ci
2342fd4e5da5Sopenharmony_ci%1 = OpCooperativeMatrixLengthNV %u32 %f16mat
2343fd4e5da5Sopenharmony_ci
2344fd4e5da5Sopenharmony_ciOpReturn
2345fd4e5da5Sopenharmony_ciOpFunctionEnd)";
2346fd4e5da5Sopenharmony_ci
2347fd4e5da5Sopenharmony_ci  CompileSuccessfully(body.c_str());
2348fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
2349fd4e5da5Sopenharmony_ci}
2350fd4e5da5Sopenharmony_ci
2351fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, CoopMatKHRLoadStoreSuccess) {
2352fd4e5da5Sopenharmony_ci  std::string spirv =
2353fd4e5da5Sopenharmony_ci      GenCoopMatLoadStoreShader("MakePointerAvailableKHR|NonPrivatePointerKHR",
2354fd4e5da5Sopenharmony_ci                                "MakePointerVisibleKHR|NonPrivatePointerKHR");
2355fd4e5da5Sopenharmony_ci
2356fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
2357fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
2358fd4e5da5Sopenharmony_ci}
2359fd4e5da5Sopenharmony_ci
2360fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, CoopMatKHRStoreMemoryAccessFail) {
2361fd4e5da5Sopenharmony_ci  std::string spirv =
2362fd4e5da5Sopenharmony_ci      GenCoopMatLoadStoreShader("MakePointerVisibleKHR|NonPrivatePointerKHR",
2363fd4e5da5Sopenharmony_ci                                "MakePointerVisibleKHR|NonPrivatePointerKHR");
2364fd4e5da5Sopenharmony_ci
2365fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
2366fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
2367fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
2368fd4e5da5Sopenharmony_ci              HasSubstr("MakePointerVisibleKHR cannot be used with OpStore"));
2369fd4e5da5Sopenharmony_ci}
2370fd4e5da5Sopenharmony_ci
2371fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, CoopMatKHRLoadMemoryAccessFail) {
2372fd4e5da5Sopenharmony_ci  std::string spirv =
2373fd4e5da5Sopenharmony_ci      GenCoopMatLoadStoreShader("MakePointerAvailableKHR|NonPrivatePointerKHR",
2374fd4e5da5Sopenharmony_ci                                "MakePointerAvailableKHR|NonPrivatePointerKHR");
2375fd4e5da5Sopenharmony_ci
2376fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
2377fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
2378fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
2379fd4e5da5Sopenharmony_ci              HasSubstr("MakePointerAvailableKHR cannot be used with OpLoad"));
2380fd4e5da5Sopenharmony_ci}
2381fd4e5da5Sopenharmony_ci
2382fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, CoopMatKHRInvalidStorageClassFail) {
2383fd4e5da5Sopenharmony_ci  const std::string body = R"(
2384fd4e5da5Sopenharmony_ciOpCapability Shader
2385fd4e5da5Sopenharmony_ciOpCapability Float16
2386fd4e5da5Sopenharmony_ciOpCapability CooperativeMatrixKHR
2387fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_cooperative_matrix"
2388fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model"
2389fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
2390fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %main "main"
2391fd4e5da5Sopenharmony_ci%void = OpTypeVoid
2392fd4e5da5Sopenharmony_ci%func = OpTypeFunction %void
2393fd4e5da5Sopenharmony_ci%f16 = OpTypeFloat 16
2394fd4e5da5Sopenharmony_ci%u32 = OpTypeInt 32 0
2395fd4e5da5Sopenharmony_ci
2396fd4e5da5Sopenharmony_ci%u32_8 = OpConstant %u32 8
2397fd4e5da5Sopenharmony_ci%use_A = OpConstant %u32 0
2398fd4e5da5Sopenharmony_ci%subgroup = OpConstant %u32 3
2399fd4e5da5Sopenharmony_ci
2400fd4e5da5Sopenharmony_ci%f16mat = OpTypeCooperativeMatrixKHR %f16 %subgroup %u32_8 %u32_8 %use_A
2401fd4e5da5Sopenharmony_ci
2402fd4e5da5Sopenharmony_ci%str = OpTypeStruct %f16mat
2403fd4e5da5Sopenharmony_ci%str_ptr = OpTypePointer Workgroup %str
2404fd4e5da5Sopenharmony_ci%sh = OpVariable %str_ptr Workgroup
2405fd4e5da5Sopenharmony_ci
2406fd4e5da5Sopenharmony_ci%main = OpFunction %void None %func
2407fd4e5da5Sopenharmony_ci%main_entry = OpLabel
2408fd4e5da5Sopenharmony_ci
2409fd4e5da5Sopenharmony_ciOpReturn
2410fd4e5da5Sopenharmony_ciOpFunctionEnd)";
2411fd4e5da5Sopenharmony_ci
2412fd4e5da5Sopenharmony_ci  CompileSuccessfully(body.c_str());
2413fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
2414fd4e5da5Sopenharmony_ci  EXPECT_THAT(
2415fd4e5da5Sopenharmony_ci      getDiagnosticString(),
2416fd4e5da5Sopenharmony_ci      HasSubstr(
2417fd4e5da5Sopenharmony_ci          "Cooperative matrix types (or types containing them) can only be "
2418fd4e5da5Sopenharmony_ci          "allocated in Function or Private storage classes or as function "
2419fd4e5da5Sopenharmony_ci          "parameters"));
2420fd4e5da5Sopenharmony_ci}
2421fd4e5da5Sopenharmony_ci
2422fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, CoopMatMatrixKHRLengthResultTypeBad) {
2423fd4e5da5Sopenharmony_ci  const std::string body = R"(
2424fd4e5da5Sopenharmony_ciOpCapability Shader
2425fd4e5da5Sopenharmony_ciOpCapability Float16
2426fd4e5da5Sopenharmony_ciOpCapability CooperativeMatrixKHR
2427fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_cooperative_matrix"
2428fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model"
2429fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
2430fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %main "main"
2431fd4e5da5Sopenharmony_ci%void = OpTypeVoid
2432fd4e5da5Sopenharmony_ci%func = OpTypeFunction %void
2433fd4e5da5Sopenharmony_ci%f16 = OpTypeFloat 16
2434fd4e5da5Sopenharmony_ci%u32 = OpTypeInt 32 0
2435fd4e5da5Sopenharmony_ci%i32 = OpTypeInt 32 1
2436fd4e5da5Sopenharmony_ci
2437fd4e5da5Sopenharmony_ci%u32_8 = OpConstant %u32 8
2438fd4e5da5Sopenharmony_ci%use_A = OpConstant %u32 0
2439fd4e5da5Sopenharmony_ci%subgroup = OpConstant %u32 3
2440fd4e5da5Sopenharmony_ci
2441fd4e5da5Sopenharmony_ci%f16mat = OpTypeCooperativeMatrixKHR %f16 %subgroup %u32_8 %u32_8 %use_A
2442fd4e5da5Sopenharmony_ci
2443fd4e5da5Sopenharmony_ci%main = OpFunction %void None %func
2444fd4e5da5Sopenharmony_ci%main_entry = OpLabel
2445fd4e5da5Sopenharmony_ci
2446fd4e5da5Sopenharmony_ci%1 = OpCooperativeMatrixLengthKHR %i32 %f16mat
2447fd4e5da5Sopenharmony_ci
2448fd4e5da5Sopenharmony_ciOpReturn
2449fd4e5da5Sopenharmony_ciOpFunctionEnd)";
2450fd4e5da5Sopenharmony_ci
2451fd4e5da5Sopenharmony_ci  CompileSuccessfully(body.c_str());
2452fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
2453fd4e5da5Sopenharmony_ci  EXPECT_THAT(
2454fd4e5da5Sopenharmony_ci      getDiagnosticString(),
2455fd4e5da5Sopenharmony_ci      HasSubstr("The Result Type of OpCooperativeMatrixLengthKHR <id> "
2456fd4e5da5Sopenharmony_ci                "'12[%12]' must be OpTypeInt with width 32 and signedness 0"));
2457fd4e5da5Sopenharmony_ci}
2458fd4e5da5Sopenharmony_ci
2459fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, CoopMatMatrixKHRLengthOperandTypeBad) {
2460fd4e5da5Sopenharmony_ci  const std::string body =
2461fd4e5da5Sopenharmony_ci      R"(
2462fd4e5da5Sopenharmony_ciOpCapability Shader
2463fd4e5da5Sopenharmony_ciOpCapability Float16
2464fd4e5da5Sopenharmony_ciOpCapability CooperativeMatrixKHR
2465fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_cooperative_matrix"
2466fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model"
2467fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
2468fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %main "main"
2469fd4e5da5Sopenharmony_ci%void = OpTypeVoid
2470fd4e5da5Sopenharmony_ci%func = OpTypeFunction %void
2471fd4e5da5Sopenharmony_ci%f16 = OpTypeFloat 16
2472fd4e5da5Sopenharmony_ci%u32 = OpTypeInt 32 0
2473fd4e5da5Sopenharmony_ci%i32 = OpTypeInt 32 1
2474fd4e5da5Sopenharmony_ci
2475fd4e5da5Sopenharmony_ci%u32_8 = OpConstant %u32 8
2476fd4e5da5Sopenharmony_ci%use_A = OpConstant %u32 0
2477fd4e5da5Sopenharmony_ci%subgroup = OpConstant %u32 3
2478fd4e5da5Sopenharmony_ci
2479fd4e5da5Sopenharmony_ci%f16mat = OpTypeCooperativeMatrixKHR %f16 %subgroup %u32_8 %u32_8 %use_A
2480fd4e5da5Sopenharmony_ci
2481fd4e5da5Sopenharmony_ci%main = OpFunction %void None %func
2482fd4e5da5Sopenharmony_ci%main_entry = OpLabel
2483fd4e5da5Sopenharmony_ci
2484fd4e5da5Sopenharmony_ci%1 = OpCooperativeMatrixLengthKHR %u32 %u32
2485fd4e5da5Sopenharmony_ci
2486fd4e5da5Sopenharmony_ciOpReturn
2487fd4e5da5Sopenharmony_ciOpFunctionEnd)";
2488fd4e5da5Sopenharmony_ci
2489fd4e5da5Sopenharmony_ci  CompileSuccessfully(body.c_str());
2490fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
2491fd4e5da5Sopenharmony_ci  EXPECT_THAT(
2492fd4e5da5Sopenharmony_ci      getDiagnosticString(),
2493fd4e5da5Sopenharmony_ci      HasSubstr("The type in OpCooperativeMatrixLengthKHR <id> '5[%uint]' "
2494fd4e5da5Sopenharmony_ci                "must be OpTypeCooperativeMatrixKHR"));
2495fd4e5da5Sopenharmony_ci}
2496fd4e5da5Sopenharmony_ci
2497fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, CoopMatMatrixKHRLengthGood) {
2498fd4e5da5Sopenharmony_ci  const std::string body =
2499fd4e5da5Sopenharmony_ci      R"(
2500fd4e5da5Sopenharmony_ciOpCapability Shader
2501fd4e5da5Sopenharmony_ciOpCapability Float16
2502fd4e5da5Sopenharmony_ciOpCapability CooperativeMatrixKHR
2503fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_cooperative_matrix"
2504fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model"
2505fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
2506fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %main "main"
2507fd4e5da5Sopenharmony_ci%void = OpTypeVoid
2508fd4e5da5Sopenharmony_ci%func = OpTypeFunction %void
2509fd4e5da5Sopenharmony_ci%f16 = OpTypeFloat 16
2510fd4e5da5Sopenharmony_ci%u32 = OpTypeInt 32 0
2511fd4e5da5Sopenharmony_ci%i32 = OpTypeInt 32 1
2512fd4e5da5Sopenharmony_ci
2513fd4e5da5Sopenharmony_ci%u32_8 = OpConstant %u32 8
2514fd4e5da5Sopenharmony_ci%use_A = OpConstant %u32 0
2515fd4e5da5Sopenharmony_ci%subgroup = OpConstant %u32 3
2516fd4e5da5Sopenharmony_ci
2517fd4e5da5Sopenharmony_ci%f16mat = OpTypeCooperativeMatrixKHR %f16 %subgroup %u32_8 %u32_8 %use_A
2518fd4e5da5Sopenharmony_ci
2519fd4e5da5Sopenharmony_ci%main = OpFunction %void None %func
2520fd4e5da5Sopenharmony_ci%main_entry = OpLabel
2521fd4e5da5Sopenharmony_ci
2522fd4e5da5Sopenharmony_ci%1 = OpCooperativeMatrixLengthKHR %u32 %f16mat
2523fd4e5da5Sopenharmony_ci
2524fd4e5da5Sopenharmony_ciOpReturn
2525fd4e5da5Sopenharmony_ciOpFunctionEnd)";
2526fd4e5da5Sopenharmony_ci
2527fd4e5da5Sopenharmony_ci  CompileSuccessfully(body.c_str());
2528fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
2529fd4e5da5Sopenharmony_ci}
2530fd4e5da5Sopenharmony_ci
2531fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, VulkanRTAOutsideOfStructBad) {
2532fd4e5da5Sopenharmony_ci  std::string spirv = R"(
2533fd4e5da5Sopenharmony_ciOpCapability Shader
2534fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
2535fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %func "func"
2536fd4e5da5Sopenharmony_ciOpExecutionMode %func OriginUpperLeft
2537fd4e5da5Sopenharmony_ci%sampler_t = OpTypeSampler
2538fd4e5da5Sopenharmony_ci%array_t = OpTypeRuntimeArray %sampler_t
2539fd4e5da5Sopenharmony_ci%array_ptr = OpTypePointer UniformConstant %array_t
2540fd4e5da5Sopenharmony_ci%2 = OpVariable %array_ptr UniformConstant
2541fd4e5da5Sopenharmony_ci%void = OpTypeVoid
2542fd4e5da5Sopenharmony_ci%func_t = OpTypeFunction %void
2543fd4e5da5Sopenharmony_ci%func = OpFunction %void None %func_t
2544fd4e5da5Sopenharmony_ci%1 = OpLabel
2545fd4e5da5Sopenharmony_ciOpReturn
2546fd4e5da5Sopenharmony_ciOpFunctionEnd
2547fd4e5da5Sopenharmony_ci)";
2548fd4e5da5Sopenharmony_ci
2549fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
2550fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
2551fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
2552fd4e5da5Sopenharmony_ci              AnyVUID("VUID-StandaloneSpirv-OpTypeRuntimeArray-04680"));
2553fd4e5da5Sopenharmony_ci  EXPECT_THAT(
2554fd4e5da5Sopenharmony_ci      getDiagnosticString(),
2555fd4e5da5Sopenharmony_ci      HasSubstr(
2556fd4e5da5Sopenharmony_ci          "OpVariable, <id> '5[%5]', is attempting to create memory for an "
2557fd4e5da5Sopenharmony_ci          "illegal type, OpTypeRuntimeArray.\nFor Vulkan OpTypeRuntimeArray "
2558fd4e5da5Sopenharmony_ci          "can only appear as the final member of an OpTypeStruct, thus cannot "
2559fd4e5da5Sopenharmony_ci          "be instantiated via OpVariable\n  %5 = OpVariable "
2560fd4e5da5Sopenharmony_ci          "%_ptr_UniformConstant__runtimearr_2 UniformConstant\n"));
2561fd4e5da5Sopenharmony_ci}
2562fd4e5da5Sopenharmony_ci
2563fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, VulkanRTAOutsideOfStructWithRuntimeDescriptorArrayGood) {
2564fd4e5da5Sopenharmony_ci  std::string spirv = R"(
2565fd4e5da5Sopenharmony_ciOpCapability Shader
2566fd4e5da5Sopenharmony_ciOpCapability RuntimeDescriptorArrayEXT
2567fd4e5da5Sopenharmony_ciOpExtension "SPV_EXT_descriptor_indexing"
2568fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
2569fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %func "func"
2570fd4e5da5Sopenharmony_ciOpExecutionMode %func OriginUpperLeft
2571fd4e5da5Sopenharmony_ciOpDecorate %struct Block
2572fd4e5da5Sopenharmony_ciOpMemberDecorate %struct 0 Offset 0
2573fd4e5da5Sopenharmony_ci%sampler_t = OpTypeSampler
2574fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
2575fd4e5da5Sopenharmony_ci%array_t = OpTypeRuntimeArray %sampler_t
2576fd4e5da5Sopenharmony_ci%struct = OpTypeStruct %uint
2577fd4e5da5Sopenharmony_ci%sb_array_t = OpTypeRuntimeArray %struct
2578fd4e5da5Sopenharmony_ci%array_sb_ptr = OpTypePointer StorageBuffer %sb_array_t
2579fd4e5da5Sopenharmony_ci%2 = OpVariable %array_sb_ptr StorageBuffer
2580fd4e5da5Sopenharmony_ci%array_uc_ptr = OpTypePointer UniformConstant %array_t
2581fd4e5da5Sopenharmony_ci%3 = OpVariable %array_uc_ptr UniformConstant
2582fd4e5da5Sopenharmony_ci%void = OpTypeVoid
2583fd4e5da5Sopenharmony_ci%func_t = OpTypeFunction %void
2584fd4e5da5Sopenharmony_ci%func = OpFunction %void None %func_t
2585fd4e5da5Sopenharmony_ci%1 = OpLabel
2586fd4e5da5Sopenharmony_ciOpReturn
2587fd4e5da5Sopenharmony_ciOpFunctionEnd
2588fd4e5da5Sopenharmony_ci)";
2589fd4e5da5Sopenharmony_ci
2590fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
2591fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
2592fd4e5da5Sopenharmony_ci}
2593fd4e5da5Sopenharmony_ci
2594fd4e5da5Sopenharmony_ciTEST_F(
2595fd4e5da5Sopenharmony_ci    ValidateMemory,
2596fd4e5da5Sopenharmony_ci    VulkanRTAOutsideOfStructWithRuntimeDescriptorArrayAndWrongStorageClassBad) {
2597fd4e5da5Sopenharmony_ci  std::string spirv = R"(
2598fd4e5da5Sopenharmony_ciOpCapability Shader
2599fd4e5da5Sopenharmony_ciOpCapability RuntimeDescriptorArrayEXT
2600fd4e5da5Sopenharmony_ciOpExtension "SPV_EXT_descriptor_indexing"
2601fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
2602fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %func "func"
2603fd4e5da5Sopenharmony_ciOpExecutionMode %func OriginUpperLeft
2604fd4e5da5Sopenharmony_ci%uint_t = OpTypeInt 32 0
2605fd4e5da5Sopenharmony_ci%array_t = OpTypeRuntimeArray %uint_t
2606fd4e5da5Sopenharmony_ci%array_ptr = OpTypePointer Workgroup %array_t
2607fd4e5da5Sopenharmony_ci%2 = OpVariable %array_ptr Workgroup
2608fd4e5da5Sopenharmony_ci%void = OpTypeVoid
2609fd4e5da5Sopenharmony_ci%func_t = OpTypeFunction %void
2610fd4e5da5Sopenharmony_ci%func = OpFunction %void None %func_t
2611fd4e5da5Sopenharmony_ci%1 = OpLabel
2612fd4e5da5Sopenharmony_ciOpReturn
2613fd4e5da5Sopenharmony_ciOpFunctionEnd
2614fd4e5da5Sopenharmony_ci)";
2615fd4e5da5Sopenharmony_ci
2616fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
2617fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
2618fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
2619fd4e5da5Sopenharmony_ci              AnyVUID("VUID-StandaloneSpirv-OpTypeRuntimeArray-04680"));
2620fd4e5da5Sopenharmony_ci  EXPECT_THAT(
2621fd4e5da5Sopenharmony_ci      getDiagnosticString(),
2622fd4e5da5Sopenharmony_ci      HasSubstr("For Vulkan with RuntimeDescriptorArrayEXT, a variable "
2623fd4e5da5Sopenharmony_ci                "containing OpTypeRuntimeArray must have storage class of "
2624fd4e5da5Sopenharmony_ci                "StorageBuffer, Uniform, or UniformConstant.\n  %5 = "
2625fd4e5da5Sopenharmony_ci                "OpVariable %_ptr_Workgroup__runtimearr_uint Workgroup\n"));
2626fd4e5da5Sopenharmony_ci}
2627fd4e5da5Sopenharmony_ci
2628fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, VulkanRTAInsideStorageBufferStructGood) {
2629fd4e5da5Sopenharmony_ci  std::string spirv = R"(
2630fd4e5da5Sopenharmony_ciOpCapability Shader
2631fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
2632fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %func "func"
2633fd4e5da5Sopenharmony_ciOpExecutionMode %func OriginUpperLeft
2634fd4e5da5Sopenharmony_ciOpDecorate %array_t ArrayStride 4
2635fd4e5da5Sopenharmony_ciOpMemberDecorate %struct_t 0 Offset 0
2636fd4e5da5Sopenharmony_ciOpDecorate %struct_t Block
2637fd4e5da5Sopenharmony_ci%uint_t = OpTypeInt 32 0
2638fd4e5da5Sopenharmony_ci%array_t = OpTypeRuntimeArray %uint_t
2639fd4e5da5Sopenharmony_ci%struct_t = OpTypeStruct %array_t
2640fd4e5da5Sopenharmony_ci%struct_ptr = OpTypePointer StorageBuffer %struct_t
2641fd4e5da5Sopenharmony_ci%2 = OpVariable %struct_ptr StorageBuffer
2642fd4e5da5Sopenharmony_ci%void = OpTypeVoid
2643fd4e5da5Sopenharmony_ci%func_t = OpTypeFunction %void
2644fd4e5da5Sopenharmony_ci%func = OpFunction %void None %func_t
2645fd4e5da5Sopenharmony_ci%1 = OpLabel
2646fd4e5da5Sopenharmony_ciOpReturn
2647fd4e5da5Sopenharmony_ciOpFunctionEnd
2648fd4e5da5Sopenharmony_ci)";
2649fd4e5da5Sopenharmony_ci
2650fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
2651fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
2652fd4e5da5Sopenharmony_ci}
2653fd4e5da5Sopenharmony_ci
2654fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, VulkanRTAInsideWrongStorageClassStructBad) {
2655fd4e5da5Sopenharmony_ci  std::string spirv = R"(
2656fd4e5da5Sopenharmony_ciOpCapability Shader
2657fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
2658fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %func "func"
2659fd4e5da5Sopenharmony_ciOpExecutionMode %func OriginUpperLeft
2660fd4e5da5Sopenharmony_ciOpDecorate %struct_t Block
2661fd4e5da5Sopenharmony_ci%uint_t = OpTypeInt 32 0
2662fd4e5da5Sopenharmony_ci%array_t = OpTypeRuntimeArray %uint_t
2663fd4e5da5Sopenharmony_ci%struct_t = OpTypeStruct %array_t
2664fd4e5da5Sopenharmony_ci%struct_ptr = OpTypePointer Workgroup %struct_t
2665fd4e5da5Sopenharmony_ci%2 = OpVariable %struct_ptr Workgroup
2666fd4e5da5Sopenharmony_ci%void = OpTypeVoid
2667fd4e5da5Sopenharmony_ci%func_t = OpTypeFunction %void
2668fd4e5da5Sopenharmony_ci%func = OpFunction %void None %func_t
2669fd4e5da5Sopenharmony_ci%1 = OpLabel
2670fd4e5da5Sopenharmony_ciOpReturn
2671fd4e5da5Sopenharmony_ciOpFunctionEnd
2672fd4e5da5Sopenharmony_ci)";
2673fd4e5da5Sopenharmony_ci
2674fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
2675fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
2676fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
2677fd4e5da5Sopenharmony_ci              AnyVUID("VUID-StandaloneSpirv-OpTypeRuntimeArray-04680"));
2678fd4e5da5Sopenharmony_ci  EXPECT_THAT(
2679fd4e5da5Sopenharmony_ci      getDiagnosticString(),
2680fd4e5da5Sopenharmony_ci      HasSubstr(
2681fd4e5da5Sopenharmony_ci          "For Vulkan, OpTypeStruct variables containing OpTypeRuntimeArray "
2682fd4e5da5Sopenharmony_ci          "must have storage class of StorageBuffer, PhysicalStorageBuffer, or "
2683fd4e5da5Sopenharmony_ci          "Uniform.\n  %6 = "
2684fd4e5da5Sopenharmony_ci          "OpVariable %_ptr_Workgroup__struct_2 Workgroup\n"));
2685fd4e5da5Sopenharmony_ci}
2686fd4e5da5Sopenharmony_ci
2687fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, VulkanRTAInsideStorageBufferStructWithoutBlockBad) {
2688fd4e5da5Sopenharmony_ci  std::string spirv = R"(
2689fd4e5da5Sopenharmony_ciOpCapability Shader
2690fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
2691fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %func "func"
2692fd4e5da5Sopenharmony_ciOpExecutionMode %func OriginUpperLeft
2693fd4e5da5Sopenharmony_ciOpDecorate %struct_t BufferBlock
2694fd4e5da5Sopenharmony_ci%uint_t = OpTypeInt 32 0
2695fd4e5da5Sopenharmony_ci%array_t = OpTypeRuntimeArray %uint_t
2696fd4e5da5Sopenharmony_ci%struct_t = OpTypeStruct %array_t
2697fd4e5da5Sopenharmony_ci%struct_ptr = OpTypePointer StorageBuffer %struct_t
2698fd4e5da5Sopenharmony_ci%2 = OpVariable %struct_ptr StorageBuffer
2699fd4e5da5Sopenharmony_ci%void = OpTypeVoid
2700fd4e5da5Sopenharmony_ci%func_t = OpTypeFunction %void
2701fd4e5da5Sopenharmony_ci%func = OpFunction %void None %func_t
2702fd4e5da5Sopenharmony_ci%1 = OpLabel
2703fd4e5da5Sopenharmony_ciOpReturn
2704fd4e5da5Sopenharmony_ciOpFunctionEnd
2705fd4e5da5Sopenharmony_ci)";
2706fd4e5da5Sopenharmony_ci
2707fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
2708fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
2709fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
2710fd4e5da5Sopenharmony_ci              AnyVUID("VUID-StandaloneSpirv-OpTypeRuntimeArray-04680"));
2711fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
2712fd4e5da5Sopenharmony_ci              HasSubstr("For Vulkan, an OpTypeStruct variable containing an "
2713fd4e5da5Sopenharmony_ci                        "OpTypeRuntimeArray must be decorated with Block if it "
2714fd4e5da5Sopenharmony_ci                        "has storage class StorageBuffer or "
2715fd4e5da5Sopenharmony_ci                        "PhysicalStorageBuffer.\n  %6 = OpVariable "
2716fd4e5da5Sopenharmony_ci                        "%_ptr_StorageBuffer__struct_2 StorageBuffer\n"));
2717fd4e5da5Sopenharmony_ci}
2718fd4e5da5Sopenharmony_ci
2719fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, VulkanRTAInsideUniformStructGood) {
2720fd4e5da5Sopenharmony_ci  std::string spirv = R"(
2721fd4e5da5Sopenharmony_ciOpCapability Shader
2722fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
2723fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %func "func"
2724fd4e5da5Sopenharmony_ciOpExecutionMode %func OriginUpperLeft
2725fd4e5da5Sopenharmony_ciOpDecorate %array_t ArrayStride 4
2726fd4e5da5Sopenharmony_ciOpMemberDecorate %struct_t 0 Offset 0
2727fd4e5da5Sopenharmony_ciOpDecorate %struct_t BufferBlock
2728fd4e5da5Sopenharmony_ci%uint_t = OpTypeInt 32 0
2729fd4e5da5Sopenharmony_ci%array_t = OpTypeRuntimeArray %uint_t
2730fd4e5da5Sopenharmony_ci%struct_t = OpTypeStruct %array_t
2731fd4e5da5Sopenharmony_ci%struct_ptr = OpTypePointer Uniform %struct_t
2732fd4e5da5Sopenharmony_ci%2 = OpVariable %struct_ptr Uniform
2733fd4e5da5Sopenharmony_ci%void = OpTypeVoid
2734fd4e5da5Sopenharmony_ci%func_t = OpTypeFunction %void
2735fd4e5da5Sopenharmony_ci%func = OpFunction %void None %func_t
2736fd4e5da5Sopenharmony_ci%1 = OpLabel
2737fd4e5da5Sopenharmony_ciOpReturn
2738fd4e5da5Sopenharmony_ciOpFunctionEnd
2739fd4e5da5Sopenharmony_ci)";
2740fd4e5da5Sopenharmony_ci
2741fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
2742fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
2743fd4e5da5Sopenharmony_ci}
2744fd4e5da5Sopenharmony_ci
2745fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, VulkanRTAInsideUniformStructWithoutBufferBlockBad) {
2746fd4e5da5Sopenharmony_ci  std::string spirv = R"(
2747fd4e5da5Sopenharmony_ciOpCapability Shader
2748fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
2749fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %func "func"
2750fd4e5da5Sopenharmony_ciOpExecutionMode %func OriginUpperLeft
2751fd4e5da5Sopenharmony_ciOpDecorate %struct_t Block
2752fd4e5da5Sopenharmony_ci%uint_t = OpTypeInt 32 0
2753fd4e5da5Sopenharmony_ci%array_t = OpTypeRuntimeArray %uint_t
2754fd4e5da5Sopenharmony_ci%struct_t = OpTypeStruct %array_t
2755fd4e5da5Sopenharmony_ci%struct_ptr = OpTypePointer Uniform %struct_t
2756fd4e5da5Sopenharmony_ci%2 = OpVariable %struct_ptr Uniform
2757fd4e5da5Sopenharmony_ci%void = OpTypeVoid
2758fd4e5da5Sopenharmony_ci%func_t = OpTypeFunction %void
2759fd4e5da5Sopenharmony_ci%func = OpFunction %void None %func_t
2760fd4e5da5Sopenharmony_ci%1 = OpLabel
2761fd4e5da5Sopenharmony_ciOpReturn
2762fd4e5da5Sopenharmony_ciOpFunctionEnd
2763fd4e5da5Sopenharmony_ci)";
2764fd4e5da5Sopenharmony_ci
2765fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
2766fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
2767fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
2768fd4e5da5Sopenharmony_ci              AnyVUID("VUID-StandaloneSpirv-OpTypeRuntimeArray-04680"));
2769fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
2770fd4e5da5Sopenharmony_ci              HasSubstr("For Vulkan, an OpTypeStruct variable containing an "
2771fd4e5da5Sopenharmony_ci                        "OpTypeRuntimeArray must be decorated with BufferBlock "
2772fd4e5da5Sopenharmony_ci                        "if it has storage class Uniform.\n  %6 = OpVariable "
2773fd4e5da5Sopenharmony_ci                        "%_ptr_Uniform__struct_2 Uniform\n"));
2774fd4e5da5Sopenharmony_ci}
2775fd4e5da5Sopenharmony_ci
2776fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, VulkanRTAInsideRTABad) {
2777fd4e5da5Sopenharmony_ci  std::string spirv = R"(
2778fd4e5da5Sopenharmony_ciOpCapability Shader
2779fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
2780fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %func "func"
2781fd4e5da5Sopenharmony_ciOpExecutionMode %func OriginUpperLeft
2782fd4e5da5Sopenharmony_ci%sampler_t = OpTypeSampler
2783fd4e5da5Sopenharmony_ci%inner_array_t = OpTypeRuntimeArray %sampler_t
2784fd4e5da5Sopenharmony_ci%array_t = OpTypeRuntimeArray %inner_array_t
2785fd4e5da5Sopenharmony_ci%array_ptr = OpTypePointer UniformConstant %array_t
2786fd4e5da5Sopenharmony_ci%2 = OpVariable %array_ptr UniformConstant
2787fd4e5da5Sopenharmony_ci%void = OpTypeVoid
2788fd4e5da5Sopenharmony_ci%func_t = OpTypeFunction %void
2789fd4e5da5Sopenharmony_ci%func = OpFunction %void None %func_t
2790fd4e5da5Sopenharmony_ci%1 = OpLabel
2791fd4e5da5Sopenharmony_ciOpReturn
2792fd4e5da5Sopenharmony_ciOpFunctionEnd
2793fd4e5da5Sopenharmony_ci)";
2794fd4e5da5Sopenharmony_ci
2795fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
2796fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
2797fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
2798fd4e5da5Sopenharmony_ci              AnyVUID("VUID-StandaloneSpirv-OpTypeRuntimeArray-04680"));
2799fd4e5da5Sopenharmony_ci  EXPECT_THAT(
2800fd4e5da5Sopenharmony_ci      getDiagnosticString(),
2801fd4e5da5Sopenharmony_ci      HasSubstr(
2802fd4e5da5Sopenharmony_ci          "OpTypeRuntimeArray Element Type <id> '3[%_runtimearr_2]' is not "
2803fd4e5da5Sopenharmony_ci          "valid in Vulkan environments.\n  %_runtimearr__runtimearr_2 = "
2804fd4e5da5Sopenharmony_ci          "OpTypeRuntimeArray %_runtimearr_2\n"));
2805fd4e5da5Sopenharmony_ci}
2806fd4e5da5Sopenharmony_ci
2807fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, VulkanRTAInsideRTAWithRuntimeDescriptorArrayBad) {
2808fd4e5da5Sopenharmony_ci  std::string spirv = R"(
2809fd4e5da5Sopenharmony_ciOpCapability RuntimeDescriptorArrayEXT
2810fd4e5da5Sopenharmony_ciOpCapability Shader
2811fd4e5da5Sopenharmony_ciOpExtension "SPV_EXT_descriptor_indexing"
2812fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
2813fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %func "func"
2814fd4e5da5Sopenharmony_ciOpExecutionMode %func OriginUpperLeft
2815fd4e5da5Sopenharmony_ciOpDecorate %struct Block
2816fd4e5da5Sopenharmony_ci%uint_t = OpTypeInt 32 0
2817fd4e5da5Sopenharmony_ci%inner_array_t = OpTypeRuntimeArray %uint_t
2818fd4e5da5Sopenharmony_ci%array_t = OpTypeRuntimeArray %inner_array_t
2819fd4e5da5Sopenharmony_ci%struct = OpTypeStruct %array_t
2820fd4e5da5Sopenharmony_ci%array_ptr = OpTypePointer StorageBuffer %struct
2821fd4e5da5Sopenharmony_ci%2 = OpVariable %array_ptr StorageBuffer
2822fd4e5da5Sopenharmony_ci%void = OpTypeVoid
2823fd4e5da5Sopenharmony_ci%func_t = OpTypeFunction %void
2824fd4e5da5Sopenharmony_ci%func = OpFunction %void None %func_t
2825fd4e5da5Sopenharmony_ci%1 = OpLabel
2826fd4e5da5Sopenharmony_ciOpReturn
2827fd4e5da5Sopenharmony_ciOpFunctionEnd
2828fd4e5da5Sopenharmony_ci)";
2829fd4e5da5Sopenharmony_ci
2830fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
2831fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
2832fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
2833fd4e5da5Sopenharmony_ci              AnyVUID("VUID-StandaloneSpirv-OpTypeRuntimeArray-04680"));
2834fd4e5da5Sopenharmony_ci  EXPECT_THAT(
2835fd4e5da5Sopenharmony_ci      getDiagnosticString(),
2836fd4e5da5Sopenharmony_ci      HasSubstr(
2837fd4e5da5Sopenharmony_ci          "OpTypeRuntimeArray Element Type <id> '4[%_runtimearr_uint]' is not "
2838fd4e5da5Sopenharmony_ci          "valid in Vulkan environments.\n  %_runtimearr__runtimearr_uint = "
2839fd4e5da5Sopenharmony_ci          "OpTypeRuntimeArray %_runtimearr_uint\n"));
2840fd4e5da5Sopenharmony_ci}
2841fd4e5da5Sopenharmony_ci
2842fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory,
2843fd4e5da5Sopenharmony_ci       VulkanUniformStructInsideRTAWithRuntimeDescriptorArrayGood) {
2844fd4e5da5Sopenharmony_ci  std::string spirv = R"(
2845fd4e5da5Sopenharmony_ciOpCapability RuntimeDescriptorArrayEXT
2846fd4e5da5Sopenharmony_ciOpCapability Shader
2847fd4e5da5Sopenharmony_ciOpExtension "SPV_EXT_descriptor_indexing"
2848fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
2849fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %func "func"
2850fd4e5da5Sopenharmony_ciOpExecutionMode %func OriginUpperLeft
2851fd4e5da5Sopenharmony_ciOpDecorate %array_t ArrayStride 4
2852fd4e5da5Sopenharmony_ciOpMemberDecorate %struct_t 0 Offset 0
2853fd4e5da5Sopenharmony_ciOpDecorate %struct_t Block
2854fd4e5da5Sopenharmony_ci%uint_t = OpTypeInt 32 0
2855fd4e5da5Sopenharmony_ci%struct_t = OpTypeStruct %uint_t
2856fd4e5da5Sopenharmony_ci%array_t = OpTypeRuntimeArray %struct_t
2857fd4e5da5Sopenharmony_ci%array_ptr = OpTypePointer Uniform %array_t
2858fd4e5da5Sopenharmony_ci%2 = OpVariable %array_ptr Uniform
2859fd4e5da5Sopenharmony_ci%void = OpTypeVoid
2860fd4e5da5Sopenharmony_ci%func_t = OpTypeFunction %void
2861fd4e5da5Sopenharmony_ci%func = OpFunction %void None %func_t
2862fd4e5da5Sopenharmony_ci%1 = OpLabel
2863fd4e5da5Sopenharmony_ciOpReturn
2864fd4e5da5Sopenharmony_ciOpFunctionEnd
2865fd4e5da5Sopenharmony_ci)";
2866fd4e5da5Sopenharmony_ci
2867fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
2868fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
2869fd4e5da5Sopenharmony_ci}
2870fd4e5da5Sopenharmony_ci
2871fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, VulkanRTAInsideRTAInsideStructBad) {
2872fd4e5da5Sopenharmony_ci  std::string spirv = R"(
2873fd4e5da5Sopenharmony_ciOpCapability Shader
2874fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
2875fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %func "func"
2876fd4e5da5Sopenharmony_ciOpExecutionMode %func OriginUpperLeft
2877fd4e5da5Sopenharmony_ciOpDecorate %array_t ArrayStride 4
2878fd4e5da5Sopenharmony_ciOpMemberDecorate %struct_t 0 Offset 0
2879fd4e5da5Sopenharmony_ciOpDecorate %struct_t Block
2880fd4e5da5Sopenharmony_ci%uint_t = OpTypeInt 32 0
2881fd4e5da5Sopenharmony_ci%inner_array_t = OpTypeRuntimeArray %uint_t
2882fd4e5da5Sopenharmony_ci%array_t = OpTypeRuntimeArray %inner_array_t
2883fd4e5da5Sopenharmony_ci%struct_t = OpTypeStruct %array_t
2884fd4e5da5Sopenharmony_ci%struct_ptr = OpTypePointer StorageBuffer %struct_t
2885fd4e5da5Sopenharmony_ci%2 = OpVariable %struct_ptr StorageBuffer
2886fd4e5da5Sopenharmony_ci%void = OpTypeVoid
2887fd4e5da5Sopenharmony_ci%func_t = OpTypeFunction %void
2888fd4e5da5Sopenharmony_ci%func = OpFunction %void None %func_t
2889fd4e5da5Sopenharmony_ci%1 = OpLabel
2890fd4e5da5Sopenharmony_ciOpReturn
2891fd4e5da5Sopenharmony_ciOpFunctionEnd
2892fd4e5da5Sopenharmony_ci)";
2893fd4e5da5Sopenharmony_ci
2894fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
2895fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
2896fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
2897fd4e5da5Sopenharmony_ci              AnyVUID("VUID-StandaloneSpirv-OpTypeRuntimeArray-04680"));
2898fd4e5da5Sopenharmony_ci  EXPECT_THAT(
2899fd4e5da5Sopenharmony_ci      getDiagnosticString(),
2900fd4e5da5Sopenharmony_ci      HasSubstr(
2901fd4e5da5Sopenharmony_ci          "OpTypeRuntimeArray Element Type <id> '5[%_runtimearr_uint]' is not "
2902fd4e5da5Sopenharmony_ci          "valid in Vulkan environments.\n  %_runtimearr__runtimearr_uint = "
2903fd4e5da5Sopenharmony_ci          "OpTypeRuntimeArray %_runtimearr_uint\n"));
2904fd4e5da5Sopenharmony_ci}
2905fd4e5da5Sopenharmony_ci
2906fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory,
2907fd4e5da5Sopenharmony_ci       VulkanRTAInsideRTAInsideStructWithRuntimeDescriptorArrayBad) {
2908fd4e5da5Sopenharmony_ci  std::string spirv = R"(
2909fd4e5da5Sopenharmony_ciOpCapability RuntimeDescriptorArrayEXT
2910fd4e5da5Sopenharmony_ciOpCapability Shader
2911fd4e5da5Sopenharmony_ciOpExtension "SPV_EXT_descriptor_indexing"
2912fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
2913fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %func "func"
2914fd4e5da5Sopenharmony_ciOpExecutionMode %func OriginUpperLeft
2915fd4e5da5Sopenharmony_ciOpDecorate %array_t ArrayStride 4
2916fd4e5da5Sopenharmony_ciOpMemberDecorate %struct_t 0 Offset 0
2917fd4e5da5Sopenharmony_ciOpDecorate %struct_t Block
2918fd4e5da5Sopenharmony_ci%uint_t = OpTypeInt 32 0
2919fd4e5da5Sopenharmony_ci%inner_array_t = OpTypeRuntimeArray %uint_t
2920fd4e5da5Sopenharmony_ci%array_t = OpTypeRuntimeArray %inner_array_t
2921fd4e5da5Sopenharmony_ci%struct_t = OpTypeStruct %array_t
2922fd4e5da5Sopenharmony_ci%struct_ptr = OpTypePointer StorageBuffer %struct_t
2923fd4e5da5Sopenharmony_ci%2 = OpVariable %struct_ptr StorageBuffer
2924fd4e5da5Sopenharmony_ci%void = OpTypeVoid
2925fd4e5da5Sopenharmony_ci%func_t = OpTypeFunction %void
2926fd4e5da5Sopenharmony_ci%func = OpFunction %void None %func_t
2927fd4e5da5Sopenharmony_ci%1 = OpLabel
2928fd4e5da5Sopenharmony_ciOpReturn
2929fd4e5da5Sopenharmony_ciOpFunctionEnd
2930fd4e5da5Sopenharmony_ci)";
2931fd4e5da5Sopenharmony_ci
2932fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
2933fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
2934fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
2935fd4e5da5Sopenharmony_ci              AnyVUID("VUID-StandaloneSpirv-OpTypeRuntimeArray-04680"));
2936fd4e5da5Sopenharmony_ci  EXPECT_THAT(
2937fd4e5da5Sopenharmony_ci      getDiagnosticString(),
2938fd4e5da5Sopenharmony_ci      HasSubstr(
2939fd4e5da5Sopenharmony_ci          "OpTypeRuntimeArray Element Type <id> '5[%_runtimearr_uint]' is not "
2940fd4e5da5Sopenharmony_ci          "valid in Vulkan environments.\n  %_runtimearr__runtimearr_uint = "
2941fd4e5da5Sopenharmony_ci          "OpTypeRuntimeArray %_runtimearr_uint\n"));
2942fd4e5da5Sopenharmony_ci}
2943fd4e5da5Sopenharmony_ci
2944fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, VulkanRTAInsideArrayBad) {
2945fd4e5da5Sopenharmony_ci  std::string spirv = R"(
2946fd4e5da5Sopenharmony_ciOpCapability Shader
2947fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
2948fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %func "func"
2949fd4e5da5Sopenharmony_ciOpExecutionMode %func OriginUpperLeft
2950fd4e5da5Sopenharmony_ci%uint_t = OpTypeInt 32 0
2951fd4e5da5Sopenharmony_ci%dim = OpConstant %uint_t 1
2952fd4e5da5Sopenharmony_ci%sampler_t = OpTypeSampler
2953fd4e5da5Sopenharmony_ci%inner_array_t = OpTypeRuntimeArray %sampler_t
2954fd4e5da5Sopenharmony_ci%array_t = OpTypeArray %inner_array_t %dim
2955fd4e5da5Sopenharmony_ci%array_ptr = OpTypePointer UniformConstant %array_t
2956fd4e5da5Sopenharmony_ci%2 = OpVariable %array_ptr UniformConstant
2957fd4e5da5Sopenharmony_ci%void = OpTypeVoid
2958fd4e5da5Sopenharmony_ci%func_t = OpTypeFunction %void
2959fd4e5da5Sopenharmony_ci%func = OpFunction %void None %func_t
2960fd4e5da5Sopenharmony_ci%1 = OpLabel
2961fd4e5da5Sopenharmony_ciOpReturn
2962fd4e5da5Sopenharmony_ciOpFunctionEnd
2963fd4e5da5Sopenharmony_ci)";
2964fd4e5da5Sopenharmony_ci
2965fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
2966fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
2967fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
2968fd4e5da5Sopenharmony_ci              AnyVUID("VUID-StandaloneSpirv-OpTypeRuntimeArray-04680"));
2969fd4e5da5Sopenharmony_ci  EXPECT_THAT(
2970fd4e5da5Sopenharmony_ci      getDiagnosticString(),
2971fd4e5da5Sopenharmony_ci      HasSubstr("OpTypeArray Element Type <id> '5[%_runtimearr_4]' is not "
2972fd4e5da5Sopenharmony_ci                "valid in Vulkan environments.\n  %_arr__runtimearr_4_uint_1 = "
2973fd4e5da5Sopenharmony_ci                "OpTypeArray %_runtimearr_4 %uint_1\n"));
2974fd4e5da5Sopenharmony_ci}
2975fd4e5da5Sopenharmony_ci
2976fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, VulkanRTAInsideArrayWithRuntimeDescriptorArrayBad) {
2977fd4e5da5Sopenharmony_ci  std::string spirv = R"(
2978fd4e5da5Sopenharmony_ciOpCapability RuntimeDescriptorArrayEXT
2979fd4e5da5Sopenharmony_ciOpCapability Shader
2980fd4e5da5Sopenharmony_ciOpExtension "SPV_EXT_descriptor_indexing"
2981fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
2982fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %func "func"
2983fd4e5da5Sopenharmony_ciOpExecutionMode %func OriginUpperLeft
2984fd4e5da5Sopenharmony_ciOpDecorate %struct Block
2985fd4e5da5Sopenharmony_ci%uint_t = OpTypeInt 32 0
2986fd4e5da5Sopenharmony_ci%dim = OpConstant %uint_t 1
2987fd4e5da5Sopenharmony_ci%sampler_t = OpTypeSampler
2988fd4e5da5Sopenharmony_ci%inner_array_t = OpTypeRuntimeArray %uint_t
2989fd4e5da5Sopenharmony_ci%array_t = OpTypeRuntimeArray %inner_array_t
2990fd4e5da5Sopenharmony_ci%struct = OpTypeStruct %array_t
2991fd4e5da5Sopenharmony_ci%array_ptr = OpTypePointer StorageBuffer %struct
2992fd4e5da5Sopenharmony_ci%2 = OpVariable %array_ptr StorageBuffer
2993fd4e5da5Sopenharmony_ci%void = OpTypeVoid
2994fd4e5da5Sopenharmony_ci%func_t = OpTypeFunction %void
2995fd4e5da5Sopenharmony_ci%func = OpFunction %void None %func_t
2996fd4e5da5Sopenharmony_ci%1 = OpLabel
2997fd4e5da5Sopenharmony_ciOpReturn
2998fd4e5da5Sopenharmony_ciOpFunctionEnd
2999fd4e5da5Sopenharmony_ci)";
3000fd4e5da5Sopenharmony_ci
3001fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
3002fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
3003fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
3004fd4e5da5Sopenharmony_ci              AnyVUID("VUID-StandaloneSpirv-OpTypeRuntimeArray-04680"));
3005fd4e5da5Sopenharmony_ci  EXPECT_THAT(
3006fd4e5da5Sopenharmony_ci      getDiagnosticString(),
3007fd4e5da5Sopenharmony_ci      HasSubstr(
3008fd4e5da5Sopenharmony_ci          "OpTypeRuntimeArray Element Type <id> '6[%_runtimearr_uint]' is not "
3009fd4e5da5Sopenharmony_ci          "valid in Vulkan environments.\n  %_runtimearr__runtimearr_uint = "
3010fd4e5da5Sopenharmony_ci          "OpTypeRuntimeArray %_runtimearr_uint\n"));
3011fd4e5da5Sopenharmony_ci}
3012fd4e5da5Sopenharmony_ci
3013fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, VulkanRTAInsideArrayInsideStructBad) {
3014fd4e5da5Sopenharmony_ci  std::string spirv = R"(
3015fd4e5da5Sopenharmony_ciOpCapability Shader
3016fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
3017fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %func "func"
3018fd4e5da5Sopenharmony_ciOpExecutionMode %func OriginUpperLeft
3019fd4e5da5Sopenharmony_ciOpDecorate %array_t ArrayStride 4
3020fd4e5da5Sopenharmony_ciOpMemberDecorate %struct_t 0 Offset 0
3021fd4e5da5Sopenharmony_ciOpDecorate %struct_t Block
3022fd4e5da5Sopenharmony_ci%uint_t = OpTypeInt 32 0
3023fd4e5da5Sopenharmony_ci%dim = OpConstant %uint_t 1
3024fd4e5da5Sopenharmony_ci%inner_array_t = OpTypeRuntimeArray %uint_t
3025fd4e5da5Sopenharmony_ci%array_t = OpTypeArray %inner_array_t %dim
3026fd4e5da5Sopenharmony_ci%struct_t = OpTypeStruct %array_t
3027fd4e5da5Sopenharmony_ci%struct_ptr = OpTypePointer StorageBuffer %struct_t
3028fd4e5da5Sopenharmony_ci%2 = OpVariable %struct_ptr StorageBuffer
3029fd4e5da5Sopenharmony_ci%void = OpTypeVoid
3030fd4e5da5Sopenharmony_ci%func_t = OpTypeFunction %void
3031fd4e5da5Sopenharmony_ci%func = OpFunction %void None %func_t
3032fd4e5da5Sopenharmony_ci%1 = OpLabel
3033fd4e5da5Sopenharmony_ciOpReturn
3034fd4e5da5Sopenharmony_ciOpFunctionEnd
3035fd4e5da5Sopenharmony_ci)";
3036fd4e5da5Sopenharmony_ci
3037fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
3038fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
3039fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
3040fd4e5da5Sopenharmony_ci              AnyVUID("VUID-StandaloneSpirv-OpTypeRuntimeArray-04680"));
3041fd4e5da5Sopenharmony_ci  EXPECT_THAT(
3042fd4e5da5Sopenharmony_ci      getDiagnosticString(),
3043fd4e5da5Sopenharmony_ci      HasSubstr(
3044fd4e5da5Sopenharmony_ci          "OpTypeArray Element Type <id> '6[%_runtimearr_uint]' is not "
3045fd4e5da5Sopenharmony_ci          "valid in Vulkan environments.\n  %_arr__runtimearr_uint_uint_1 "
3046fd4e5da5Sopenharmony_ci          "= OpTypeArray %_runtimearr_uint %uint_1\n"));
3047fd4e5da5Sopenharmony_ci}
3048fd4e5da5Sopenharmony_ci
3049fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory,
3050fd4e5da5Sopenharmony_ci       VulkanRTAInsideArrayInsideStructWithRuntimeDescriptorArrayBad) {
3051fd4e5da5Sopenharmony_ci  std::string spirv = R"(
3052fd4e5da5Sopenharmony_ciOpCapability RuntimeDescriptorArrayEXT
3053fd4e5da5Sopenharmony_ciOpCapability Shader
3054fd4e5da5Sopenharmony_ciOpExtension "SPV_EXT_descriptor_indexing"
3055fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
3056fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %func "func"
3057fd4e5da5Sopenharmony_ciOpExecutionMode %func OriginUpperLeft
3058fd4e5da5Sopenharmony_ciOpDecorate %array_t ArrayStride 4
3059fd4e5da5Sopenharmony_ciOpMemberDecorate %struct_t 0 Offset 0
3060fd4e5da5Sopenharmony_ciOpDecorate %struct_t Block
3061fd4e5da5Sopenharmony_ci%uint_t = OpTypeInt 32 0
3062fd4e5da5Sopenharmony_ci%dim = OpConstant %uint_t 1
3063fd4e5da5Sopenharmony_ci%inner_array_t = OpTypeRuntimeArray %uint_t
3064fd4e5da5Sopenharmony_ci%array_t = OpTypeArray %inner_array_t %dim
3065fd4e5da5Sopenharmony_ci%struct_t = OpTypeStruct %array_t
3066fd4e5da5Sopenharmony_ci%struct_ptr = OpTypePointer StorageBuffer %struct_t
3067fd4e5da5Sopenharmony_ci%2 = OpVariable %struct_ptr StorageBuffer
3068fd4e5da5Sopenharmony_ci%void = OpTypeVoid
3069fd4e5da5Sopenharmony_ci%func_t = OpTypeFunction %void
3070fd4e5da5Sopenharmony_ci%func = OpFunction %void None %func_t
3071fd4e5da5Sopenharmony_ci%1 = OpLabel
3072fd4e5da5Sopenharmony_ciOpReturn
3073fd4e5da5Sopenharmony_ciOpFunctionEnd
3074fd4e5da5Sopenharmony_ci)";
3075fd4e5da5Sopenharmony_ci
3076fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
3077fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
3078fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
3079fd4e5da5Sopenharmony_ci              AnyVUID("VUID-StandaloneSpirv-OpTypeRuntimeArray-04680"));
3080fd4e5da5Sopenharmony_ci  EXPECT_THAT(
3081fd4e5da5Sopenharmony_ci      getDiagnosticString(),
3082fd4e5da5Sopenharmony_ci      HasSubstr(
3083fd4e5da5Sopenharmony_ci          "OpTypeArray Element Type <id> '6[%_runtimearr_uint]' is not "
3084fd4e5da5Sopenharmony_ci          "valid in Vulkan environments.\n  %_arr__runtimearr_uint_uint_1 "
3085fd4e5da5Sopenharmony_ci          "= OpTypeArray %_runtimearr_uint %uint_1\n"));
3086fd4e5da5Sopenharmony_ci}
3087fd4e5da5Sopenharmony_ci
3088fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, VulkanRTAStructInsideRTAWithRuntimeDescriptorArrayGood) {
3089fd4e5da5Sopenharmony_ci  std::string spirv = R"(
3090fd4e5da5Sopenharmony_ciOpCapability RuntimeDescriptorArrayEXT
3091fd4e5da5Sopenharmony_ciOpCapability Shader
3092fd4e5da5Sopenharmony_ciOpExtension "SPV_EXT_descriptor_indexing"
3093fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
3094fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %func "func"
3095fd4e5da5Sopenharmony_ciOpExecutionMode %func OriginUpperLeft
3096fd4e5da5Sopenharmony_ciOpDecorate %inner_array_t ArrayStride 4
3097fd4e5da5Sopenharmony_ciOpDecorate %array_t ArrayStride 4
3098fd4e5da5Sopenharmony_ciOpMemberDecorate %struct_t 0 Offset 0
3099fd4e5da5Sopenharmony_ciOpDecorate %struct_t Block
3100fd4e5da5Sopenharmony_ci%uint_t = OpTypeInt 32 0
3101fd4e5da5Sopenharmony_ci%inner_array_t = OpTypeRuntimeArray %uint_t
3102fd4e5da5Sopenharmony_ci%struct_t = OpTypeStruct %inner_array_t
3103fd4e5da5Sopenharmony_ci%array_t = OpTypeRuntimeArray %struct_t
3104fd4e5da5Sopenharmony_ci%array_ptr = OpTypePointer StorageBuffer %array_t
3105fd4e5da5Sopenharmony_ci%2 = OpVariable %array_ptr StorageBuffer
3106fd4e5da5Sopenharmony_ci%void = OpTypeVoid
3107fd4e5da5Sopenharmony_ci%func_t = OpTypeFunction %void
3108fd4e5da5Sopenharmony_ci%func = OpFunction %void None %func_t
3109fd4e5da5Sopenharmony_ci%1 = OpLabel
3110fd4e5da5Sopenharmony_ciOpReturn
3111fd4e5da5Sopenharmony_ciOpFunctionEnd
3112fd4e5da5Sopenharmony_ci)";
3113fd4e5da5Sopenharmony_ci
3114fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
3115fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
3116fd4e5da5Sopenharmony_ci}
3117fd4e5da5Sopenharmony_ci
3118fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, VulkanRTAStructInsideArrayGood) {
3119fd4e5da5Sopenharmony_ci  std::string spirv = R"(
3120fd4e5da5Sopenharmony_ciOpCapability RuntimeDescriptorArrayEXT
3121fd4e5da5Sopenharmony_ciOpCapability Shader
3122fd4e5da5Sopenharmony_ciOpExtension "SPV_EXT_descriptor_indexing"
3123fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
3124fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %func "func"
3125fd4e5da5Sopenharmony_ciOpExecutionMode %func OriginUpperLeft
3126fd4e5da5Sopenharmony_ciOpDecorate %inner_array_t ArrayStride 4
3127fd4e5da5Sopenharmony_ciOpDecorate %array_t ArrayStride 4
3128fd4e5da5Sopenharmony_ciOpMemberDecorate %struct_t 0 Offset 0
3129fd4e5da5Sopenharmony_ciOpDecorate %struct_t Block
3130fd4e5da5Sopenharmony_ci%uint_t = OpTypeInt 32 0
3131fd4e5da5Sopenharmony_ci%inner_array_t = OpTypeRuntimeArray %uint_t
3132fd4e5da5Sopenharmony_ci%struct_t = OpTypeStruct %inner_array_t
3133fd4e5da5Sopenharmony_ci%array_size = OpConstant %uint_t 5
3134fd4e5da5Sopenharmony_ci%array_t = OpTypeArray %struct_t %array_size
3135fd4e5da5Sopenharmony_ci%array_ptr = OpTypePointer StorageBuffer %array_t
3136fd4e5da5Sopenharmony_ci%2 = OpVariable %array_ptr StorageBuffer
3137fd4e5da5Sopenharmony_ci%void = OpTypeVoid
3138fd4e5da5Sopenharmony_ci%func_t = OpTypeFunction %void
3139fd4e5da5Sopenharmony_ci%func = OpFunction %void None %func_t
3140fd4e5da5Sopenharmony_ci%1 = OpLabel
3141fd4e5da5Sopenharmony_ciOpReturn
3142fd4e5da5Sopenharmony_ciOpFunctionEnd
3143fd4e5da5Sopenharmony_ci)";
3144fd4e5da5Sopenharmony_ci
3145fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
3146fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
3147fd4e5da5Sopenharmony_ci}
3148fd4e5da5Sopenharmony_ci
3149fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, CopyMemoryNoAccessGood) {
3150fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
3151fd4e5da5Sopenharmony_ciOpCapability Shader
3152fd4e5da5Sopenharmony_ciOpCapability Linkage
3153fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
3154fd4e5da5Sopenharmony_ci%void = OpTypeVoid
3155fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
3156fd4e5da5Sopenharmony_ci%int_ptr_priv = OpTypePointer Private %int
3157fd4e5da5Sopenharmony_ci%var1 = OpVariable %int_ptr_priv Private
3158fd4e5da5Sopenharmony_ci%var2 = OpVariable %int_ptr_priv Private
3159fd4e5da5Sopenharmony_ci%voidfn = OpTypeFunction %void
3160fd4e5da5Sopenharmony_ci%func = OpFunction %void None %voidfn
3161fd4e5da5Sopenharmony_ci%entry = OpLabel
3162fd4e5da5Sopenharmony_ciOpCopyMemory %var1 %var2
3163fd4e5da5Sopenharmony_ciOpReturn
3164fd4e5da5Sopenharmony_ciOpFunctionEnd
3165fd4e5da5Sopenharmony_ci)";
3166fd4e5da5Sopenharmony_ci
3167fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv);
3168fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
3169fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(), Eq(""));
3170fd4e5da5Sopenharmony_ci}
3171fd4e5da5Sopenharmony_ci
3172fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, CopyMemorySimpleMixedAccessGood) {
3173fd4e5da5Sopenharmony_ci  // Test one memory access operand using features that don't require the
3174fd4e5da5Sopenharmony_ci  // Vulkan memory model.
3175fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
3176fd4e5da5Sopenharmony_ciOpCapability Shader
3177fd4e5da5Sopenharmony_ciOpCapability Linkage
3178fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
3179fd4e5da5Sopenharmony_ci%void = OpTypeVoid
3180fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
3181fd4e5da5Sopenharmony_ci%int_ptr_priv = OpTypePointer Private %int
3182fd4e5da5Sopenharmony_ci%var1 = OpVariable %int_ptr_priv Private
3183fd4e5da5Sopenharmony_ci%var2 = OpVariable %int_ptr_priv Private
3184fd4e5da5Sopenharmony_ci%voidfn = OpTypeFunction %void
3185fd4e5da5Sopenharmony_ci%func = OpFunction %void None %voidfn
3186fd4e5da5Sopenharmony_ci%entry = OpLabel
3187fd4e5da5Sopenharmony_ciOpCopyMemory %var1 %var2 Volatile|Aligned|Nontemporal 4
3188fd4e5da5Sopenharmony_ciOpReturn
3189fd4e5da5Sopenharmony_ciOpFunctionEnd
3190fd4e5da5Sopenharmony_ci)";
3191fd4e5da5Sopenharmony_ci
3192fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv);
3193fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
3194fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(), Eq(""));
3195fd4e5da5Sopenharmony_ci}
3196fd4e5da5Sopenharmony_ci
3197fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, CopyMemorySimpleTwoMixedAccessV13Bad) {
3198fd4e5da5Sopenharmony_ci  // Two memory access operands is invalid up to SPIR-V 1.3
3199fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
3200fd4e5da5Sopenharmony_ciOpCapability Shader
3201fd4e5da5Sopenharmony_ciOpCapability Linkage
3202fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
3203fd4e5da5Sopenharmony_ci%void = OpTypeVoid
3204fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
3205fd4e5da5Sopenharmony_ci%int_ptr_priv = OpTypePointer Private %int
3206fd4e5da5Sopenharmony_ci%var1 = OpVariable %int_ptr_priv Private
3207fd4e5da5Sopenharmony_ci%var2 = OpVariable %int_ptr_priv Private
3208fd4e5da5Sopenharmony_ci%voidfn = OpTypeFunction %void
3209fd4e5da5Sopenharmony_ci%func = OpFunction %void None %voidfn
3210fd4e5da5Sopenharmony_ci%entry = OpLabel
3211fd4e5da5Sopenharmony_ciOpCopyMemory %var1 %var2 Volatile Volatile
3212fd4e5da5Sopenharmony_ciOpReturn
3213fd4e5da5Sopenharmony_ciOpFunctionEnd
3214fd4e5da5Sopenharmony_ci)";
3215fd4e5da5Sopenharmony_ci
3216fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
3217fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_DATA,
3218fd4e5da5Sopenharmony_ci            ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
3219fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
3220fd4e5da5Sopenharmony_ci              HasSubstr("CopyMemory with two memory access operands requires "
3221fd4e5da5Sopenharmony_ci                        "SPIR-V 1.4 or later"));
3222fd4e5da5Sopenharmony_ci}
3223fd4e5da5Sopenharmony_ci
3224fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, CopyMemorySimpleTwoMixedAccessV14Good) {
3225fd4e5da5Sopenharmony_ci  // Two memory access operands is valid in SPIR-V 1.4
3226fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
3227fd4e5da5Sopenharmony_ciOpCapability Shader
3228fd4e5da5Sopenharmony_ciOpCapability Linkage
3229fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
3230fd4e5da5Sopenharmony_ci%void = OpTypeVoid
3231fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
3232fd4e5da5Sopenharmony_ci%int_ptr_priv = OpTypePointer Private %int
3233fd4e5da5Sopenharmony_ci%var1 = OpVariable %int_ptr_priv Private
3234fd4e5da5Sopenharmony_ci%var2 = OpVariable %int_ptr_priv Private
3235fd4e5da5Sopenharmony_ci%voidfn = OpTypeFunction %void
3236fd4e5da5Sopenharmony_ci%func = OpFunction %void None %voidfn
3237fd4e5da5Sopenharmony_ci%entry = OpLabel
3238fd4e5da5Sopenharmony_ciOpCopyMemory %var1 %var2 Volatile Volatile
3239fd4e5da5Sopenharmony_ciOpReturn
3240fd4e5da5Sopenharmony_ciOpFunctionEnd
3241fd4e5da5Sopenharmony_ci)";
3242fd4e5da5Sopenharmony_ci
3243fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
3244fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
3245fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(), Eq(""));
3246fd4e5da5Sopenharmony_ci}
3247fd4e5da5Sopenharmony_ci
3248fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, CopyMemorySizedNoAccessGood) {
3249fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
3250fd4e5da5Sopenharmony_ciOpCapability Shader
3251fd4e5da5Sopenharmony_ciOpCapability Linkage
3252fd4e5da5Sopenharmony_ciOpCapability Addresses
3253fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
3254fd4e5da5Sopenharmony_ci%void = OpTypeVoid
3255fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
3256fd4e5da5Sopenharmony_ci%int_16 = OpConstant %int 16
3257fd4e5da5Sopenharmony_ci%int_ptr_priv = OpTypePointer Private %int
3258fd4e5da5Sopenharmony_ci%var1 = OpVariable %int_ptr_priv Private
3259fd4e5da5Sopenharmony_ci%var2 = OpVariable %int_ptr_priv Private
3260fd4e5da5Sopenharmony_ci%voidfn = OpTypeFunction %void
3261fd4e5da5Sopenharmony_ci%func = OpFunction %void None %voidfn
3262fd4e5da5Sopenharmony_ci%entry = OpLabel
3263fd4e5da5Sopenharmony_ciOpCopyMemorySized %var1 %var2 %int_16
3264fd4e5da5Sopenharmony_ciOpReturn
3265fd4e5da5Sopenharmony_ciOpFunctionEnd
3266fd4e5da5Sopenharmony_ci)";
3267fd4e5da5Sopenharmony_ci
3268fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv);
3269fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
3270fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(), Eq(""));
3271fd4e5da5Sopenharmony_ci}
3272fd4e5da5Sopenharmony_ci
3273fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, CopyMemorySizedSimpleMixedAccessGood) {
3274fd4e5da5Sopenharmony_ci  // Test one memory access operand using features that don't require the
3275fd4e5da5Sopenharmony_ci  // Vulkan memory model.
3276fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
3277fd4e5da5Sopenharmony_ciOpCapability Shader
3278fd4e5da5Sopenharmony_ciOpCapability Linkage
3279fd4e5da5Sopenharmony_ciOpCapability Addresses
3280fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
3281fd4e5da5Sopenharmony_ci%void = OpTypeVoid
3282fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
3283fd4e5da5Sopenharmony_ci%int_16 = OpConstant %int 16
3284fd4e5da5Sopenharmony_ci%int_ptr_priv = OpTypePointer Private %int
3285fd4e5da5Sopenharmony_ci%var1 = OpVariable %int_ptr_priv Private
3286fd4e5da5Sopenharmony_ci%var2 = OpVariable %int_ptr_priv Private
3287fd4e5da5Sopenharmony_ci%voidfn = OpTypeFunction %void
3288fd4e5da5Sopenharmony_ci%func = OpFunction %void None %voidfn
3289fd4e5da5Sopenharmony_ci%entry = OpLabel
3290fd4e5da5Sopenharmony_ciOpCopyMemorySized %var1 %var2 %int_16 Volatile|Aligned|Nontemporal 4
3291fd4e5da5Sopenharmony_ciOpReturn
3292fd4e5da5Sopenharmony_ciOpFunctionEnd
3293fd4e5da5Sopenharmony_ci)";
3294fd4e5da5Sopenharmony_ci
3295fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv);
3296fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3297fd4e5da5Sopenharmony_ci}
3298fd4e5da5Sopenharmony_ci
3299fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, CopyMemorySizedSimpleTwoMixedAccessV13Bad) {
3300fd4e5da5Sopenharmony_ci  // Two memory access operands is invalid up to SPIR-V 1.3
3301fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
3302fd4e5da5Sopenharmony_ciOpCapability Shader
3303fd4e5da5Sopenharmony_ciOpCapability Linkage
3304fd4e5da5Sopenharmony_ciOpCapability Addresses
3305fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
3306fd4e5da5Sopenharmony_ci%void = OpTypeVoid
3307fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
3308fd4e5da5Sopenharmony_ci%int_16 = OpConstant %int 16
3309fd4e5da5Sopenharmony_ci%int_ptr_priv = OpTypePointer Private %int
3310fd4e5da5Sopenharmony_ci%var1 = OpVariable %int_ptr_priv Private
3311fd4e5da5Sopenharmony_ci%var2 = OpVariable %int_ptr_priv Private
3312fd4e5da5Sopenharmony_ci%voidfn = OpTypeFunction %void
3313fd4e5da5Sopenharmony_ci%func = OpFunction %void None %voidfn
3314fd4e5da5Sopenharmony_ci%entry = OpLabel
3315fd4e5da5Sopenharmony_ciOpCopyMemorySized %var1 %var2 %int_16 Volatile Volatile
3316fd4e5da5Sopenharmony_ciOpReturn
3317fd4e5da5Sopenharmony_ciOpFunctionEnd
3318fd4e5da5Sopenharmony_ci)";
3319fd4e5da5Sopenharmony_ci
3320fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
3321fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_DATA,
3322fd4e5da5Sopenharmony_ci            ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
3323fd4e5da5Sopenharmony_ci  EXPECT_THAT(
3324fd4e5da5Sopenharmony_ci      getDiagnosticString(),
3325fd4e5da5Sopenharmony_ci      HasSubstr("CopyMemorySized with two memory access operands requires "
3326fd4e5da5Sopenharmony_ci                "SPIR-V 1.4 or later"));
3327fd4e5da5Sopenharmony_ci}
3328fd4e5da5Sopenharmony_ci
3329fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, CopyMemorySizedSimpleTwoMixedAccessV14Good) {
3330fd4e5da5Sopenharmony_ci  // Two memory access operands is valid in SPIR-V 1.4
3331fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
3332fd4e5da5Sopenharmony_ciOpCapability Shader
3333fd4e5da5Sopenharmony_ciOpCapability Linkage
3334fd4e5da5Sopenharmony_ciOpCapability Addresses
3335fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
3336fd4e5da5Sopenharmony_ci%void = OpTypeVoid
3337fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
3338fd4e5da5Sopenharmony_ci%int_16 = OpConstant %int 16
3339fd4e5da5Sopenharmony_ci%int_ptr_priv = OpTypePointer Private %int
3340fd4e5da5Sopenharmony_ci%var1 = OpVariable %int_ptr_priv Private
3341fd4e5da5Sopenharmony_ci%var2 = OpVariable %int_ptr_priv Private
3342fd4e5da5Sopenharmony_ci%voidfn = OpTypeFunction %void
3343fd4e5da5Sopenharmony_ci%func = OpFunction %void None %voidfn
3344fd4e5da5Sopenharmony_ci%entry = OpLabel
3345fd4e5da5Sopenharmony_ciOpCopyMemorySized %var1 %var2 %int_16 Volatile Volatile
3346fd4e5da5Sopenharmony_ciOpReturn
3347fd4e5da5Sopenharmony_ciOpFunctionEnd
3348fd4e5da5Sopenharmony_ci)";
3349fd4e5da5Sopenharmony_ci
3350fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
3351fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
3352fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(), Eq(""));
3353fd4e5da5Sopenharmony_ci}
3354fd4e5da5Sopenharmony_ci
3355fd4e5da5Sopenharmony_ciusing ValidatePointerComparisons = spvtest::ValidateBase<std::string>;
3356fd4e5da5Sopenharmony_ci
3357fd4e5da5Sopenharmony_ciTEST_P(ValidatePointerComparisons, Good) {
3358fd4e5da5Sopenharmony_ci  const std::string operation = GetParam();
3359fd4e5da5Sopenharmony_ci
3360fd4e5da5Sopenharmony_ci  std::string spirv = R"(
3361fd4e5da5Sopenharmony_ciOpCapability Shader
3362fd4e5da5Sopenharmony_ciOpCapability Linkage
3363fd4e5da5Sopenharmony_ciOpCapability VariablePointersStorageBuffer
3364fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
3365fd4e5da5Sopenharmony_ci%void = OpTypeVoid
3366fd4e5da5Sopenharmony_ci%bool = OpTypeBool
3367fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
3368fd4e5da5Sopenharmony_ci%ptr_int = OpTypePointer StorageBuffer %int
3369fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_int StorageBuffer
3370fd4e5da5Sopenharmony_ci%func_ty = OpTypeFunction %void
3371fd4e5da5Sopenharmony_ci%func = OpFunction %void None %func_ty
3372fd4e5da5Sopenharmony_ci%1 = OpLabel
3373fd4e5da5Sopenharmony_ci%equal = )" + operation;
3374fd4e5da5Sopenharmony_ci
3375fd4e5da5Sopenharmony_ci  if (operation == "OpPtrDiff") {
3376fd4e5da5Sopenharmony_ci    spirv += " %int ";
3377fd4e5da5Sopenharmony_ci  } else {
3378fd4e5da5Sopenharmony_ci    spirv += " %bool ";
3379fd4e5da5Sopenharmony_ci  }
3380fd4e5da5Sopenharmony_ci
3381fd4e5da5Sopenharmony_ci  spirv += R"(%var %var
3382fd4e5da5Sopenharmony_ciOpReturn
3383fd4e5da5Sopenharmony_ciOpFunctionEnd
3384fd4e5da5Sopenharmony_ci)";
3385fd4e5da5Sopenharmony_ci
3386fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
3387fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
3388fd4e5da5Sopenharmony_ci}
3389fd4e5da5Sopenharmony_ci
3390fd4e5da5Sopenharmony_ciTEST_P(ValidatePointerComparisons, GoodWorkgroup) {
3391fd4e5da5Sopenharmony_ci  const std::string operation = GetParam();
3392fd4e5da5Sopenharmony_ci
3393fd4e5da5Sopenharmony_ci  std::string spirv = R"(
3394fd4e5da5Sopenharmony_ciOpCapability Shader
3395fd4e5da5Sopenharmony_ciOpCapability Linkage
3396fd4e5da5Sopenharmony_ciOpCapability VariablePointers
3397fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
3398fd4e5da5Sopenharmony_ci%void = OpTypeVoid
3399fd4e5da5Sopenharmony_ci%bool = OpTypeBool
3400fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
3401fd4e5da5Sopenharmony_ci%ptr_int = OpTypePointer Workgroup %int
3402fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_int Workgroup
3403fd4e5da5Sopenharmony_ci%func_ty = OpTypeFunction %void
3404fd4e5da5Sopenharmony_ci%func = OpFunction %void None %func_ty
3405fd4e5da5Sopenharmony_ci%1 = OpLabel
3406fd4e5da5Sopenharmony_ci%equal = )" + operation;
3407fd4e5da5Sopenharmony_ci
3408fd4e5da5Sopenharmony_ci  if (operation == "OpPtrDiff") {
3409fd4e5da5Sopenharmony_ci    spirv += " %int ";
3410fd4e5da5Sopenharmony_ci  } else {
3411fd4e5da5Sopenharmony_ci    spirv += " %bool ";
3412fd4e5da5Sopenharmony_ci  }
3413fd4e5da5Sopenharmony_ci
3414fd4e5da5Sopenharmony_ci  spirv += R"(%var %var
3415fd4e5da5Sopenharmony_ciOpReturn
3416fd4e5da5Sopenharmony_ciOpFunctionEnd
3417fd4e5da5Sopenharmony_ci)";
3418fd4e5da5Sopenharmony_ci
3419fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
3420fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
3421fd4e5da5Sopenharmony_ci}
3422fd4e5da5Sopenharmony_ci
3423fd4e5da5Sopenharmony_ciTEST_P(ValidatePointerComparisons, BadResultType) {
3424fd4e5da5Sopenharmony_ci  const std::string operation = GetParam();
3425fd4e5da5Sopenharmony_ci
3426fd4e5da5Sopenharmony_ci  std::string spirv = R"(
3427fd4e5da5Sopenharmony_ciOpCapability Shader
3428fd4e5da5Sopenharmony_ciOpCapability Linkage
3429fd4e5da5Sopenharmony_ciOpCapability VariablePointersStorageBuffer
3430fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
3431fd4e5da5Sopenharmony_ci%void = OpTypeVoid
3432fd4e5da5Sopenharmony_ci%bool = OpTypeBool
3433fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
3434fd4e5da5Sopenharmony_ci%ptr_int = OpTypePointer StorageBuffer %int
3435fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_int StorageBuffer
3436fd4e5da5Sopenharmony_ci%func_ty = OpTypeFunction %void
3437fd4e5da5Sopenharmony_ci%func = OpFunction %void None %func_ty
3438fd4e5da5Sopenharmony_ci%1 = OpLabel
3439fd4e5da5Sopenharmony_ci%equal = )" + operation;
3440fd4e5da5Sopenharmony_ci
3441fd4e5da5Sopenharmony_ci  if (operation == "OpPtrDiff") {
3442fd4e5da5Sopenharmony_ci    spirv += " %bool ";
3443fd4e5da5Sopenharmony_ci  } else {
3444fd4e5da5Sopenharmony_ci    spirv += " %int ";
3445fd4e5da5Sopenharmony_ci  }
3446fd4e5da5Sopenharmony_ci
3447fd4e5da5Sopenharmony_ci  spirv += R"(%var %var
3448fd4e5da5Sopenharmony_ciOpReturn
3449fd4e5da5Sopenharmony_ciOpFunctionEnd
3450fd4e5da5Sopenharmony_ci)";
3451fd4e5da5Sopenharmony_ci
3452fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
3453fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
3454fd4e5da5Sopenharmony_ci  if (operation == "OpPtrDiff") {
3455fd4e5da5Sopenharmony_ci    EXPECT_THAT(getDiagnosticString(),
3456fd4e5da5Sopenharmony_ci                HasSubstr("Result Type must be an integer scalar"));
3457fd4e5da5Sopenharmony_ci  } else {
3458fd4e5da5Sopenharmony_ci    EXPECT_THAT(getDiagnosticString(),
3459fd4e5da5Sopenharmony_ci                HasSubstr("Result Type must be OpTypeBool"));
3460fd4e5da5Sopenharmony_ci  }
3461fd4e5da5Sopenharmony_ci}
3462fd4e5da5Sopenharmony_ci
3463fd4e5da5Sopenharmony_ciTEST_P(ValidatePointerComparisons, BadCapabilities) {
3464fd4e5da5Sopenharmony_ci  const std::string operation = GetParam();
3465fd4e5da5Sopenharmony_ci
3466fd4e5da5Sopenharmony_ci  std::string spirv = R"(
3467fd4e5da5Sopenharmony_ciOpCapability Shader
3468fd4e5da5Sopenharmony_ciOpCapability Linkage
3469fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
3470fd4e5da5Sopenharmony_ci%void = OpTypeVoid
3471fd4e5da5Sopenharmony_ci%bool = OpTypeBool
3472fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
3473fd4e5da5Sopenharmony_ci%ptr_int = OpTypePointer StorageBuffer %int
3474fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_int StorageBuffer
3475fd4e5da5Sopenharmony_ci%func_ty = OpTypeFunction %void
3476fd4e5da5Sopenharmony_ci%func = OpFunction %void None %func_ty
3477fd4e5da5Sopenharmony_ci%1 = OpLabel
3478fd4e5da5Sopenharmony_ci%equal = )" + operation;
3479fd4e5da5Sopenharmony_ci
3480fd4e5da5Sopenharmony_ci  if (operation == "OpPtrDiff") {
3481fd4e5da5Sopenharmony_ci    spirv += " %int ";
3482fd4e5da5Sopenharmony_ci  } else {
3483fd4e5da5Sopenharmony_ci    spirv += " %bool ";
3484fd4e5da5Sopenharmony_ci  }
3485fd4e5da5Sopenharmony_ci
3486fd4e5da5Sopenharmony_ci  spirv += R"(%var %var
3487fd4e5da5Sopenharmony_ciOpReturn
3488fd4e5da5Sopenharmony_ciOpFunctionEnd
3489fd4e5da5Sopenharmony_ci)";
3490fd4e5da5Sopenharmony_ci
3491fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
3492fd4e5da5Sopenharmony_ci  if (operation == "OpPtrDiff") {
3493fd4e5da5Sopenharmony_ci    // Gets caught by the grammar.
3494fd4e5da5Sopenharmony_ci    EXPECT_EQ(SPV_ERROR_INVALID_CAPABILITY,
3495fd4e5da5Sopenharmony_ci              ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
3496fd4e5da5Sopenharmony_ci  } else {
3497fd4e5da5Sopenharmony_ci    EXPECT_EQ(SPV_ERROR_INVALID_ID,
3498fd4e5da5Sopenharmony_ci              ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
3499fd4e5da5Sopenharmony_ci    EXPECT_THAT(getDiagnosticString(),
3500fd4e5da5Sopenharmony_ci                HasSubstr("Instruction cannot for logical addressing model be "
3501fd4e5da5Sopenharmony_ci                          "used without a variable pointers capability"));
3502fd4e5da5Sopenharmony_ci  }
3503fd4e5da5Sopenharmony_ci}
3504fd4e5da5Sopenharmony_ci
3505fd4e5da5Sopenharmony_ciTEST_P(ValidatePointerComparisons, BadOperandType) {
3506fd4e5da5Sopenharmony_ci  const std::string operation = GetParam();
3507fd4e5da5Sopenharmony_ci
3508fd4e5da5Sopenharmony_ci  std::string spirv = R"(
3509fd4e5da5Sopenharmony_ciOpCapability Shader
3510fd4e5da5Sopenharmony_ciOpCapability Linkage
3511fd4e5da5Sopenharmony_ciOpCapability VariablePointersStorageBuffer
3512fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
3513fd4e5da5Sopenharmony_ci%void = OpTypeVoid
3514fd4e5da5Sopenharmony_ci%bool = OpTypeBool
3515fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
3516fd4e5da5Sopenharmony_ci%ptr_int = OpTypePointer StorageBuffer %int
3517fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_int StorageBuffer
3518fd4e5da5Sopenharmony_ci%func_ty = OpTypeFunction %void
3519fd4e5da5Sopenharmony_ci%func = OpFunction %void None %func_ty
3520fd4e5da5Sopenharmony_ci%1 = OpLabel
3521fd4e5da5Sopenharmony_ci%ld = OpLoad %int %var
3522fd4e5da5Sopenharmony_ci%equal = )" + operation;
3523fd4e5da5Sopenharmony_ci
3524fd4e5da5Sopenharmony_ci  if (operation == "OpPtrDiff") {
3525fd4e5da5Sopenharmony_ci    spirv += " %int ";
3526fd4e5da5Sopenharmony_ci  } else {
3527fd4e5da5Sopenharmony_ci    spirv += " %bool ";
3528fd4e5da5Sopenharmony_ci  }
3529fd4e5da5Sopenharmony_ci
3530fd4e5da5Sopenharmony_ci  spirv += R"(%ld %ld
3531fd4e5da5Sopenharmony_ciOpReturn
3532fd4e5da5Sopenharmony_ciOpFunctionEnd
3533fd4e5da5Sopenharmony_ci)";
3534fd4e5da5Sopenharmony_ci
3535fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
3536fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
3537fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
3538fd4e5da5Sopenharmony_ci              HasSubstr("Operand type must be a pointer"));
3539fd4e5da5Sopenharmony_ci}
3540fd4e5da5Sopenharmony_ci
3541fd4e5da5Sopenharmony_ciTEST_P(ValidatePointerComparisons, BadStorageClassWorkgroup) {
3542fd4e5da5Sopenharmony_ci  const std::string operation = GetParam();
3543fd4e5da5Sopenharmony_ci
3544fd4e5da5Sopenharmony_ci  std::string spirv = R"(
3545fd4e5da5Sopenharmony_ciOpCapability Shader
3546fd4e5da5Sopenharmony_ciOpCapability Linkage
3547fd4e5da5Sopenharmony_ciOpCapability VariablePointersStorageBuffer
3548fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
3549fd4e5da5Sopenharmony_ci%void = OpTypeVoid
3550fd4e5da5Sopenharmony_ci%bool = OpTypeBool
3551fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
3552fd4e5da5Sopenharmony_ci%ptr_int = OpTypePointer Workgroup %int
3553fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_int Workgroup
3554fd4e5da5Sopenharmony_ci%func_ty = OpTypeFunction %void
3555fd4e5da5Sopenharmony_ci%func = OpFunction %void None %func_ty
3556fd4e5da5Sopenharmony_ci%1 = OpLabel
3557fd4e5da5Sopenharmony_ci%equal = )" + operation;
3558fd4e5da5Sopenharmony_ci
3559fd4e5da5Sopenharmony_ci  if (operation == "OpPtrDiff") {
3560fd4e5da5Sopenharmony_ci    spirv += " %int ";
3561fd4e5da5Sopenharmony_ci  } else {
3562fd4e5da5Sopenharmony_ci    spirv += " %bool ";
3563fd4e5da5Sopenharmony_ci  }
3564fd4e5da5Sopenharmony_ci
3565fd4e5da5Sopenharmony_ci  spirv += R"(%var %var
3566fd4e5da5Sopenharmony_ciOpReturn
3567fd4e5da5Sopenharmony_ciOpFunctionEnd
3568fd4e5da5Sopenharmony_ci)";
3569fd4e5da5Sopenharmony_ci
3570fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
3571fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
3572fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
3573fd4e5da5Sopenharmony_ci              HasSubstr("Workgroup storage class pointer requires "
3574fd4e5da5Sopenharmony_ci                        "VariablePointers capability to be specified"));
3575fd4e5da5Sopenharmony_ci}
3576fd4e5da5Sopenharmony_ci
3577fd4e5da5Sopenharmony_ciTEST_P(ValidatePointerComparisons, BadStorageClass) {
3578fd4e5da5Sopenharmony_ci  const std::string operation = GetParam();
3579fd4e5da5Sopenharmony_ci
3580fd4e5da5Sopenharmony_ci  std::string spirv = R"(
3581fd4e5da5Sopenharmony_ciOpCapability Shader
3582fd4e5da5Sopenharmony_ciOpCapability Linkage
3583fd4e5da5Sopenharmony_ciOpCapability VariablePointersStorageBuffer
3584fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
3585fd4e5da5Sopenharmony_ci%void = OpTypeVoid
3586fd4e5da5Sopenharmony_ci%bool = OpTypeBool
3587fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
3588fd4e5da5Sopenharmony_ci%ptr_int = OpTypePointer Private %int
3589fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_int Private
3590fd4e5da5Sopenharmony_ci%func_ty = OpTypeFunction %void
3591fd4e5da5Sopenharmony_ci%func = OpFunction %void None %func_ty
3592fd4e5da5Sopenharmony_ci%1 = OpLabel
3593fd4e5da5Sopenharmony_ci%equal = )" + operation;
3594fd4e5da5Sopenharmony_ci
3595fd4e5da5Sopenharmony_ci  if (operation == "OpPtrDiff") {
3596fd4e5da5Sopenharmony_ci    spirv += " %int ";
3597fd4e5da5Sopenharmony_ci  } else {
3598fd4e5da5Sopenharmony_ci    spirv += " %bool ";
3599fd4e5da5Sopenharmony_ci  }
3600fd4e5da5Sopenharmony_ci
3601fd4e5da5Sopenharmony_ci  spirv += R"(%var %var
3602fd4e5da5Sopenharmony_ciOpReturn
3603fd4e5da5Sopenharmony_ciOpFunctionEnd
3604fd4e5da5Sopenharmony_ci)";
3605fd4e5da5Sopenharmony_ci
3606fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
3607fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
3608fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
3609fd4e5da5Sopenharmony_ci              HasSubstr("Invalid pointer storage class"));
3610fd4e5da5Sopenharmony_ci}
3611fd4e5da5Sopenharmony_ci
3612fd4e5da5Sopenharmony_ciTEST_P(ValidatePointerComparisons, BadDiffOperandTypes) {
3613fd4e5da5Sopenharmony_ci  const std::string operation = GetParam();
3614fd4e5da5Sopenharmony_ci
3615fd4e5da5Sopenharmony_ci  std::string spirv = R"(
3616fd4e5da5Sopenharmony_ciOpCapability Shader
3617fd4e5da5Sopenharmony_ciOpCapability Linkage
3618fd4e5da5Sopenharmony_ciOpCapability VariablePointersStorageBuffer
3619fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
3620fd4e5da5Sopenharmony_ci%void = OpTypeVoid
3621fd4e5da5Sopenharmony_ci%bool = OpTypeBool
3622fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
3623fd4e5da5Sopenharmony_ci%ptr_int = OpTypePointer Private %int
3624fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_int Private
3625fd4e5da5Sopenharmony_ci%func_ty = OpTypeFunction %void
3626fd4e5da5Sopenharmony_ci%func = OpFunction %void None %func_ty
3627fd4e5da5Sopenharmony_ci%1 = OpLabel
3628fd4e5da5Sopenharmony_ci%ld = OpLoad %int %var
3629fd4e5da5Sopenharmony_ci%equal = )" + operation;
3630fd4e5da5Sopenharmony_ci
3631fd4e5da5Sopenharmony_ci  if (operation == "OpPtrDiff") {
3632fd4e5da5Sopenharmony_ci    spirv += " %int ";
3633fd4e5da5Sopenharmony_ci  } else {
3634fd4e5da5Sopenharmony_ci    spirv += " %bool ";
3635fd4e5da5Sopenharmony_ci  }
3636fd4e5da5Sopenharmony_ci
3637fd4e5da5Sopenharmony_ci  spirv += R"(%var %ld
3638fd4e5da5Sopenharmony_ciOpReturn
3639fd4e5da5Sopenharmony_ciOpFunctionEnd
3640fd4e5da5Sopenharmony_ci)";
3641fd4e5da5Sopenharmony_ci
3642fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
3643fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
3644fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
3645fd4e5da5Sopenharmony_ci              HasSubstr("The types of Operand 1 and Operand 2 must match"));
3646fd4e5da5Sopenharmony_ci}
3647fd4e5da5Sopenharmony_ci
3648fd4e5da5Sopenharmony_ciINSTANTIATE_TEST_SUITE_P(PointerComparisons, ValidatePointerComparisons,
3649fd4e5da5Sopenharmony_ci                         Values("OpPtrEqual", "OpPtrNotEqual", "OpPtrDiff"));
3650fd4e5da5Sopenharmony_ci
3651fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, VariableInitializerWrongType) {
3652fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
3653fd4e5da5Sopenharmony_ciOpCapability Shader
3654fd4e5da5Sopenharmony_ciOpCapability Linkage
3655fd4e5da5Sopenharmony_ciOpCapability VariablePointersStorageBuffer
3656fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
3657fd4e5da5Sopenharmony_ci%void = OpTypeVoid
3658fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
3659fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
3660fd4e5da5Sopenharmony_ci%ptr_wg_int = OpTypePointer Workgroup %int
3661fd4e5da5Sopenharmony_ci%ptr_wg_float = OpTypePointer Workgroup %int
3662fd4e5da5Sopenharmony_ci%wg_var = OpVariable %ptr_wg_int Workgroup
3663fd4e5da5Sopenharmony_ci%ptr_private_wg_float = OpTypePointer Private %ptr_wg_float
3664fd4e5da5Sopenharmony_ci%priv_var = OpVariable %ptr_private_wg_float Private %wg_var
3665fd4e5da5Sopenharmony_ci)";
3666fd4e5da5Sopenharmony_ci
3667fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
3668fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
3669fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
3670fd4e5da5Sopenharmony_ci              HasSubstr("Initializer type must match the type pointed to by "
3671fd4e5da5Sopenharmony_ci                        "the Result Type"));
3672fd4e5da5Sopenharmony_ci}
3673fd4e5da5Sopenharmony_ci
3674fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, StoreToUniformBlock) {
3675fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
3676fd4e5da5Sopenharmony_ciOpCapability Shader
3677fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
3678fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %main "main"
3679fd4e5da5Sopenharmony_ciOpExecutionMode %main LocalSize 1 1 1
3680fd4e5da5Sopenharmony_ciOpDecorate %struct Block
3681fd4e5da5Sopenharmony_ciOpMemberDecorate %struct 0 Offset 0
3682fd4e5da5Sopenharmony_ciOpDecorate %var DescriptorSet 0
3683fd4e5da5Sopenharmony_ciOpDecorate %var Binding 0
3684fd4e5da5Sopenharmony_ci%void = OpTypeVoid
3685fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
3686fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0
3687fd4e5da5Sopenharmony_ci%int4 = OpTypeVector %int 4
3688fd4e5da5Sopenharmony_ci%struct = OpTypeStruct %int4
3689fd4e5da5Sopenharmony_ci%ptr_uniform_struct = OpTypePointer Uniform %struct
3690fd4e5da5Sopenharmony_ci%ptr_uniform_int4 = OpTypePointer Uniform %int4
3691fd4e5da5Sopenharmony_ci%ptr_uniform_int = OpTypePointer Uniform %int
3692fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_uniform_struct Uniform
3693fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void
3694fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn
3695fd4e5da5Sopenharmony_ci%entry = OpLabel
3696fd4e5da5Sopenharmony_ci%gep1 = OpAccessChain %ptr_uniform_int4 %var %int_0
3697fd4e5da5Sopenharmony_ci%gep2 = OpAccessChain %ptr_uniform_int %gep1 %int_0
3698fd4e5da5Sopenharmony_ciOpStore %gep2 %int_0
3699fd4e5da5Sopenharmony_ciOpReturn
3700fd4e5da5Sopenharmony_ciOpFunctionEnd
3701fd4e5da5Sopenharmony_ci)";
3702fd4e5da5Sopenharmony_ci
3703fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv);
3704fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
3705fd4e5da5Sopenharmony_ci}
3706fd4e5da5Sopenharmony_ci
3707fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, StoreToUniformBlockVulkan) {
3708fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
3709fd4e5da5Sopenharmony_ciOpCapability Shader
3710fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
3711fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %main "main"
3712fd4e5da5Sopenharmony_ciOpExecutionMode %main LocalSize 1 1 1
3713fd4e5da5Sopenharmony_ciOpDecorate %struct Block
3714fd4e5da5Sopenharmony_ciOpMemberDecorate %struct 0 Offset 0
3715fd4e5da5Sopenharmony_ciOpDecorate %var DescriptorSet 0
3716fd4e5da5Sopenharmony_ciOpDecorate %var Binding 0
3717fd4e5da5Sopenharmony_ci%void = OpTypeVoid
3718fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
3719fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0
3720fd4e5da5Sopenharmony_ci%int4 = OpTypeVector %int 4
3721fd4e5da5Sopenharmony_ci%struct = OpTypeStruct %int4
3722fd4e5da5Sopenharmony_ci%ptr_uniform_struct = OpTypePointer Uniform %struct
3723fd4e5da5Sopenharmony_ci%ptr_uniform_int4 = OpTypePointer Uniform %int4
3724fd4e5da5Sopenharmony_ci%ptr_uniform_int = OpTypePointer Uniform %int
3725fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_uniform_struct Uniform
3726fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void
3727fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn
3728fd4e5da5Sopenharmony_ci%entry = OpLabel
3729fd4e5da5Sopenharmony_ci%gep1 = OpAccessChain %ptr_uniform_int4 %var %int_0
3730fd4e5da5Sopenharmony_ci%gep2 = OpAccessChain %ptr_uniform_int %gep1 %int_0
3731fd4e5da5Sopenharmony_ciOpStore %gep2 %int_0
3732fd4e5da5Sopenharmony_ciOpReturn
3733fd4e5da5Sopenharmony_ciOpFunctionEnd
3734fd4e5da5Sopenharmony_ci)";
3735fd4e5da5Sopenharmony_ci
3736fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
3737fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
3738fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
3739fd4e5da5Sopenharmony_ci              AnyVUID("VUID-StandaloneSpirv-Uniform-06925"));
3740fd4e5da5Sopenharmony_ci  EXPECT_THAT(
3741fd4e5da5Sopenharmony_ci      getDiagnosticString(),
3742fd4e5da5Sopenharmony_ci      HasSubstr("In the Vulkan environment, cannot store to Uniform Blocks"));
3743fd4e5da5Sopenharmony_ci}
3744fd4e5da5Sopenharmony_ci
3745fd4e5da5Sopenharmony_ci// This test requires that the struct is not id 2.
3746fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, StoreToUniformBlockVulkan2) {
3747fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
3748fd4e5da5Sopenharmony_ciOpCapability Shader
3749fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
3750fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %main "main" %gid_var
3751fd4e5da5Sopenharmony_ciOpExecutionMode %main LocalSize 1 1 1
3752fd4e5da5Sopenharmony_ciOpDecorate %3 Block
3753fd4e5da5Sopenharmony_ciOpMemberDecorate %3 0 Offset 0
3754fd4e5da5Sopenharmony_ciOpDecorate %var DescriptorSet 0
3755fd4e5da5Sopenharmony_ciOpDecorate %var Binding 0
3756fd4e5da5Sopenharmony_ciOpDecorate %gid_var BuiltIn GlobalInvocationId
3757fd4e5da5Sopenharmony_ci%void = OpTypeVoid
3758fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
3759fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0
3760fd4e5da5Sopenharmony_ci%int3 = OpTypeVector %int 3
3761fd4e5da5Sopenharmony_ci%int4 = OpTypeVector %int 4
3762fd4e5da5Sopenharmony_ci%3 = OpTypeStruct %int4
3763fd4e5da5Sopenharmony_ci%ptr_uniform_struct = OpTypePointer Uniform %3
3764fd4e5da5Sopenharmony_ci%ptr_uniform_int4 = OpTypePointer Uniform %int4
3765fd4e5da5Sopenharmony_ci%ptr_uniform_int = OpTypePointer Uniform %int
3766fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_uniform_struct Uniform
3767fd4e5da5Sopenharmony_ci%ptr_input_int3 = OpTypePointer Input %int3
3768fd4e5da5Sopenharmony_ci%gid_var = OpVariable %ptr_input_int3 Input
3769fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void
3770fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn
3771fd4e5da5Sopenharmony_ci%entry = OpLabel
3772fd4e5da5Sopenharmony_ci%gep1 = OpAccessChain %ptr_uniform_int4 %var %int_0
3773fd4e5da5Sopenharmony_ci%gep2 = OpAccessChain %ptr_uniform_int %gep1 %int_0
3774fd4e5da5Sopenharmony_ciOpStore %gep2 %int_0
3775fd4e5da5Sopenharmony_ciOpReturn
3776fd4e5da5Sopenharmony_ciOpFunctionEnd
3777fd4e5da5Sopenharmony_ci)";
3778fd4e5da5Sopenharmony_ci
3779fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
3780fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
3781fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
3782fd4e5da5Sopenharmony_ci              AnyVUID("VUID-StandaloneSpirv-Uniform-06925"));
3783fd4e5da5Sopenharmony_ci  EXPECT_THAT(
3784fd4e5da5Sopenharmony_ci      getDiagnosticString(),
3785fd4e5da5Sopenharmony_ci      HasSubstr("In the Vulkan environment, cannot store to Uniform Blocks"));
3786fd4e5da5Sopenharmony_ci}
3787fd4e5da5Sopenharmony_ci
3788fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, StoreToUniformBufferBlockVulkan) {
3789fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
3790fd4e5da5Sopenharmony_ciOpCapability Shader
3791fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
3792fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %main "main"
3793fd4e5da5Sopenharmony_ciOpExecutionMode %main LocalSize 1 1 1
3794fd4e5da5Sopenharmony_ciOpDecorate %struct BufferBlock
3795fd4e5da5Sopenharmony_ciOpMemberDecorate %struct 0 Offset 0
3796fd4e5da5Sopenharmony_ciOpDecorate %var DescriptorSet 0
3797fd4e5da5Sopenharmony_ciOpDecorate %var Binding 0
3798fd4e5da5Sopenharmony_ci%void = OpTypeVoid
3799fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
3800fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0
3801fd4e5da5Sopenharmony_ci%int4 = OpTypeVector %int 4
3802fd4e5da5Sopenharmony_ci%struct = OpTypeStruct %int4
3803fd4e5da5Sopenharmony_ci%ptr_uniform_struct = OpTypePointer Uniform %struct
3804fd4e5da5Sopenharmony_ci%ptr_uniform_int4 = OpTypePointer Uniform %int4
3805fd4e5da5Sopenharmony_ci%ptr_uniform_int = OpTypePointer Uniform %int
3806fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_uniform_struct Uniform
3807fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void
3808fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn
3809fd4e5da5Sopenharmony_ci%entry = OpLabel
3810fd4e5da5Sopenharmony_ci%gep1 = OpAccessChain %ptr_uniform_int4 %var %int_0
3811fd4e5da5Sopenharmony_ci%gep2 = OpAccessChain %ptr_uniform_int %gep1 %int_0
3812fd4e5da5Sopenharmony_ciOpStore %gep2 %int_0
3813fd4e5da5Sopenharmony_ciOpReturn
3814fd4e5da5Sopenharmony_ciOpFunctionEnd
3815fd4e5da5Sopenharmony_ci)";
3816fd4e5da5Sopenharmony_ci
3817fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
3818fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
3819fd4e5da5Sopenharmony_ci}
3820fd4e5da5Sopenharmony_ci
3821fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, StoreToUniformBlockVulkanArray) {
3822fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
3823fd4e5da5Sopenharmony_ciOpCapability Shader
3824fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
3825fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %main "main"
3826fd4e5da5Sopenharmony_ciOpExecutionMode %main LocalSize 1 1 1
3827fd4e5da5Sopenharmony_ciOpDecorate %struct Block
3828fd4e5da5Sopenharmony_ciOpMemberDecorate %struct 0 Offset 0
3829fd4e5da5Sopenharmony_ciOpDecorate %var DescriptorSet 0
3830fd4e5da5Sopenharmony_ciOpDecorate %var Binding 0
3831fd4e5da5Sopenharmony_ci%void = OpTypeVoid
3832fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
3833fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0
3834fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1
3835fd4e5da5Sopenharmony_ci%int4 = OpTypeVector %int 4
3836fd4e5da5Sopenharmony_ci%struct = OpTypeStruct %int4
3837fd4e5da5Sopenharmony_ci%array_struct = OpTypeArray %struct %int_1
3838fd4e5da5Sopenharmony_ci%ptr_uniform_array = OpTypePointer Uniform %array_struct
3839fd4e5da5Sopenharmony_ci%ptr_uniform_struct = OpTypePointer Uniform %struct
3840fd4e5da5Sopenharmony_ci%ptr_uniform_int4 = OpTypePointer Uniform %int4
3841fd4e5da5Sopenharmony_ci%ptr_uniform_int = OpTypePointer Uniform %int
3842fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_uniform_array Uniform
3843fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void
3844fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn
3845fd4e5da5Sopenharmony_ci%entry = OpLabel
3846fd4e5da5Sopenharmony_ci%gep1 = OpAccessChain %ptr_uniform_int %var %int_0 %int_0 %int_0
3847fd4e5da5Sopenharmony_ci%gep2 = OpCopyObject %ptr_uniform_int %gep1
3848fd4e5da5Sopenharmony_ciOpStore %gep2 %int_0
3849fd4e5da5Sopenharmony_ciOpReturn
3850fd4e5da5Sopenharmony_ciOpFunctionEnd
3851fd4e5da5Sopenharmony_ci)";
3852fd4e5da5Sopenharmony_ci
3853fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
3854fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
3855fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
3856fd4e5da5Sopenharmony_ci              AnyVUID("VUID-StandaloneSpirv-Uniform-06925"));
3857fd4e5da5Sopenharmony_ci  EXPECT_THAT(
3858fd4e5da5Sopenharmony_ci      getDiagnosticString(),
3859fd4e5da5Sopenharmony_ci      HasSubstr("In the Vulkan environment, cannot store to Uniform Blocks"));
3860fd4e5da5Sopenharmony_ci}
3861fd4e5da5Sopenharmony_ci
3862fd4e5da5Sopenharmony_ci// This test requires that the struct is not id 2.
3863fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, StoreToUniformBlockVulkanArray2) {
3864fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
3865fd4e5da5Sopenharmony_ciOpCapability Shader
3866fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
3867fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %main "main" %gid_var
3868fd4e5da5Sopenharmony_ciOpExecutionMode %main LocalSize 1 1 1
3869fd4e5da5Sopenharmony_ciOpDecorate %struct Block
3870fd4e5da5Sopenharmony_ciOpMemberDecorate %struct 0 Offset 0
3871fd4e5da5Sopenharmony_ciOpDecorate %var DescriptorSet 0
3872fd4e5da5Sopenharmony_ciOpDecorate %var Binding 0
3873fd4e5da5Sopenharmony_ciOpDecorate %gid_var BuiltIn GlobalInvocationId
3874fd4e5da5Sopenharmony_ci%void = OpTypeVoid
3875fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
3876fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0
3877fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1
3878fd4e5da5Sopenharmony_ci%int3 = OpTypeVector %int 3
3879fd4e5da5Sopenharmony_ci%int4 = OpTypeVector %int 4
3880fd4e5da5Sopenharmony_ci%struct = OpTypeStruct %int4
3881fd4e5da5Sopenharmony_ci%array_struct = OpTypeArray %struct %int_1
3882fd4e5da5Sopenharmony_ci%ptr_uniform_array = OpTypePointer Uniform %array_struct
3883fd4e5da5Sopenharmony_ci%ptr_uniform_struct = OpTypePointer Uniform %struct
3884fd4e5da5Sopenharmony_ci%ptr_uniform_int4 = OpTypePointer Uniform %int4
3885fd4e5da5Sopenharmony_ci%ptr_uniform_int = OpTypePointer Uniform %int
3886fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_uniform_array Uniform
3887fd4e5da5Sopenharmony_ci%ptr_input_int3 = OpTypePointer Input %int3
3888fd4e5da5Sopenharmony_ci%gid_var = OpVariable %ptr_input_int3 Input
3889fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void
3890fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn
3891fd4e5da5Sopenharmony_ci%entry = OpLabel
3892fd4e5da5Sopenharmony_ci%gep1 = OpAccessChain %ptr_uniform_int %var %int_0 %int_0 %int_0
3893fd4e5da5Sopenharmony_ci%gep2 = OpCopyObject %ptr_uniform_int %gep1
3894fd4e5da5Sopenharmony_ciOpStore %gep2 %int_0
3895fd4e5da5Sopenharmony_ciOpReturn
3896fd4e5da5Sopenharmony_ciOpFunctionEnd
3897fd4e5da5Sopenharmony_ci)";
3898fd4e5da5Sopenharmony_ci
3899fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
3900fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
3901fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
3902fd4e5da5Sopenharmony_ci              AnyVUID("VUID-StandaloneSpirv-Uniform-06925"));
3903fd4e5da5Sopenharmony_ci  EXPECT_THAT(
3904fd4e5da5Sopenharmony_ci      getDiagnosticString(),
3905fd4e5da5Sopenharmony_ci      HasSubstr("In the Vulkan environment, cannot store to Uniform Blocks"));
3906fd4e5da5Sopenharmony_ci}
3907fd4e5da5Sopenharmony_ci
3908fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, StoreToUniformBlockVulkanRuntimeArray) {
3909fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
3910fd4e5da5Sopenharmony_ciOpCapability Shader
3911fd4e5da5Sopenharmony_ciOpCapability RuntimeDescriptorArrayEXT
3912fd4e5da5Sopenharmony_ciOpExtension "SPV_EXT_descriptor_indexing"
3913fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
3914fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %main "main"
3915fd4e5da5Sopenharmony_ciOpExecutionMode %main LocalSize 1 1 1
3916fd4e5da5Sopenharmony_ciOpDecorate %struct Block
3917fd4e5da5Sopenharmony_ciOpMemberDecorate %struct 0 Offset 0
3918fd4e5da5Sopenharmony_ciOpDecorate %var DescriptorSet 0
3919fd4e5da5Sopenharmony_ciOpDecorate %var Binding 0
3920fd4e5da5Sopenharmony_ci%void = OpTypeVoid
3921fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
3922fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0
3923fd4e5da5Sopenharmony_ci%int4 = OpTypeVector %int 4
3924fd4e5da5Sopenharmony_ci%struct = OpTypeStruct %int4
3925fd4e5da5Sopenharmony_ci%array_struct = OpTypeRuntimeArray %struct
3926fd4e5da5Sopenharmony_ci%ptr_uniform_array = OpTypePointer Uniform %array_struct
3927fd4e5da5Sopenharmony_ci%ptr_uniform_struct = OpTypePointer Uniform %struct
3928fd4e5da5Sopenharmony_ci%ptr_uniform_int4 = OpTypePointer Uniform %int4
3929fd4e5da5Sopenharmony_ci%ptr_uniform_int = OpTypePointer Uniform %int
3930fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_uniform_array Uniform
3931fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void
3932fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn
3933fd4e5da5Sopenharmony_ci%entry = OpLabel
3934fd4e5da5Sopenharmony_ci%gep1 = OpAccessChain %ptr_uniform_int4 %var %int_0 %int_0
3935fd4e5da5Sopenharmony_ci%gep2 = OpInBoundsAccessChain %ptr_uniform_int %gep1 %int_0
3936fd4e5da5Sopenharmony_ciOpStore %gep2 %int_0
3937fd4e5da5Sopenharmony_ciOpReturn
3938fd4e5da5Sopenharmony_ciOpFunctionEnd
3939fd4e5da5Sopenharmony_ci)";
3940fd4e5da5Sopenharmony_ci
3941fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
3942fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
3943fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
3944fd4e5da5Sopenharmony_ci              AnyVUID("VUID-StandaloneSpirv-Uniform-06925"));
3945fd4e5da5Sopenharmony_ci  EXPECT_THAT(
3946fd4e5da5Sopenharmony_ci      getDiagnosticString(),
3947fd4e5da5Sopenharmony_ci      HasSubstr("In the Vulkan environment, cannot store to Uniform Blocks"));
3948fd4e5da5Sopenharmony_ci}
3949fd4e5da5Sopenharmony_ci
3950fd4e5da5Sopenharmony_ciusing ValidateSizedVariable = spvtest::ValidateBase<
3951fd4e5da5Sopenharmony_ci    std::tuple<std::string, std::string, std::string, spv_target_env>>;
3952fd4e5da5Sopenharmony_ci
3953fd4e5da5Sopenharmony_ciCodeGenerator GetSizedVariableCodeGenerator(bool is_8bit, bool buffer_block) {
3954fd4e5da5Sopenharmony_ci  CodeGenerator generator;
3955fd4e5da5Sopenharmony_ci  generator.capabilities_ = "OpCapability Shader\nOpCapability Linkage\n";
3956fd4e5da5Sopenharmony_ci  generator.extensions_ =
3957fd4e5da5Sopenharmony_ci      "OpExtension \"SPV_KHR_16bit_storage\"\nOpExtension "
3958fd4e5da5Sopenharmony_ci      "\"SPV_KHR_8bit_storage\"\n";
3959fd4e5da5Sopenharmony_ci  generator.memory_model_ = "OpMemoryModel Logical GLSL450\n";
3960fd4e5da5Sopenharmony_ci  if (is_8bit) {
3961fd4e5da5Sopenharmony_ci    generator.before_types_ =
3962fd4e5da5Sopenharmony_ci        "OpMemberDecorate %char_buffer_block 0 Offset 0\n";
3963fd4e5da5Sopenharmony_ci    if (buffer_block)
3964fd4e5da5Sopenharmony_ci      generator.before_types_ += "OpDecorate %char_buffer_block BufferBlock\n";
3965fd4e5da5Sopenharmony_ci
3966fd4e5da5Sopenharmony_ci    generator.types_ = R"(%void = OpTypeVoid
3967fd4e5da5Sopenharmony_ci%char = OpTypeInt 8 0
3968fd4e5da5Sopenharmony_ci%char4 = OpTypeVector %char 4
3969fd4e5da5Sopenharmony_ci%char_buffer_block = OpTypeStruct %char
3970fd4e5da5Sopenharmony_ci)";
3971fd4e5da5Sopenharmony_ci  } else {
3972fd4e5da5Sopenharmony_ci    generator.before_types_ =
3973fd4e5da5Sopenharmony_ci        "OpMemberDecorate %half_buffer_block 0 Offset 0\n"
3974fd4e5da5Sopenharmony_ci        "OpMemberDecorate %short_buffer_block 0 Offset 0\n";
3975fd4e5da5Sopenharmony_ci    if (buffer_block) {
3976fd4e5da5Sopenharmony_ci      generator.before_types_ +=
3977fd4e5da5Sopenharmony_ci          "OpDecorate %half_buffer_block BufferBlock\n"
3978fd4e5da5Sopenharmony_ci          "OpDecorate %short_buffer_block BufferBlock\n";
3979fd4e5da5Sopenharmony_ci    }
3980fd4e5da5Sopenharmony_ci
3981fd4e5da5Sopenharmony_ci    generator.types_ = R"(%void = OpTypeVoid
3982fd4e5da5Sopenharmony_ci%short = OpTypeInt 16 0
3983fd4e5da5Sopenharmony_ci%half = OpTypeFloat 16
3984fd4e5da5Sopenharmony_ci%short4 = OpTypeVector %short 4
3985fd4e5da5Sopenharmony_ci%half4 = OpTypeVector %half 4
3986fd4e5da5Sopenharmony_ci%mat4x4 = OpTypeMatrix %half4 4
3987fd4e5da5Sopenharmony_ci%short_buffer_block = OpTypeStruct %short
3988fd4e5da5Sopenharmony_ci%half_buffer_block = OpTypeStruct %half
3989fd4e5da5Sopenharmony_ci)";
3990fd4e5da5Sopenharmony_ci  }
3991fd4e5da5Sopenharmony_ci  generator.after_types_ = R"(%void_fn = OpTypeFunction %void
3992fd4e5da5Sopenharmony_ci%func = OpFunction %void None %void_fn
3993fd4e5da5Sopenharmony_ci%entry = OpLabel
3994fd4e5da5Sopenharmony_ci)";
3995fd4e5da5Sopenharmony_ci  generator.add_at_the_end_ = "OpReturn\nOpFunctionEnd\n";
3996fd4e5da5Sopenharmony_ci  return generator;
3997fd4e5da5Sopenharmony_ci}
3998fd4e5da5Sopenharmony_ci
3999fd4e5da5Sopenharmony_ciTEST_P(ValidateSizedVariable, Capability) {
4000fd4e5da5Sopenharmony_ci  const std::string storage_class = std::get<0>(GetParam());
4001fd4e5da5Sopenharmony_ci  const std::string capability = std::get<1>(GetParam());
4002fd4e5da5Sopenharmony_ci  const std::string var_type = std::get<2>(GetParam());
4003fd4e5da5Sopenharmony_ci  const spv_target_env target = std::get<3>(GetParam());
4004fd4e5da5Sopenharmony_ci
4005fd4e5da5Sopenharmony_ci  ASSERT_TRUE(target == SPV_ENV_UNIVERSAL_1_3 ||
4006fd4e5da5Sopenharmony_ci              target == SPV_ENV_UNIVERSAL_1_4);
4007fd4e5da5Sopenharmony_ci
4008fd4e5da5Sopenharmony_ci  bool type_8bit = false;
4009fd4e5da5Sopenharmony_ci  if (var_type == "%char" || var_type == "%char4" ||
4010fd4e5da5Sopenharmony_ci      var_type == "%char_buffer_block") {
4011fd4e5da5Sopenharmony_ci    type_8bit = true;
4012fd4e5da5Sopenharmony_ci  }
4013fd4e5da5Sopenharmony_ci
4014fd4e5da5Sopenharmony_ci  const bool buffer_block = var_type.find("buffer_block") != std::string::npos;
4015fd4e5da5Sopenharmony_ci
4016fd4e5da5Sopenharmony_ci  auto generator = GetSizedVariableCodeGenerator(type_8bit, buffer_block);
4017fd4e5da5Sopenharmony_ci
4018fd4e5da5Sopenharmony_ci  if (capability == "WorkgroupMemoryExplicitLayout8BitAccessKHR" ||
4019fd4e5da5Sopenharmony_ci      capability == "WorkgroupMemoryExplicitLayout16BitAccessKHR") {
4020fd4e5da5Sopenharmony_ci    generator.extensions_ +=
4021fd4e5da5Sopenharmony_ci        "OpExtension \"SPV_KHR_workgroup_memory_explicit_layout\"\n";
4022fd4e5da5Sopenharmony_ci  }
4023fd4e5da5Sopenharmony_ci
4024fd4e5da5Sopenharmony_ci  generator.types_ += "%ptr_type = OpTypePointer " + storage_class + " " +
4025fd4e5da5Sopenharmony_ci                      var_type + "\n%var = OpVariable %ptr_type " +
4026fd4e5da5Sopenharmony_ci                      storage_class + "\n";
4027fd4e5da5Sopenharmony_ci  generator.capabilities_ += "OpCapability " + capability + "\n";
4028fd4e5da5Sopenharmony_ci
4029fd4e5da5Sopenharmony_ci  bool capability_ok = false;
4030fd4e5da5Sopenharmony_ci  bool storage_class_ok = false;
4031fd4e5da5Sopenharmony_ci  if (storage_class == "Input" || storage_class == "Output") {
4032fd4e5da5Sopenharmony_ci    if (!type_8bit) {
4033fd4e5da5Sopenharmony_ci      capability_ok = capability == "StorageInputOutput16";
4034fd4e5da5Sopenharmony_ci      storage_class_ok = true;
4035fd4e5da5Sopenharmony_ci    }
4036fd4e5da5Sopenharmony_ci  } else if (storage_class == "StorageBuffer") {
4037fd4e5da5Sopenharmony_ci    if (type_8bit) {
4038fd4e5da5Sopenharmony_ci      capability_ok = capability == "StorageBuffer8BitAccess" ||
4039fd4e5da5Sopenharmony_ci                      capability == "UniformAndStorageBuffer8BitAccess";
4040fd4e5da5Sopenharmony_ci    } else {
4041fd4e5da5Sopenharmony_ci      capability_ok = capability == "StorageBuffer16BitAccess" ||
4042fd4e5da5Sopenharmony_ci                      capability == "UniformAndStorageBuffer16BitAccess";
4043fd4e5da5Sopenharmony_ci    }
4044fd4e5da5Sopenharmony_ci    storage_class_ok = true;
4045fd4e5da5Sopenharmony_ci  } else if (storage_class == "PushConstant") {
4046fd4e5da5Sopenharmony_ci    if (type_8bit) {
4047fd4e5da5Sopenharmony_ci      capability_ok = capability == "StoragePushConstant8";
4048fd4e5da5Sopenharmony_ci    } else {
4049fd4e5da5Sopenharmony_ci      capability_ok = capability == "StoragePushConstant16";
4050fd4e5da5Sopenharmony_ci    }
4051fd4e5da5Sopenharmony_ci    storage_class_ok = true;
4052fd4e5da5Sopenharmony_ci  } else if (storage_class == "Uniform") {
4053fd4e5da5Sopenharmony_ci    if (type_8bit) {
4054fd4e5da5Sopenharmony_ci      capability_ok = capability == "UniformAndStorageBuffer8BitAccess" ||
4055fd4e5da5Sopenharmony_ci                      (capability == "StorageBuffer8BitAccess" && buffer_block);
4056fd4e5da5Sopenharmony_ci    } else {
4057fd4e5da5Sopenharmony_ci      capability_ok =
4058fd4e5da5Sopenharmony_ci          capability == "UniformAndStorageBuffer16BitAccess" ||
4059fd4e5da5Sopenharmony_ci          (capability == "StorageBuffer16BitAccess" && buffer_block);
4060fd4e5da5Sopenharmony_ci    }
4061fd4e5da5Sopenharmony_ci    storage_class_ok = true;
4062fd4e5da5Sopenharmony_ci  } else if (storage_class == "Workgroup") {
4063fd4e5da5Sopenharmony_ci    if (type_8bit) {
4064fd4e5da5Sopenharmony_ci      capability_ok =
4065fd4e5da5Sopenharmony_ci          capability == "WorkgroupMemoryExplicitLayout8BitAccessKHR";
4066fd4e5da5Sopenharmony_ci    } else {
4067fd4e5da5Sopenharmony_ci      capability_ok =
4068fd4e5da5Sopenharmony_ci          capability == "WorkgroupMemoryExplicitLayout16BitAccessKHR";
4069fd4e5da5Sopenharmony_ci    }
4070fd4e5da5Sopenharmony_ci    storage_class_ok = true;
4071fd4e5da5Sopenharmony_ci  }
4072fd4e5da5Sopenharmony_ci
4073fd4e5da5Sopenharmony_ci  CompileSuccessfully(generator.Build(), target);
4074fd4e5da5Sopenharmony_ci  spv_result_t result = ValidateInstructions(target);
4075fd4e5da5Sopenharmony_ci  if (target < SPV_ENV_UNIVERSAL_1_4 &&
4076fd4e5da5Sopenharmony_ci      (capability == "WorkgroupMemoryExplicitLayout8BitAccessKHR" ||
4077fd4e5da5Sopenharmony_ci       capability == "WorkgroupMemoryExplicitLayout16BitAccessKHR")) {
4078fd4e5da5Sopenharmony_ci    EXPECT_EQ(SPV_ERROR_WRONG_VERSION, result);
4079fd4e5da5Sopenharmony_ci    EXPECT_THAT(getDiagnosticString(),
4080fd4e5da5Sopenharmony_ci                HasSubstr("requires SPIR-V version 1.4 or later"));
4081fd4e5da5Sopenharmony_ci  } else if (buffer_block && target > SPV_ENV_UNIVERSAL_1_3) {
4082fd4e5da5Sopenharmony_ci    EXPECT_EQ(SPV_ERROR_WRONG_VERSION, result);
4083fd4e5da5Sopenharmony_ci    EXPECT_THAT(getDiagnosticString(),
4084fd4e5da5Sopenharmony_ci                HasSubstr("requires SPIR-V version 1.3 or earlier"));
4085fd4e5da5Sopenharmony_ci  } else if (capability_ok) {
4086fd4e5da5Sopenharmony_ci    EXPECT_EQ(SPV_SUCCESS, result);
4087fd4e5da5Sopenharmony_ci  } else {
4088fd4e5da5Sopenharmony_ci    EXPECT_EQ(SPV_ERROR_INVALID_ID, result);
4089fd4e5da5Sopenharmony_ci    if (storage_class_ok) {
4090fd4e5da5Sopenharmony_ci      std::string message = std::string("Allocating a variable containing a ") +
4091fd4e5da5Sopenharmony_ci                            (type_8bit ? "8" : "16") + "-bit element in " +
4092fd4e5da5Sopenharmony_ci                            storage_class +
4093fd4e5da5Sopenharmony_ci                            " storage class requires an additional capability";
4094fd4e5da5Sopenharmony_ci      EXPECT_THAT(getDiagnosticString(), HasSubstr(message));
4095fd4e5da5Sopenharmony_ci    } else {
4096fd4e5da5Sopenharmony_ci      std::string message =
4097fd4e5da5Sopenharmony_ci          std::string("Cannot allocate a variable containing a ") +
4098fd4e5da5Sopenharmony_ci          (type_8bit ? "8" : "16") + "-bit type in " + storage_class +
4099fd4e5da5Sopenharmony_ci          " storage class";
4100fd4e5da5Sopenharmony_ci      EXPECT_THAT(getDiagnosticString(), HasSubstr(message));
4101fd4e5da5Sopenharmony_ci    }
4102fd4e5da5Sopenharmony_ci  }
4103fd4e5da5Sopenharmony_ci}
4104fd4e5da5Sopenharmony_ci
4105fd4e5da5Sopenharmony_ciINSTANTIATE_TEST_SUITE_P(
4106fd4e5da5Sopenharmony_ci    Storage8, ValidateSizedVariable,
4107fd4e5da5Sopenharmony_ci    Combine(Values("UniformConstant", "Input", "Output", "Workgroup",
4108fd4e5da5Sopenharmony_ci                   "CrossWorkgroup", "Private", "StorageBuffer", "Uniform"),
4109fd4e5da5Sopenharmony_ci            Values("StorageBuffer8BitAccess",
4110fd4e5da5Sopenharmony_ci                   "UniformAndStorageBuffer8BitAccess", "StoragePushConstant8",
4111fd4e5da5Sopenharmony_ci                   "WorkgroupMemoryExplicitLayout8BitAccessKHR"),
4112fd4e5da5Sopenharmony_ci            Values("%char", "%char4", "%char_buffer_block"),
4113fd4e5da5Sopenharmony_ci            Values(SPV_ENV_UNIVERSAL_1_3, SPV_ENV_UNIVERSAL_1_4)));
4114fd4e5da5Sopenharmony_ci
4115fd4e5da5Sopenharmony_ciINSTANTIATE_TEST_SUITE_P(
4116fd4e5da5Sopenharmony_ci    Storage16, ValidateSizedVariable,
4117fd4e5da5Sopenharmony_ci    Combine(Values("UniformConstant", "Input", "Output", "Workgroup",
4118fd4e5da5Sopenharmony_ci                   "CrossWorkgroup", "Private", "StorageBuffer", "Uniform"),
4119fd4e5da5Sopenharmony_ci            Values("StorageBuffer16BitAccess",
4120fd4e5da5Sopenharmony_ci                   "UniformAndStorageBuffer16BitAccess",
4121fd4e5da5Sopenharmony_ci                   "StoragePushConstant16", "StorageInputOutput16",
4122fd4e5da5Sopenharmony_ci                   "WorkgroupMemoryExplicitLayout16BitAccessKHR"),
4123fd4e5da5Sopenharmony_ci            Values("%short", "%half", "%short4", "%half4", "%mat4x4",
4124fd4e5da5Sopenharmony_ci                   "%short_buffer_block", "%half_buffer_block"),
4125fd4e5da5Sopenharmony_ci            Values(SPV_ENV_UNIVERSAL_1_3, SPV_ENV_UNIVERSAL_1_4)));
4126fd4e5da5Sopenharmony_ci
4127fd4e5da5Sopenharmony_ciusing ValidateSizedLoadStore =
4128fd4e5da5Sopenharmony_ci    spvtest::ValidateBase<std::tuple<std::string, uint32_t, std::string>>;
4129fd4e5da5Sopenharmony_ci
4130fd4e5da5Sopenharmony_ciCodeGenerator GetSizedLoadStoreCodeGenerator(const std::string& base_type,
4131fd4e5da5Sopenharmony_ci                                             uint32_t width) {
4132fd4e5da5Sopenharmony_ci  CodeGenerator generator;
4133fd4e5da5Sopenharmony_ci  generator.capabilities_ = "OpCapability Shader\nOpCapability Linkage\n";
4134fd4e5da5Sopenharmony_ci  if (width == 8) {
4135fd4e5da5Sopenharmony_ci    generator.capabilities_ +=
4136fd4e5da5Sopenharmony_ci        "OpCapability UniformAndStorageBuffer8BitAccess\n";
4137fd4e5da5Sopenharmony_ci    generator.extensions_ = "OpExtension \"SPV_KHR_8bit_storage\"\n";
4138fd4e5da5Sopenharmony_ci  } else {
4139fd4e5da5Sopenharmony_ci    generator.capabilities_ +=
4140fd4e5da5Sopenharmony_ci        "OpCapability UniformAndStorageBuffer16BitAccess\n";
4141fd4e5da5Sopenharmony_ci    generator.extensions_ = "OpExtension \"SPV_KHR_16bit_storage\"\n";
4142fd4e5da5Sopenharmony_ci  }
4143fd4e5da5Sopenharmony_ci  generator.memory_model_ = "OpMemoryModel Logical GLSL450\n";
4144fd4e5da5Sopenharmony_ci  generator.before_types_ = R"(OpDecorate %block Block
4145fd4e5da5Sopenharmony_ciOpMemberDecorate %block 0 Offset 0
4146fd4e5da5Sopenharmony_ciOpMemberDecorate %struct 0 Offset 0
4147fd4e5da5Sopenharmony_ci)";
4148fd4e5da5Sopenharmony_ci  generator.types_ = R"(%void = OpTypeVoid
4149fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
4150fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0
4151fd4e5da5Sopenharmony_ci%int_1 = OpConstant %int 1
4152fd4e5da5Sopenharmony_ci%int_2 = OpConstant %int 2
4153fd4e5da5Sopenharmony_ci%int_3 = OpConstant %int 3
4154fd4e5da5Sopenharmony_ci)";
4155fd4e5da5Sopenharmony_ci
4156fd4e5da5Sopenharmony_ci  if (width == 8) {
4157fd4e5da5Sopenharmony_ci    generator.types_ += R"(%scalar = OpTypeInt 8 0
4158fd4e5da5Sopenharmony_ci%vector = OpTypeVector %scalar 4
4159fd4e5da5Sopenharmony_ci%struct = OpTypeStruct %vector
4160fd4e5da5Sopenharmony_ci)";
4161fd4e5da5Sopenharmony_ci  } else if (base_type == "int") {
4162fd4e5da5Sopenharmony_ci    generator.types_ += R"(%scalar = OpTypeInt 16 0
4163fd4e5da5Sopenharmony_ci%vector = OpTypeVector %scalar 4
4164fd4e5da5Sopenharmony_ci%struct = OpTypeStruct %vector
4165fd4e5da5Sopenharmony_ci)";
4166fd4e5da5Sopenharmony_ci  } else {
4167fd4e5da5Sopenharmony_ci    generator.types_ += R"(%scalar = OpTypeFloat 16
4168fd4e5da5Sopenharmony_ci%vector = OpTypeVector %scalar 4
4169fd4e5da5Sopenharmony_ci%matrix = OpTypeMatrix %vector 4
4170fd4e5da5Sopenharmony_ci%struct = OpTypeStruct %matrix
4171fd4e5da5Sopenharmony_ci%ptr_ssbo_matrix = OpTypePointer StorageBuffer %matrix
4172fd4e5da5Sopenharmony_ci)";
4173fd4e5da5Sopenharmony_ci    generator.before_types_ += R"(OpMemberDecorate %struct 0 RowMajor
4174fd4e5da5Sopenharmony_ciOpMemberDecorate %struct 0 MatrixStride 16
4175fd4e5da5Sopenharmony_ci)";
4176fd4e5da5Sopenharmony_ci  }
4177fd4e5da5Sopenharmony_ci  generator.types_ += R"(%block = OpTypeStruct %struct
4178fd4e5da5Sopenharmony_ci%ptr_ssbo_block = OpTypePointer StorageBuffer %block
4179fd4e5da5Sopenharmony_ci%ptr_ssbo_struct = OpTypePointer StorageBuffer %struct
4180fd4e5da5Sopenharmony_ci%ptr_ssbo_vector = OpTypePointer StorageBuffer %vector
4181fd4e5da5Sopenharmony_ci%ptr_ssbo_scalar = OpTypePointer StorageBuffer %scalar
4182fd4e5da5Sopenharmony_ci%ld_var = OpVariable %ptr_ssbo_block StorageBuffer
4183fd4e5da5Sopenharmony_ci%st_var = OpVariable %ptr_ssbo_block StorageBuffer
4184fd4e5da5Sopenharmony_ci)";
4185fd4e5da5Sopenharmony_ci
4186fd4e5da5Sopenharmony_ci  generator.after_types_ = R"(%void_fn = OpTypeFunction %void
4187fd4e5da5Sopenharmony_ci%func = OpFunction %void None %void_fn
4188fd4e5da5Sopenharmony_ci%entry = OpLabel
4189fd4e5da5Sopenharmony_ci)";
4190fd4e5da5Sopenharmony_ci  generator.add_at_the_end_ = "OpReturn\nOpFunctionEnd\n";
4191fd4e5da5Sopenharmony_ci  return generator;
4192fd4e5da5Sopenharmony_ci}
4193fd4e5da5Sopenharmony_ci
4194fd4e5da5Sopenharmony_ciTEST_P(ValidateSizedLoadStore, Load) {
4195fd4e5da5Sopenharmony_ci  std::string base_type = std::get<0>(GetParam());
4196fd4e5da5Sopenharmony_ci  uint32_t width = std::get<1>(GetParam());
4197fd4e5da5Sopenharmony_ci  std::string mem_type = std::get<2>(GetParam());
4198fd4e5da5Sopenharmony_ci
4199fd4e5da5Sopenharmony_ci  CodeGenerator generator = GetSizedLoadStoreCodeGenerator(base_type, width);
4200fd4e5da5Sopenharmony_ci  generator.after_types_ +=
4201fd4e5da5Sopenharmony_ci      "%ld_gep = OpAccessChain %ptr_ssbo_" + mem_type + " %ld_var %int_0";
4202fd4e5da5Sopenharmony_ci  if (mem_type != "struct") {
4203fd4e5da5Sopenharmony_ci    generator.after_types_ += " %int_0";
4204fd4e5da5Sopenharmony_ci    if (mem_type != "matrix" && base_type == "float") {
4205fd4e5da5Sopenharmony_ci      generator.after_types_ += " %int_0";
4206fd4e5da5Sopenharmony_ci    }
4207fd4e5da5Sopenharmony_ci    if (mem_type == "scalar") {
4208fd4e5da5Sopenharmony_ci      generator.after_types_ += " %int_0";
4209fd4e5da5Sopenharmony_ci    }
4210fd4e5da5Sopenharmony_ci  }
4211fd4e5da5Sopenharmony_ci  generator.after_types_ += "\n";
4212fd4e5da5Sopenharmony_ci  generator.after_types_ += "%ld = OpLoad %" + mem_type + " %ld_gep\n";
4213fd4e5da5Sopenharmony_ci
4214fd4e5da5Sopenharmony_ci  CompileSuccessfully(generator.Build(), SPV_ENV_UNIVERSAL_1_3);
4215fd4e5da5Sopenharmony_ci  if (mem_type == "struct") {
4216fd4e5da5Sopenharmony_ci    EXPECT_EQ(SPV_ERROR_INVALID_ID,
4217fd4e5da5Sopenharmony_ci              ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
4218fd4e5da5Sopenharmony_ci    EXPECT_THAT(
4219fd4e5da5Sopenharmony_ci        getDiagnosticString(),
4220fd4e5da5Sopenharmony_ci        HasSubstr(
4221fd4e5da5Sopenharmony_ci            "8- or 16-bit loads must be a scalar, vector or matrix type"));
4222fd4e5da5Sopenharmony_ci  } else {
4223fd4e5da5Sopenharmony_ci    EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
4224fd4e5da5Sopenharmony_ci  }
4225fd4e5da5Sopenharmony_ci}
4226fd4e5da5Sopenharmony_ci
4227fd4e5da5Sopenharmony_ciTEST_P(ValidateSizedLoadStore, Store) {
4228fd4e5da5Sopenharmony_ci  std::string base_type = std::get<0>(GetParam());
4229fd4e5da5Sopenharmony_ci  uint32_t width = std::get<1>(GetParam());
4230fd4e5da5Sopenharmony_ci  std::string mem_type = std::get<2>(GetParam());
4231fd4e5da5Sopenharmony_ci
4232fd4e5da5Sopenharmony_ci  CodeGenerator generator = GetSizedLoadStoreCodeGenerator(base_type, width);
4233fd4e5da5Sopenharmony_ci  generator.after_types_ +=
4234fd4e5da5Sopenharmony_ci      "%ld_gep = OpAccessChain %ptr_ssbo_" + mem_type + " %ld_var %int_0";
4235fd4e5da5Sopenharmony_ci  if (mem_type != "struct") {
4236fd4e5da5Sopenharmony_ci    generator.after_types_ += " %int_0";
4237fd4e5da5Sopenharmony_ci    if (mem_type != "matrix" && base_type == "float") {
4238fd4e5da5Sopenharmony_ci      generator.after_types_ += " %int_0";
4239fd4e5da5Sopenharmony_ci    }
4240fd4e5da5Sopenharmony_ci    if (mem_type == "scalar") {
4241fd4e5da5Sopenharmony_ci      generator.after_types_ += " %int_0";
4242fd4e5da5Sopenharmony_ci    }
4243fd4e5da5Sopenharmony_ci  }
4244fd4e5da5Sopenharmony_ci  generator.after_types_ += "\n";
4245fd4e5da5Sopenharmony_ci  generator.after_types_ += "%ld = OpLoad %" + mem_type + " %ld_gep\n";
4246fd4e5da5Sopenharmony_ci  generator.after_types_ +=
4247fd4e5da5Sopenharmony_ci      "%st_gep = OpAccessChain %ptr_ssbo_" + mem_type + " %st_var %int_0";
4248fd4e5da5Sopenharmony_ci  if (mem_type != "struct") {
4249fd4e5da5Sopenharmony_ci    generator.after_types_ += " %int_0";
4250fd4e5da5Sopenharmony_ci    if (mem_type != "matrix" && base_type == "float") {
4251fd4e5da5Sopenharmony_ci      generator.after_types_ += " %int_0";
4252fd4e5da5Sopenharmony_ci    }
4253fd4e5da5Sopenharmony_ci    if (mem_type == "scalar") {
4254fd4e5da5Sopenharmony_ci      generator.after_types_ += " %int_0";
4255fd4e5da5Sopenharmony_ci    }
4256fd4e5da5Sopenharmony_ci  }
4257fd4e5da5Sopenharmony_ci  generator.after_types_ += "\n";
4258fd4e5da5Sopenharmony_ci  generator.after_types_ += "OpStore %st_gep %ld\n";
4259fd4e5da5Sopenharmony_ci
4260fd4e5da5Sopenharmony_ci  CompileSuccessfully(generator.Build(), SPV_ENV_UNIVERSAL_1_3);
4261fd4e5da5Sopenharmony_ci  if (mem_type == "struct") {
4262fd4e5da5Sopenharmony_ci    EXPECT_EQ(SPV_ERROR_INVALID_ID,
4263fd4e5da5Sopenharmony_ci              ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
4264fd4e5da5Sopenharmony_ci    // Can only catch the load.
4265fd4e5da5Sopenharmony_ci    EXPECT_THAT(
4266fd4e5da5Sopenharmony_ci        getDiagnosticString(),
4267fd4e5da5Sopenharmony_ci        HasSubstr(
4268fd4e5da5Sopenharmony_ci            "8- or 16-bit loads must be a scalar, vector or matrix type"));
4269fd4e5da5Sopenharmony_ci  } else {
4270fd4e5da5Sopenharmony_ci    EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
4271fd4e5da5Sopenharmony_ci  }
4272fd4e5da5Sopenharmony_ci}
4273fd4e5da5Sopenharmony_ci
4274fd4e5da5Sopenharmony_ciINSTANTIATE_TEST_SUITE_P(LoadStoreInt8, ValidateSizedLoadStore,
4275fd4e5da5Sopenharmony_ci                         Combine(Values("int"), Values(8u),
4276fd4e5da5Sopenharmony_ci                                 Values("scalar", "vector", "struct")));
4277fd4e5da5Sopenharmony_ciINSTANTIATE_TEST_SUITE_P(LoadStoreInt16, ValidateSizedLoadStore,
4278fd4e5da5Sopenharmony_ci                         Combine(Values("int"), Values(16u),
4279fd4e5da5Sopenharmony_ci                                 Values("scalar", "vector", "struct")));
4280fd4e5da5Sopenharmony_ciINSTANTIATE_TEST_SUITE_P(LoadStoreFloat16, ValidateSizedLoadStore,
4281fd4e5da5Sopenharmony_ci                         Combine(Values("float"), Values(16u),
4282fd4e5da5Sopenharmony_ci                                 Values("scalar", "vector", "matrix",
4283fd4e5da5Sopenharmony_ci                                        "struct")));
4284fd4e5da5Sopenharmony_ci
4285fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, SmallStorageCopyMemoryChar) {
4286fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
4287fd4e5da5Sopenharmony_ciOpCapability Shader
4288fd4e5da5Sopenharmony_ciOpCapability Linkage
4289fd4e5da5Sopenharmony_ciOpCapability UniformAndStorageBuffer8BitAccess
4290fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_8bit_storage"
4291fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
4292fd4e5da5Sopenharmony_ciOpDecorate %block Block
4293fd4e5da5Sopenharmony_ciOpMemberDecorate %block 0 Offset 0
4294fd4e5da5Sopenharmony_ci%void = OpTypeVoid
4295fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
4296fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0
4297fd4e5da5Sopenharmony_ci%char = OpTypeInt 8 0
4298fd4e5da5Sopenharmony_ci%block = OpTypeStruct %char
4299fd4e5da5Sopenharmony_ci%ptr_ssbo_block = OpTypePointer StorageBuffer %block
4300fd4e5da5Sopenharmony_ci%in = OpVariable %ptr_ssbo_block StorageBuffer
4301fd4e5da5Sopenharmony_ci%out = OpVariable %ptr_ssbo_block StorageBuffer
4302fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void
4303fd4e5da5Sopenharmony_ci%func = OpFunction %void None %void_fn
4304fd4e5da5Sopenharmony_ci%entry = OpLabel
4305fd4e5da5Sopenharmony_ciOpCopyMemory %out %in
4306fd4e5da5Sopenharmony_ciOpReturn
4307fd4e5da5Sopenharmony_ciOpFunctionEnd
4308fd4e5da5Sopenharmony_ci)";
4309fd4e5da5Sopenharmony_ci
4310fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
4311fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
4312fd4e5da5Sopenharmony_ci  EXPECT_THAT(
4313fd4e5da5Sopenharmony_ci      getDiagnosticString(),
4314fd4e5da5Sopenharmony_ci      HasSubstr("Cannot copy memory of objects containing 8- or 16-bit types"));
4315fd4e5da5Sopenharmony_ci}
4316fd4e5da5Sopenharmony_ci
4317fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, SmallStorageCopyMemoryShort) {
4318fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
4319fd4e5da5Sopenharmony_ciOpCapability Shader
4320fd4e5da5Sopenharmony_ciOpCapability Linkage
4321fd4e5da5Sopenharmony_ciOpCapability UniformAndStorageBuffer16BitAccess
4322fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_16bit_storage"
4323fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
4324fd4e5da5Sopenharmony_ciOpDecorate %block Block
4325fd4e5da5Sopenharmony_ciOpMemberDecorate %block 0 Offset 0
4326fd4e5da5Sopenharmony_ci%void = OpTypeVoid
4327fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
4328fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0
4329fd4e5da5Sopenharmony_ci%short = OpTypeInt 16 0
4330fd4e5da5Sopenharmony_ci%block = OpTypeStruct %short
4331fd4e5da5Sopenharmony_ci%ptr_ssbo_block = OpTypePointer StorageBuffer %block
4332fd4e5da5Sopenharmony_ci%in = OpVariable %ptr_ssbo_block StorageBuffer
4333fd4e5da5Sopenharmony_ci%out = OpVariable %ptr_ssbo_block StorageBuffer
4334fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void
4335fd4e5da5Sopenharmony_ci%func = OpFunction %void None %void_fn
4336fd4e5da5Sopenharmony_ci%entry = OpLabel
4337fd4e5da5Sopenharmony_ciOpCopyMemory %out %in
4338fd4e5da5Sopenharmony_ciOpReturn
4339fd4e5da5Sopenharmony_ciOpFunctionEnd
4340fd4e5da5Sopenharmony_ci)";
4341fd4e5da5Sopenharmony_ci
4342fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
4343fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
4344fd4e5da5Sopenharmony_ci  EXPECT_THAT(
4345fd4e5da5Sopenharmony_ci      getDiagnosticString(),
4346fd4e5da5Sopenharmony_ci      HasSubstr("Cannot copy memory of objects containing 8- or 16-bit types"));
4347fd4e5da5Sopenharmony_ci}
4348fd4e5da5Sopenharmony_ci
4349fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, SmallStorageCopyMemoryHalf) {
4350fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
4351fd4e5da5Sopenharmony_ciOpCapability Shader
4352fd4e5da5Sopenharmony_ciOpCapability Linkage
4353fd4e5da5Sopenharmony_ciOpCapability UniformAndStorageBuffer16BitAccess
4354fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_16bit_storage"
4355fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
4356fd4e5da5Sopenharmony_ciOpDecorate %block Block
4357fd4e5da5Sopenharmony_ciOpMemberDecorate %block 0 Offset 0
4358fd4e5da5Sopenharmony_ci%void = OpTypeVoid
4359fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
4360fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0
4361fd4e5da5Sopenharmony_ci%half = OpTypeFloat 16
4362fd4e5da5Sopenharmony_ci%block = OpTypeStruct %half
4363fd4e5da5Sopenharmony_ci%ptr_ssbo_block = OpTypePointer StorageBuffer %block
4364fd4e5da5Sopenharmony_ci%in = OpVariable %ptr_ssbo_block StorageBuffer
4365fd4e5da5Sopenharmony_ci%out = OpVariable %ptr_ssbo_block StorageBuffer
4366fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void
4367fd4e5da5Sopenharmony_ci%func = OpFunction %void None %void_fn
4368fd4e5da5Sopenharmony_ci%entry = OpLabel
4369fd4e5da5Sopenharmony_ciOpCopyMemory %out %in
4370fd4e5da5Sopenharmony_ciOpReturn
4371fd4e5da5Sopenharmony_ciOpFunctionEnd
4372fd4e5da5Sopenharmony_ci)";
4373fd4e5da5Sopenharmony_ci
4374fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
4375fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
4376fd4e5da5Sopenharmony_ci  EXPECT_THAT(
4377fd4e5da5Sopenharmony_ci      getDiagnosticString(),
4378fd4e5da5Sopenharmony_ci      HasSubstr("Cannot copy memory of objects containing 8- or 16-bit types"));
4379fd4e5da5Sopenharmony_ci}
4380fd4e5da5Sopenharmony_ci
4381fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, SmallStorageVariableArrayBufferBlockShort) {
4382fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
4383fd4e5da5Sopenharmony_ciOpCapability Shader
4384fd4e5da5Sopenharmony_ciOpCapability Linkage
4385fd4e5da5Sopenharmony_ciOpCapability StorageBuffer16BitAccess
4386fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_16bit_storage"
4387fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
4388fd4e5da5Sopenharmony_ciOpDecorate %block BufferBlock
4389fd4e5da5Sopenharmony_ciOpMemberDecorate %block 0 Offset 0
4390fd4e5da5Sopenharmony_ci%void = OpTypeVoid
4391fd4e5da5Sopenharmony_ci%short = OpTypeInt 16 0
4392fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
4393fd4e5da5Sopenharmony_ci%int_4 = OpConstant %int 4
4394fd4e5da5Sopenharmony_ci%block = OpTypeStruct %short
4395fd4e5da5Sopenharmony_ci%block_array = OpTypeArray %block %int_4
4396fd4e5da5Sopenharmony_ci%ptr_block_array = OpTypePointer Uniform %block_array
4397fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_block_array Uniform
4398fd4e5da5Sopenharmony_ci)";
4399fd4e5da5Sopenharmony_ci
4400fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
4401fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
4402fd4e5da5Sopenharmony_ci}
4403fd4e5da5Sopenharmony_ci
4404fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, SmallStorageVariableArrayBufferBlockChar) {
4405fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
4406fd4e5da5Sopenharmony_ciOpCapability Shader
4407fd4e5da5Sopenharmony_ciOpCapability Linkage
4408fd4e5da5Sopenharmony_ciOpCapability StorageBuffer8BitAccess
4409fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_8bit_storage"
4410fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
4411fd4e5da5Sopenharmony_ciOpDecorate %block BufferBlock
4412fd4e5da5Sopenharmony_ciOpMemberDecorate %block 0 Offset 0
4413fd4e5da5Sopenharmony_ci%void = OpTypeVoid
4414fd4e5da5Sopenharmony_ci%char = OpTypeInt 8 0
4415fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
4416fd4e5da5Sopenharmony_ci%int_4 = OpConstant %int 4
4417fd4e5da5Sopenharmony_ci%block = OpTypeStruct %char
4418fd4e5da5Sopenharmony_ci%block_array = OpTypeArray %block %int_4
4419fd4e5da5Sopenharmony_ci%ptr_block_array = OpTypePointer Uniform %block_array
4420fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_block_array Uniform
4421fd4e5da5Sopenharmony_ci)";
4422fd4e5da5Sopenharmony_ci
4423fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
4424fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
4425fd4e5da5Sopenharmony_ci}
4426fd4e5da5Sopenharmony_ci
4427fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, SmallStorageVariableArrayBufferBlockHalf) {
4428fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
4429fd4e5da5Sopenharmony_ciOpCapability Shader
4430fd4e5da5Sopenharmony_ciOpCapability Linkage
4431fd4e5da5Sopenharmony_ciOpCapability StorageBuffer16BitAccess
4432fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_16bit_storage"
4433fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
4434fd4e5da5Sopenharmony_ciOpDecorate %block BufferBlock
4435fd4e5da5Sopenharmony_ciOpMemberDecorate %block 0 Offset 0
4436fd4e5da5Sopenharmony_ci%void = OpTypeVoid
4437fd4e5da5Sopenharmony_ci%half = OpTypeFloat 16
4438fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
4439fd4e5da5Sopenharmony_ci%int_4 = OpConstant %int 4
4440fd4e5da5Sopenharmony_ci%block = OpTypeStruct %half
4441fd4e5da5Sopenharmony_ci%block_array = OpTypeArray %block %int_4
4442fd4e5da5Sopenharmony_ci%ptr_block_array = OpTypePointer Uniform %block_array
4443fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_block_array Uniform
4444fd4e5da5Sopenharmony_ci)";
4445fd4e5da5Sopenharmony_ci
4446fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
4447fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
4448fd4e5da5Sopenharmony_ci}
4449fd4e5da5Sopenharmony_ci
4450fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, VulkanStorageBufferNotAStruct) {
4451fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
4452fd4e5da5Sopenharmony_ciOpCapability Shader
4453fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_storage_buffer_storage_class"
4454fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
4455fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %main "main"
4456fd4e5da5Sopenharmony_ciOpExecutionMode %main LocalSize 1 1 1
4457fd4e5da5Sopenharmony_ci%void = OpTypeVoid
4458fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
4459fd4e5da5Sopenharmony_ci%ptr_ssbo = OpTypePointer StorageBuffer %uint
4460fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_ssbo StorageBuffer
4461fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void
4462fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn
4463fd4e5da5Sopenharmony_ci%entry = OpLabel
4464fd4e5da5Sopenharmony_ciOpReturn
4465fd4e5da5Sopenharmony_ciOpFunctionEnd
4466fd4e5da5Sopenharmony_ci)";
4467fd4e5da5Sopenharmony_ci
4468fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
4469fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
4470fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
4471fd4e5da5Sopenharmony_ci              AnyVUID("VUID-StandaloneSpirv-Uniform-06807"));
4472fd4e5da5Sopenharmony_ci  EXPECT_THAT(
4473fd4e5da5Sopenharmony_ci      getDiagnosticString(),
4474fd4e5da5Sopenharmony_ci      HasSubstr("From Vulkan spec:\nVariables identified with "
4475fd4e5da5Sopenharmony_ci                "the StorageBuffer storage class are used to access "
4476fd4e5da5Sopenharmony_ci                "transparent buffer backed resources. Such variables must be "
4477fd4e5da5Sopenharmony_ci                "typed as OpTypeStruct, or an array of this type"));
4478fd4e5da5Sopenharmony_ci}
4479fd4e5da5Sopenharmony_ci
4480fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, VulkanStorageBufferRuntimeArrayNotAStruct) {
4481fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
4482fd4e5da5Sopenharmony_ciOpCapability Shader
4483fd4e5da5Sopenharmony_ciOpCapability RuntimeDescriptorArrayEXT
4484fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_storage_buffer_storage_class"
4485fd4e5da5Sopenharmony_ciOpExtension "SPV_EXT_descriptor_indexing"
4486fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
4487fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %main "main"
4488fd4e5da5Sopenharmony_ciOpExecutionMode %main LocalSize 1 1 1
4489fd4e5da5Sopenharmony_ci%void = OpTypeVoid
4490fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
4491fd4e5da5Sopenharmony_ci%array = OpTypeRuntimeArray %uint
4492fd4e5da5Sopenharmony_ci%ptr_ssbo = OpTypePointer StorageBuffer %array
4493fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_ssbo StorageBuffer
4494fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void
4495fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn
4496fd4e5da5Sopenharmony_ci%entry = OpLabel
4497fd4e5da5Sopenharmony_ciOpReturn
4498fd4e5da5Sopenharmony_ciOpFunctionEnd
4499fd4e5da5Sopenharmony_ci)";
4500fd4e5da5Sopenharmony_ci
4501fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
4502fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
4503fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
4504fd4e5da5Sopenharmony_ci              AnyVUID("VUID-StandaloneSpirv-Uniform-06807"));
4505fd4e5da5Sopenharmony_ci  EXPECT_THAT(
4506fd4e5da5Sopenharmony_ci      getDiagnosticString(),
4507fd4e5da5Sopenharmony_ci      HasSubstr("From Vulkan spec:\nVariables identified with "
4508fd4e5da5Sopenharmony_ci                "the StorageBuffer storage class are used to access "
4509fd4e5da5Sopenharmony_ci                "transparent buffer backed resources. Such variables must be "
4510fd4e5da5Sopenharmony_ci                "typed as OpTypeStruct, or an array of this type"));
4511fd4e5da5Sopenharmony_ci}
4512fd4e5da5Sopenharmony_ci
4513fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, VulkanStorageBufferArrayNotAStruct) {
4514fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
4515fd4e5da5Sopenharmony_ciOpCapability Shader
4516fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_storage_buffer_storage_class"
4517fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
4518fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %main "main"
4519fd4e5da5Sopenharmony_ciOpExecutionMode %main LocalSize 1 1 1
4520fd4e5da5Sopenharmony_ci%void = OpTypeVoid
4521fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
4522fd4e5da5Sopenharmony_ci%uint_4 = OpConstant %uint 4
4523fd4e5da5Sopenharmony_ci%array = OpTypeArray %uint %uint_4
4524fd4e5da5Sopenharmony_ci%ptr_ssbo = OpTypePointer StorageBuffer %array
4525fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_ssbo StorageBuffer
4526fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void
4527fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn
4528fd4e5da5Sopenharmony_ci%entry = OpLabel
4529fd4e5da5Sopenharmony_ciOpReturn
4530fd4e5da5Sopenharmony_ciOpFunctionEnd
4531fd4e5da5Sopenharmony_ci)";
4532fd4e5da5Sopenharmony_ci
4533fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
4534fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
4535fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
4536fd4e5da5Sopenharmony_ci              AnyVUID("VUID-StandaloneSpirv-Uniform-06807"));
4537fd4e5da5Sopenharmony_ci  EXPECT_THAT(
4538fd4e5da5Sopenharmony_ci      getDiagnosticString(),
4539fd4e5da5Sopenharmony_ci      HasSubstr("From Vulkan spec:\nVariables identified with "
4540fd4e5da5Sopenharmony_ci                "the StorageBuffer storage class are used to access "
4541fd4e5da5Sopenharmony_ci                "transparent buffer backed resources. Such variables must be "
4542fd4e5da5Sopenharmony_ci                "typed as OpTypeStruct, or an array of this type"));
4543fd4e5da5Sopenharmony_ci}
4544fd4e5da5Sopenharmony_ci
4545fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, VulkanInvariantOutputSuccess) {
4546fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
4547fd4e5da5Sopenharmony_ciOpCapability Shader
4548fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
4549fd4e5da5Sopenharmony_ciOpEntryPoint Vertex %main "main" %var
4550fd4e5da5Sopenharmony_ciOpDecorate %var Location 0
4551fd4e5da5Sopenharmony_ciOpDecorate %var Invariant
4552fd4e5da5Sopenharmony_ci%void = OpTypeVoid
4553fd4e5da5Sopenharmony_ci%f32 = OpTypeFloat 32
4554fd4e5da5Sopenharmony_ci%ptr_output = OpTypePointer Output %f32
4555fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_output Output
4556fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void
4557fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn
4558fd4e5da5Sopenharmony_ci%entry = OpLabel
4559fd4e5da5Sopenharmony_ciOpReturn
4560fd4e5da5Sopenharmony_ciOpFunctionEnd
4561fd4e5da5Sopenharmony_ci)";
4562fd4e5da5Sopenharmony_ci
4563fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
4564fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
4565fd4e5da5Sopenharmony_ci}
4566fd4e5da5Sopenharmony_ci
4567fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, VulkanInvariantInputStructSuccess) {
4568fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
4569fd4e5da5Sopenharmony_ciOpCapability Shader
4570fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
4571fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main" %var
4572fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
4573fd4e5da5Sopenharmony_ciOpDecorate %var Location 0
4574fd4e5da5Sopenharmony_ciOpMemberDecorate %struct 1 Invariant
4575fd4e5da5Sopenharmony_ci%void = OpTypeVoid
4576fd4e5da5Sopenharmony_ci%f32 = OpTypeFloat 32
4577fd4e5da5Sopenharmony_ci%struct = OpTypeStruct %f32 %f32
4578fd4e5da5Sopenharmony_ci%ptr_input = OpTypePointer Input %struct
4579fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_input Input
4580fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void
4581fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn
4582fd4e5da5Sopenharmony_ci%entry = OpLabel
4583fd4e5da5Sopenharmony_ciOpReturn
4584fd4e5da5Sopenharmony_ciOpFunctionEnd
4585fd4e5da5Sopenharmony_ci)";
4586fd4e5da5Sopenharmony_ci
4587fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
4588fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
4589fd4e5da5Sopenharmony_ci}
4590fd4e5da5Sopenharmony_ci
4591fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, VulkanInvariantWrongStorageClass) {
4592fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
4593fd4e5da5Sopenharmony_ciOpCapability Shader
4594fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
4595fd4e5da5Sopenharmony_ciOpEntryPoint Vertex %main "main"
4596fd4e5da5Sopenharmony_ciOpDecorate %var Invariant
4597fd4e5da5Sopenharmony_ci%void = OpTypeVoid
4598fd4e5da5Sopenharmony_ci%f32 = OpTypeFloat 32
4599fd4e5da5Sopenharmony_ci%ptr_private = OpTypePointer Private %f32
4600fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_private Private
4601fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void
4602fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn
4603fd4e5da5Sopenharmony_ci%entry = OpLabel
4604fd4e5da5Sopenharmony_ciOpReturn
4605fd4e5da5Sopenharmony_ciOpFunctionEnd
4606fd4e5da5Sopenharmony_ci)";
4607fd4e5da5Sopenharmony_ci
4608fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
4609fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
4610fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
4611fd4e5da5Sopenharmony_ci              AnyVUID("VUID-StandaloneSpirv-Invariant-04677"));
4612fd4e5da5Sopenharmony_ci  EXPECT_THAT(
4613fd4e5da5Sopenharmony_ci      getDiagnosticString(),
4614fd4e5da5Sopenharmony_ci      HasSubstr(
4615fd4e5da5Sopenharmony_ci          "Variable decorated with Invariant must only be identified with the "
4616fd4e5da5Sopenharmony_ci          "Input or Output storage class in Vulkan environment."));
4617fd4e5da5Sopenharmony_ci}
4618fd4e5da5Sopenharmony_ci
4619fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, VulkanInvariantMemberWrongStorageClass) {
4620fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
4621fd4e5da5Sopenharmony_ciOpCapability Shader
4622fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
4623fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main"
4624fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
4625fd4e5da5Sopenharmony_ciOpMemberDecorate %struct 1 Invariant
4626fd4e5da5Sopenharmony_ci%void = OpTypeVoid
4627fd4e5da5Sopenharmony_ci%f32 = OpTypeFloat 32
4628fd4e5da5Sopenharmony_ci%struct = OpTypeStruct %f32 %f32
4629fd4e5da5Sopenharmony_ci%ptr_private = OpTypePointer Private %struct
4630fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_private Private
4631fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void
4632fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn
4633fd4e5da5Sopenharmony_ci%entry = OpLabel
4634fd4e5da5Sopenharmony_ciOpReturn
4635fd4e5da5Sopenharmony_ciOpFunctionEnd
4636fd4e5da5Sopenharmony_ci)";
4637fd4e5da5Sopenharmony_ci
4638fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
4639fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
4640fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
4641fd4e5da5Sopenharmony_ci              AnyVUID("VUID-StandaloneSpirv-Invariant-04677"));
4642fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
4643fd4e5da5Sopenharmony_ci              HasSubstr("Variable struct member decorated with Invariant must "
4644fd4e5da5Sopenharmony_ci                        "only be identified with the Input or Output storage "
4645fd4e5da5Sopenharmony_ci                        "class in Vulkan environment."));
4646fd4e5da5Sopenharmony_ci}
4647fd4e5da5Sopenharmony_ci
4648fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, PhysicalStorageBufferPtrEqual) {
4649fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
4650fd4e5da5Sopenharmony_ciOpCapability Shader
4651fd4e5da5Sopenharmony_ciOpCapability Int64
4652fd4e5da5Sopenharmony_ciOpCapability PhysicalStorageBufferAddresses
4653fd4e5da5Sopenharmony_ciOpMemoryModel PhysicalStorageBuffer64 GLSL450
4654fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %main "main"
4655fd4e5da5Sopenharmony_ciOpExecutionMode %main LocalSize 1 1 1
4656fd4e5da5Sopenharmony_ci%void = OpTypeVoid
4657fd4e5da5Sopenharmony_ci%bool = OpTypeBool
4658fd4e5da5Sopenharmony_ci%long = OpTypeInt 64 0
4659fd4e5da5Sopenharmony_ci%long_0 = OpConstant %long 0
4660fd4e5da5Sopenharmony_ci%ptr_pssbo_long = OpTypePointer PhysicalStorageBuffer %long
4661fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void
4662fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn
4663fd4e5da5Sopenharmony_ci%entry = OpLabel
4664fd4e5da5Sopenharmony_ci%conv = OpConvertUToPtr %ptr_pssbo_long %long_0
4665fd4e5da5Sopenharmony_ci%eq = OpPtrEqual %bool %conv %conv
4666fd4e5da5Sopenharmony_ciOpReturn
4667fd4e5da5Sopenharmony_ciOpFunctionEnd
4668fd4e5da5Sopenharmony_ci)";
4669fd4e5da5Sopenharmony_ci
4670fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_5);
4671fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
4672fd4e5da5Sopenharmony_ci  EXPECT_THAT(
4673fd4e5da5Sopenharmony_ci      getDiagnosticString(),
4674fd4e5da5Sopenharmony_ci      HasSubstr(
4675fd4e5da5Sopenharmony_ci          "Cannot use a pointer in the PhysicalStorageBuffer storage class"));
4676fd4e5da5Sopenharmony_ci}
4677fd4e5da5Sopenharmony_ci
4678fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, PhysicalStorageBufferPtrNotEqual) {
4679fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
4680fd4e5da5Sopenharmony_ciOpCapability Shader
4681fd4e5da5Sopenharmony_ciOpCapability Int64
4682fd4e5da5Sopenharmony_ciOpCapability PhysicalStorageBufferAddresses
4683fd4e5da5Sopenharmony_ciOpMemoryModel PhysicalStorageBuffer64 GLSL450
4684fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %main "main"
4685fd4e5da5Sopenharmony_ciOpExecutionMode %main LocalSize 1 1 1
4686fd4e5da5Sopenharmony_ci%void = OpTypeVoid
4687fd4e5da5Sopenharmony_ci%bool = OpTypeBool
4688fd4e5da5Sopenharmony_ci%long = OpTypeInt 64 0
4689fd4e5da5Sopenharmony_ci%long_0 = OpConstant %long 0
4690fd4e5da5Sopenharmony_ci%ptr_pssbo_long = OpTypePointer PhysicalStorageBuffer %long
4691fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void
4692fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn
4693fd4e5da5Sopenharmony_ci%entry = OpLabel
4694fd4e5da5Sopenharmony_ci%conv = OpConvertUToPtr %ptr_pssbo_long %long_0
4695fd4e5da5Sopenharmony_ci%neq = OpPtrNotEqual %bool %conv %conv
4696fd4e5da5Sopenharmony_ciOpReturn
4697fd4e5da5Sopenharmony_ciOpFunctionEnd
4698fd4e5da5Sopenharmony_ci)";
4699fd4e5da5Sopenharmony_ci
4700fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_5);
4701fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
4702fd4e5da5Sopenharmony_ci  EXPECT_THAT(
4703fd4e5da5Sopenharmony_ci      getDiagnosticString(),
4704fd4e5da5Sopenharmony_ci      HasSubstr(
4705fd4e5da5Sopenharmony_ci          "Cannot use a pointer in the PhysicalStorageBuffer storage class"));
4706fd4e5da5Sopenharmony_ci}
4707fd4e5da5Sopenharmony_ci
4708fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, PhysicalStorageBufferPtrDiff) {
4709fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
4710fd4e5da5Sopenharmony_ciOpCapability Shader
4711fd4e5da5Sopenharmony_ciOpCapability Int64
4712fd4e5da5Sopenharmony_ciOpCapability PhysicalStorageBufferAddresses
4713fd4e5da5Sopenharmony_ciOpCapability VariablePointers
4714fd4e5da5Sopenharmony_ciOpMemoryModel PhysicalStorageBuffer64 GLSL450
4715fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %main "main"
4716fd4e5da5Sopenharmony_ciOpExecutionMode %main LocalSize 1 1 1
4717fd4e5da5Sopenharmony_ci%void = OpTypeVoid
4718fd4e5da5Sopenharmony_ci%long = OpTypeInt 64 0
4719fd4e5da5Sopenharmony_ci%long_0 = OpConstant %long 0
4720fd4e5da5Sopenharmony_ci%ptr_pssbo_long = OpTypePointer PhysicalStorageBuffer %long
4721fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void
4722fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn
4723fd4e5da5Sopenharmony_ci%entry = OpLabel
4724fd4e5da5Sopenharmony_ci%conv = OpConvertUToPtr %ptr_pssbo_long %long_0
4725fd4e5da5Sopenharmony_ci%diff = OpPtrDiff %long %conv %conv
4726fd4e5da5Sopenharmony_ciOpReturn
4727fd4e5da5Sopenharmony_ciOpFunctionEnd
4728fd4e5da5Sopenharmony_ci)";
4729fd4e5da5Sopenharmony_ci
4730fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_5);
4731fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
4732fd4e5da5Sopenharmony_ci  EXPECT_THAT(
4733fd4e5da5Sopenharmony_ci      getDiagnosticString(),
4734fd4e5da5Sopenharmony_ci      HasSubstr(
4735fd4e5da5Sopenharmony_ci          "Cannot use a pointer in the PhysicalStorageBuffer storage class"));
4736fd4e5da5Sopenharmony_ci}
4737fd4e5da5Sopenharmony_ci
4738fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, VulkanInitializerWithWorkgroupStorageClassBad) {
4739fd4e5da5Sopenharmony_ci  std::string spirv = R"(
4740fd4e5da5Sopenharmony_ciOpCapability Shader
4741fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR
4742fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model"
4743fd4e5da5Sopenharmony_ciOpMemoryModel Logical VulkanKHR
4744fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %func "func"
4745fd4e5da5Sopenharmony_ciOpExecutionMode %func OriginUpperLeft
4746fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
4747fd4e5da5Sopenharmony_ci%float_ptr = OpTypePointer Workgroup %float
4748fd4e5da5Sopenharmony_ci%init_val = OpConstant %float 1.0
4749fd4e5da5Sopenharmony_ci%1 = OpVariable %float_ptr Workgroup %init_val
4750fd4e5da5Sopenharmony_ci%void = OpTypeVoid
4751fd4e5da5Sopenharmony_ci%functy = OpTypeFunction %void
4752fd4e5da5Sopenharmony_ci%func = OpFunction %void None %functy
4753fd4e5da5Sopenharmony_ci%2 = OpLabel
4754fd4e5da5Sopenharmony_ciOpReturn
4755fd4e5da5Sopenharmony_ciOpFunctionEnd
4756fd4e5da5Sopenharmony_ci)";
4757fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_0);
4758fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
4759fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
4760fd4e5da5Sopenharmony_ci              AnyVUID(" VUID-StandaloneSpirv-OpVariable-04734"));
4761fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
4762fd4e5da5Sopenharmony_ci              HasSubstr("OpVariable, <id> '5[%5]', initializers are limited to "
4763fd4e5da5Sopenharmony_ci                        "OpConstantNull in Workgroup storage class"));
4764fd4e5da5Sopenharmony_ci}
4765fd4e5da5Sopenharmony_ci
4766fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, VulkanInitializerWithWorkgroupStorageClassGood) {
4767fd4e5da5Sopenharmony_ci  std::string spirv = R"(
4768fd4e5da5Sopenharmony_ciOpCapability Shader
4769fd4e5da5Sopenharmony_ciOpCapability VulkanMemoryModelKHR
4770fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_vulkan_memory_model"
4771fd4e5da5Sopenharmony_ciOpMemoryModel Logical VulkanKHR
4772fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %func "func"
4773fd4e5da5Sopenharmony_ciOpExecutionMode %func OriginUpperLeft
4774fd4e5da5Sopenharmony_ci%float = OpTypeFloat 32
4775fd4e5da5Sopenharmony_ci%float_ptr = OpTypePointer Workgroup %float
4776fd4e5da5Sopenharmony_ci%init_val = OpConstantNull %float
4777fd4e5da5Sopenharmony_ci%1 = OpVariable %float_ptr Workgroup %init_val
4778fd4e5da5Sopenharmony_ci%void = OpTypeVoid
4779fd4e5da5Sopenharmony_ci%functy = OpTypeFunction %void
4780fd4e5da5Sopenharmony_ci%func = OpFunction %void None %functy
4781fd4e5da5Sopenharmony_ci%2 = OpLabel
4782fd4e5da5Sopenharmony_ciOpReturn
4783fd4e5da5Sopenharmony_ciOpFunctionEnd
4784fd4e5da5Sopenharmony_ci)";
4785fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_0);
4786fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
4787fd4e5da5Sopenharmony_ci}
4788fd4e5da5Sopenharmony_ci
4789fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, LoadRuntimeArray) {
4790fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
4791fd4e5da5Sopenharmony_ciOpCapability Shader
4792fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_storage_buffer_storage_class"
4793fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
4794fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %main "main"
4795fd4e5da5Sopenharmony_ci%void = OpTypeVoid
4796fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
4797fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0
4798fd4e5da5Sopenharmony_ci%rta = OpTypeRuntimeArray %int
4799fd4e5da5Sopenharmony_ci%block = OpTypeStruct %rta
4800fd4e5da5Sopenharmony_ci%ptr_rta = OpTypePointer StorageBuffer %rta
4801fd4e5da5Sopenharmony_ci%ptr_block = OpTypePointer StorageBuffer %block
4802fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_block StorageBuffer
4803fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void
4804fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn
4805fd4e5da5Sopenharmony_ci%entry = OpLabel
4806fd4e5da5Sopenharmony_ci%gep = OpAccessChain %ptr_rta %var %int_0
4807fd4e5da5Sopenharmony_ci%ld = OpLoad %rta %gep
4808fd4e5da5Sopenharmony_ciOpReturn
4809fd4e5da5Sopenharmony_ciOpFunctionEnd
4810fd4e5da5Sopenharmony_ci)";
4811fd4e5da5Sopenharmony_ci
4812fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv);
4813fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
4814fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
4815fd4e5da5Sopenharmony_ci              HasSubstr("Cannot load a runtime-sized array"));
4816fd4e5da5Sopenharmony_ci}
4817fd4e5da5Sopenharmony_ci
4818fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, LoadRuntimeArrayInStruct) {
4819fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
4820fd4e5da5Sopenharmony_ciOpCapability Shader
4821fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_storage_buffer_storage_class"
4822fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
4823fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %main "main"
4824fd4e5da5Sopenharmony_ci%void = OpTypeVoid
4825fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
4826fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0
4827fd4e5da5Sopenharmony_ci%rta = OpTypeRuntimeArray %int
4828fd4e5da5Sopenharmony_ci%block = OpTypeStruct %rta
4829fd4e5da5Sopenharmony_ci%ptr_rta = OpTypePointer StorageBuffer %rta
4830fd4e5da5Sopenharmony_ci%ptr_block = OpTypePointer StorageBuffer %block
4831fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_block StorageBuffer
4832fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void
4833fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn
4834fd4e5da5Sopenharmony_ci%entry = OpLabel
4835fd4e5da5Sopenharmony_ci%ld = OpLoad %block %var
4836fd4e5da5Sopenharmony_ciOpReturn
4837fd4e5da5Sopenharmony_ciOpFunctionEnd
4838fd4e5da5Sopenharmony_ci)";
4839fd4e5da5Sopenharmony_ci
4840fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv);
4841fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
4842fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
4843fd4e5da5Sopenharmony_ci              HasSubstr("Cannot load a runtime-sized array"));
4844fd4e5da5Sopenharmony_ci}
4845fd4e5da5Sopenharmony_ci
4846fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, LoadRuntimeArrayInArray) {
4847fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
4848fd4e5da5Sopenharmony_ciOpCapability Shader
4849fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_storage_buffer_storage_class"
4850fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
4851fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %main "main"
4852fd4e5da5Sopenharmony_ci%void = OpTypeVoid
4853fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
4854fd4e5da5Sopenharmony_ci%int_0 = OpConstant %int 0
4855fd4e5da5Sopenharmony_ci%int_4 = OpConstant %int 4
4856fd4e5da5Sopenharmony_ci%rta = OpTypeRuntimeArray %int
4857fd4e5da5Sopenharmony_ci%block = OpTypeStruct %rta
4858fd4e5da5Sopenharmony_ci%array = OpTypeArray %block %int_4
4859fd4e5da5Sopenharmony_ci%ptr_rta = OpTypePointer StorageBuffer %rta
4860fd4e5da5Sopenharmony_ci%ptr_block = OpTypePointer StorageBuffer %block
4861fd4e5da5Sopenharmony_ci%ptr_array = OpTypePointer StorageBuffer %array
4862fd4e5da5Sopenharmony_ci%var = OpVariable %ptr_array StorageBuffer
4863fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void
4864fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn
4865fd4e5da5Sopenharmony_ci%entry = OpLabel
4866fd4e5da5Sopenharmony_ci%ld = OpLoad %array %var
4867fd4e5da5Sopenharmony_ciOpReturn
4868fd4e5da5Sopenharmony_ciOpFunctionEnd
4869fd4e5da5Sopenharmony_ci)";
4870fd4e5da5Sopenharmony_ci
4871fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv);
4872fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
4873fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
4874fd4e5da5Sopenharmony_ci              HasSubstr("Cannot load a runtime-sized array"));
4875fd4e5da5Sopenharmony_ci}
4876fd4e5da5Sopenharmony_ci
4877fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, Pre1p4WorkgroupMemoryBadLayoutOk) {
4878fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
4879fd4e5da5Sopenharmony_ciOpCapability Shader
4880fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
4881fd4e5da5Sopenharmony_ciOpEntryPoint GLCompute %main "main"
4882fd4e5da5Sopenharmony_ciOpDecorate %struct Block
4883fd4e5da5Sopenharmony_ciOpMemberDecorate %struct 0 Offset 0
4884fd4e5da5Sopenharmony_ci%void = OpTypeVoid
4885fd4e5da5Sopenharmony_ci%bool = OpTypeBool
4886fd4e5da5Sopenharmony_ci%struct = OpTypeStruct %bool
4887fd4e5da5Sopenharmony_ci%ptr = OpTypePointer Workgroup %struct
4888fd4e5da5Sopenharmony_ci%var = OpVariable %ptr Workgroup
4889fd4e5da5Sopenharmony_ci%void_fn = OpTypeFunction %void
4890fd4e5da5Sopenharmony_ci%main = OpFunction %void None %void_fn
4891fd4e5da5Sopenharmony_ci%entry = OpLabel
4892fd4e5da5Sopenharmony_ciOpReturn
4893fd4e5da5Sopenharmony_ciOpFunctionEnd
4894fd4e5da5Sopenharmony_ci)";
4895fd4e5da5Sopenharmony_ci
4896fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv);
4897fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
4898fd4e5da5Sopenharmony_ci}
4899fd4e5da5Sopenharmony_ci
4900fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, PtrAccessChainArrayStrideBad) {
4901fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
4902fd4e5da5Sopenharmony_ci               OpCapability Shader
4903fd4e5da5Sopenharmony_ci               OpCapability VariablePointersStorageBuffer
4904fd4e5da5Sopenharmony_ci               OpExtension "SPV_KHR_storage_buffer_storage_class"
4905fd4e5da5Sopenharmony_ci               OpExtension "SPV_KHR_variable_pointers"
4906fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
4907fd4e5da5Sopenharmony_ci               OpEntryPoint GLCompute %main "foo" %var
4908fd4e5da5Sopenharmony_ci               OpExecutionMode %main LocalSize 1 1 1
4909fd4e5da5Sopenharmony_ci               OpDecorate %var DescriptorSet 0
4910fd4e5da5Sopenharmony_ci               OpDecorate %var Binding 0
4911fd4e5da5Sopenharmony_ci       %uint = OpTypeInt 32 0
4912fd4e5da5Sopenharmony_ci     %uint_0 = OpConstant %uint 0
4913fd4e5da5Sopenharmony_ci     %uint_1 = OpConstant %uint 1
4914fd4e5da5Sopenharmony_ci        %ptr = OpTypePointer StorageBuffer %uint
4915fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
4916fd4e5da5Sopenharmony_ci       %func = OpTypeFunction %void
4917fd4e5da5Sopenharmony_ci        %var = OpVariable %ptr StorageBuffer
4918fd4e5da5Sopenharmony_ci       %main = OpFunction %void None %func
4919fd4e5da5Sopenharmony_ci      %label = OpLabel
4920fd4e5da5Sopenharmony_ci     %access = OpAccessChain %ptr %var
4921fd4e5da5Sopenharmony_ci %ptr_access = OpPtrAccessChain %ptr %access %uint_1
4922fd4e5da5Sopenharmony_ci               OpReturn
4923fd4e5da5Sopenharmony_ci               OpFunctionEnd
4924fd4e5da5Sopenharmony_ci)";
4925fd4e5da5Sopenharmony_ci
4926fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_5);
4927fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_DATA,
4928fd4e5da5Sopenharmony_ci            ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
4929fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
4930fd4e5da5Sopenharmony_ci              HasSubstr("OpPtrAccessChain must have a Base whose type is "
4931fd4e5da5Sopenharmony_ci                        "decorated with ArrayStride"));
4932fd4e5da5Sopenharmony_ci}
4933fd4e5da5Sopenharmony_ci
4934fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, PtrAccessChainArrayStrideSuccess) {
4935fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
4936fd4e5da5Sopenharmony_ci               OpCapability Shader
4937fd4e5da5Sopenharmony_ci               OpCapability VariablePointersStorageBuffer
4938fd4e5da5Sopenharmony_ci               OpExtension "SPV_KHR_storage_buffer_storage_class"
4939fd4e5da5Sopenharmony_ci               OpExtension "SPV_KHR_variable_pointers"
4940fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
4941fd4e5da5Sopenharmony_ci               OpEntryPoint GLCompute %main "foo" %var
4942fd4e5da5Sopenharmony_ci               OpExecutionMode %main LocalSize 1 1 1
4943fd4e5da5Sopenharmony_ci               OpDecorate %var DescriptorSet 0
4944fd4e5da5Sopenharmony_ci               OpDecorate %var Binding 00
4945fd4e5da5Sopenharmony_ci               OpDecorate %ptr ArrayStride 4
4946fd4e5da5Sopenharmony_ci       %uint = OpTypeInt 32 0
4947fd4e5da5Sopenharmony_ci     %uint_0 = OpConstant %uint 0
4948fd4e5da5Sopenharmony_ci     %uint_1 = OpConstant %uint 1
4949fd4e5da5Sopenharmony_ci        %ptr = OpTypePointer StorageBuffer %uint
4950fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
4951fd4e5da5Sopenharmony_ci       %func = OpTypeFunction %void
4952fd4e5da5Sopenharmony_ci        %var = OpVariable %ptr StorageBuffer
4953fd4e5da5Sopenharmony_ci       %main = OpFunction %void None %func
4954fd4e5da5Sopenharmony_ci      %label = OpLabel
4955fd4e5da5Sopenharmony_ci     %access = OpAccessChain %ptr %var
4956fd4e5da5Sopenharmony_ci %ptr_access = OpPtrAccessChain %ptr %access %uint_1
4957fd4e5da5Sopenharmony_ci               OpReturn
4958fd4e5da5Sopenharmony_ci               OpFunctionEnd
4959fd4e5da5Sopenharmony_ci)";
4960fd4e5da5Sopenharmony_ci
4961fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_5);
4962fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
4963fd4e5da5Sopenharmony_ci}
4964fd4e5da5Sopenharmony_ci
4965fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, VulkanPtrAccessChainStorageBufferSuccess) {
4966fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
4967fd4e5da5Sopenharmony_ci               OpCapability Shader
4968fd4e5da5Sopenharmony_ci               OpCapability VariablePointersStorageBuffer
4969fd4e5da5Sopenharmony_ci               OpExtension "SPV_KHR_storage_buffer_storage_class"
4970fd4e5da5Sopenharmony_ci               OpExtension "SPV_KHR_variable_pointers"
4971fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
4972fd4e5da5Sopenharmony_ci               OpEntryPoint GLCompute %main "foo" %var
4973fd4e5da5Sopenharmony_ci               OpExecutionMode %main LocalSize 1 1 1
4974fd4e5da5Sopenharmony_ci               OpDecorate %_runtimearr_uint ArrayStride 4
4975fd4e5da5Sopenharmony_ci               OpMemberDecorate %_struct_10 0 Offset 0
4976fd4e5da5Sopenharmony_ci               OpDecorate %_struct_10 Block
4977fd4e5da5Sopenharmony_ci               OpDecorate %var DescriptorSet 0
4978fd4e5da5Sopenharmony_ci               OpDecorate %var Binding 0
4979fd4e5da5Sopenharmony_ci               OpDecorate %_ptr_StorageBuffer_uint ArrayStride 4
4980fd4e5da5Sopenharmony_ci       %uint = OpTypeInt 32 0
4981fd4e5da5Sopenharmony_ci     %uint_0 = OpConstant %uint 0
4982fd4e5da5Sopenharmony_ci     %uint_1 = OpConstant %uint 1
4983fd4e5da5Sopenharmony_ci%_runtimearr_uint = OpTypeRuntimeArray %uint
4984fd4e5da5Sopenharmony_ci %_struct_10 = OpTypeStruct %_runtimearr_uint
4985fd4e5da5Sopenharmony_ci%_ptr_StorageBuffer__struct_10 = OpTypePointer StorageBuffer %_struct_10
4986fd4e5da5Sopenharmony_ci%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
4987fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
4988fd4e5da5Sopenharmony_ci      %func2 = OpTypeFunction %void %_ptr_StorageBuffer_uint
4989fd4e5da5Sopenharmony_ci      %func1 = OpTypeFunction %void
4990fd4e5da5Sopenharmony_ci         %var = OpVariable %_ptr_StorageBuffer__struct_10 StorageBuffer
4991fd4e5da5Sopenharmony_ci     %called = OpFunction %void None %func2
4992fd4e5da5Sopenharmony_ci      %param = OpFunctionParameter %_ptr_StorageBuffer_uint
4993fd4e5da5Sopenharmony_ci     %label2 = OpLabel
4994fd4e5da5Sopenharmony_ci %ptr_access = OpPtrAccessChain %_ptr_StorageBuffer_uint %param %uint_1
4995fd4e5da5Sopenharmony_ci               OpReturn
4996fd4e5da5Sopenharmony_ci               OpFunctionEnd
4997fd4e5da5Sopenharmony_ci       %main = OpFunction %void None %func1
4998fd4e5da5Sopenharmony_ci     %label1 = OpLabel
4999fd4e5da5Sopenharmony_ci     %access = OpAccessChain %_ptr_StorageBuffer_uint %var %uint_0 %uint_0
5000fd4e5da5Sopenharmony_ci       %call = OpFunctionCall %void %called %access
5001fd4e5da5Sopenharmony_ci               OpReturn
5002fd4e5da5Sopenharmony_ci               OpFunctionEnd
5003fd4e5da5Sopenharmony_ci)";
5004fd4e5da5Sopenharmony_ci
5005fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_2);
5006fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
5007fd4e5da5Sopenharmony_ci}
5008fd4e5da5Sopenharmony_ci
5009fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, VulkanPtrAccessChainStorageBufferCapability) {
5010fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
5011fd4e5da5Sopenharmony_ci               OpCapability Shader
5012fd4e5da5Sopenharmony_ci               OpCapability PhysicalStorageBufferAddresses
5013fd4e5da5Sopenharmony_ci               OpExtension "SPV_KHR_storage_buffer_storage_class"
5014fd4e5da5Sopenharmony_ci               OpExtension "SPV_KHR_variable_pointers"
5015fd4e5da5Sopenharmony_ci               OpMemoryModel PhysicalStorageBuffer64 GLSL450
5016fd4e5da5Sopenharmony_ci               OpEntryPoint GLCompute %main "foo" %var
5017fd4e5da5Sopenharmony_ci               OpExecutionMode %main LocalSize 1 1 1
5018fd4e5da5Sopenharmony_ci               OpDecorate %_runtimearr_uint ArrayStride 4
5019fd4e5da5Sopenharmony_ci               OpMemberDecorate %_struct_10 0 Offset 0
5020fd4e5da5Sopenharmony_ci               OpDecorate %_struct_10 Block
5021fd4e5da5Sopenharmony_ci               OpDecorate %var DescriptorSet 0
5022fd4e5da5Sopenharmony_ci               OpDecorate %var Binding 0
5023fd4e5da5Sopenharmony_ci               OpDecorate %_ptr_StorageBuffer_uint ArrayStride 4
5024fd4e5da5Sopenharmony_ci       %uint = OpTypeInt 32 0
5025fd4e5da5Sopenharmony_ci     %uint_0 = OpConstant %uint 0
5026fd4e5da5Sopenharmony_ci     %uint_1 = OpConstant %uint 1
5027fd4e5da5Sopenharmony_ci%_runtimearr_uint = OpTypeRuntimeArray %uint
5028fd4e5da5Sopenharmony_ci %_struct_10 = OpTypeStruct %_runtimearr_uint
5029fd4e5da5Sopenharmony_ci%_ptr_StorageBuffer__struct_10 = OpTypePointer StorageBuffer %_struct_10
5030fd4e5da5Sopenharmony_ci%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
5031fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
5032fd4e5da5Sopenharmony_ci       %func = OpTypeFunction %void
5033fd4e5da5Sopenharmony_ci         %var = OpVariable %_ptr_StorageBuffer__struct_10 StorageBuffer
5034fd4e5da5Sopenharmony_ci       %main = OpFunction %void None %func
5035fd4e5da5Sopenharmony_ci      %label = OpLabel
5036fd4e5da5Sopenharmony_ci     %access = OpAccessChain %_ptr_StorageBuffer_uint %var %uint_0 %uint_0
5037fd4e5da5Sopenharmony_ci %ptr_access = OpPtrAccessChain %_ptr_StorageBuffer_uint %access %uint_1
5038fd4e5da5Sopenharmony_ci               OpReturn
5039fd4e5da5Sopenharmony_ci               OpFunctionEnd
5040fd4e5da5Sopenharmony_ci)";
5041fd4e5da5Sopenharmony_ci
5042fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_2);
5043fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_2));
5044fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
5045fd4e5da5Sopenharmony_ci              AnyVUID("VUID-StandaloneSpirv-Base-07652"));
5046fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
5047fd4e5da5Sopenharmony_ci              HasSubstr("OpPtrAccessChain Base operand pointing to "
5048fd4e5da5Sopenharmony_ci                        "StorageBuffer storage class must use VariablePointers "
5049fd4e5da5Sopenharmony_ci                        "or VariablePointersStorageBuffer capability"));
5050fd4e5da5Sopenharmony_ci}
5051fd4e5da5Sopenharmony_ci
5052fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, VulkanPtrAccessChainWorkgroupCapability) {
5053fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
5054fd4e5da5Sopenharmony_ci               OpCapability Shader
5055fd4e5da5Sopenharmony_ci               OpCapability VariablePointersStorageBuffer
5056fd4e5da5Sopenharmony_ci               OpExtension "SPV_KHR_storage_buffer_storage_class"
5057fd4e5da5Sopenharmony_ci               OpExtension "SPV_KHR_variable_pointers"
5058fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
5059fd4e5da5Sopenharmony_ci               OpEntryPoint GLCompute %main "foo" %var
5060fd4e5da5Sopenharmony_ci               OpExecutionMode %main LocalSize 1 1 1
5061fd4e5da5Sopenharmony_ci               OpDecorate %_ptr_Workgroup_uint ArrayStride 4
5062fd4e5da5Sopenharmony_ci       %uint = OpTypeInt 32 0
5063fd4e5da5Sopenharmony_ci     %uint_0 = OpConstant %uint 0
5064fd4e5da5Sopenharmony_ci     %uint_1 = OpConstant %uint 1
5065fd4e5da5Sopenharmony_ci%_arr_uint = OpTypeArray %uint %uint_1
5066fd4e5da5Sopenharmony_ci%_ptr_Workgroup__arr_uint = OpTypePointer Workgroup %_arr_uint
5067fd4e5da5Sopenharmony_ci%_ptr_Workgroup_uint = OpTypePointer Workgroup %uint
5068fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
5069fd4e5da5Sopenharmony_ci       %func = OpTypeFunction %void
5070fd4e5da5Sopenharmony_ci        %var = OpVariable %_ptr_Workgroup__arr_uint Workgroup
5071fd4e5da5Sopenharmony_ci       %main = OpFunction %void None %func
5072fd4e5da5Sopenharmony_ci      %label = OpLabel
5073fd4e5da5Sopenharmony_ci     %access = OpAccessChain %_ptr_Workgroup_uint %var %uint_0
5074fd4e5da5Sopenharmony_ci %ptr_access = OpPtrAccessChain %_ptr_Workgroup_uint %access %uint_1
5075fd4e5da5Sopenharmony_ci               OpReturn
5076fd4e5da5Sopenharmony_ci               OpFunctionEnd
5077fd4e5da5Sopenharmony_ci)";
5078fd4e5da5Sopenharmony_ci
5079fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_2);
5080fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_2));
5081fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
5082fd4e5da5Sopenharmony_ci              AnyVUID("VUID-StandaloneSpirv-Base-07651"));
5083fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
5084fd4e5da5Sopenharmony_ci              HasSubstr("OpPtrAccessChain Base operand pointing to Workgroup "
5085fd4e5da5Sopenharmony_ci                        "storage class must use VariablePointers capability"));
5086fd4e5da5Sopenharmony_ci}
5087fd4e5da5Sopenharmony_ci
5088fd4e5da5Sopenharmony_ciTEST_F(ValidateMemory, VulkanPtrAccessChainWorkgroupNoArrayStrideSuccess) {
5089fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
5090fd4e5da5Sopenharmony_ci               OpCapability Shader
5091fd4e5da5Sopenharmony_ci               OpCapability VariablePointers
5092fd4e5da5Sopenharmony_ci               OpExtension "SPV_KHR_storage_buffer_storage_class"
5093fd4e5da5Sopenharmony_ci               OpExtension "SPV_KHR_variable_pointers"
5094fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
5095fd4e5da5Sopenharmony_ci               OpEntryPoint GLCompute %main "foo" %var
5096fd4e5da5Sopenharmony_ci               OpExecutionMode %main LocalSize 1 1 1
5097fd4e5da5Sopenharmony_ci       %uint = OpTypeInt 32 0
5098fd4e5da5Sopenharmony_ci     %uint_0 = OpConstant %uint 0
5099fd4e5da5Sopenharmony_ci     %uint_1 = OpConstant %uint 1
5100fd4e5da5Sopenharmony_ci%_arr_uint = OpTypeArray %uint %uint_1
5101fd4e5da5Sopenharmony_ci%_ptr_Workgroup__arr_uint = OpTypePointer Workgroup %_arr_uint
5102fd4e5da5Sopenharmony_ci%_ptr_Workgroup_uint = OpTypePointer Workgroup %uint
5103fd4e5da5Sopenharmony_ci       %void = OpTypeVoid
5104fd4e5da5Sopenharmony_ci       %func = OpTypeFunction %void
5105fd4e5da5Sopenharmony_ci        %var = OpVariable %_ptr_Workgroup__arr_uint Workgroup
5106fd4e5da5Sopenharmony_ci       %main = OpFunction %void None %func
5107fd4e5da5Sopenharmony_ci      %label = OpLabel
5108fd4e5da5Sopenharmony_ci     %access = OpAccessChain %_ptr_Workgroup_uint %var %uint_0
5109fd4e5da5Sopenharmony_ci %ptr_access = OpPtrAccessChain %_ptr_Workgroup_uint %access %uint_1
5110fd4e5da5Sopenharmony_ci               OpReturn
5111fd4e5da5Sopenharmony_ci               OpFunctionEnd
5112fd4e5da5Sopenharmony_ci)";
5113fd4e5da5Sopenharmony_ci
5114fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_2);
5115fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
5116fd4e5da5Sopenharmony_ci}
5117fd4e5da5Sopenharmony_ci
5118fd4e5da5Sopenharmony_ci}  // namespace
5119fd4e5da5Sopenharmony_ci}  // namespace val
5120fd4e5da5Sopenharmony_ci}  // namespace spvtools
5121