• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2019 Google LLC.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 // Validation tests for misc instructions
16 
17 #include <string>
18 #include <vector>
19 
20 #include "gmock/gmock.h"
21 #include "test/unit_spirv.h"
22 #include "test/val/val_fixtures.h"
23 
24 namespace spvtools {
25 namespace val {
26 namespace {
27 
28 using ::testing::Eq;
29 using ::testing::HasSubstr;
30 
31 using ValidateMisc = spvtest::ValidateBase<bool>;
32 
TEST_F(ValidateMisc,UndefRestrictedShort)33 TEST_F(ValidateMisc, UndefRestrictedShort) {
34   const std::string spirv = R"(
35 OpCapability Shader
36 OpCapability Linkage
37 OpCapability StorageBuffer16BitAccess
38 OpExtension "SPV_KHR_16bit_storage"
39 OpMemoryModel Logical GLSL450
40 %short = OpTypeInt 16 0
41 %undef = OpUndef %short
42 )";
43 
44   CompileSuccessfully(spirv);
45   EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
46   EXPECT_THAT(
47       getDiagnosticString(),
48       HasSubstr("Cannot create undefined values with 8- or 16-bit types"));
49 }
50 
TEST_F(ValidateMisc,UndefRestrictedChar)51 TEST_F(ValidateMisc, UndefRestrictedChar) {
52   const std::string spirv = R"(
53 OpCapability Shader
54 OpCapability Linkage
55 OpCapability StorageBuffer8BitAccess
56 OpExtension "SPV_KHR_8bit_storage"
57 OpMemoryModel Logical GLSL450
58 %char = OpTypeInt 8 0
59 %undef = OpUndef %char
60 )";
61 
62   CompileSuccessfully(spirv);
63   EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
64   EXPECT_THAT(
65       getDiagnosticString(),
66       HasSubstr("Cannot create undefined values with 8- or 16-bit types"));
67 }
68 
TEST_F(ValidateMisc,UndefRestrictedHalf)69 TEST_F(ValidateMisc, UndefRestrictedHalf) {
70   const std::string spirv = R"(
71 OpCapability Shader
72 OpCapability Linkage
73 OpCapability StorageBuffer16BitAccess
74 OpExtension "SPV_KHR_16bit_storage"
75 OpMemoryModel Logical GLSL450
76 %half = OpTypeFloat 16
77 %undef = OpUndef %half
78 )";
79 
80   CompileSuccessfully(spirv);
81   EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
82   EXPECT_THAT(
83       getDiagnosticString(),
84       HasSubstr("Cannot create undefined values with 8- or 16-bit types"));
85 }
86 
TEST_F(ValidateMisc,SizeOfValid)87 TEST_F(ValidateMisc, SizeOfValid) {
88   const std::string spirv = R"(
89                OpCapability Addresses
90                OpCapability Kernel
91                OpMemoryModel Physical64 OpenCL
92                OpEntryPoint Kernel %f "f"
93        %void = OpTypeVoid
94         %i32 = OpTypeInt 32 0
95         %ptr = OpTypePointer CrossWorkgroup %i32
96        %fnTy = OpTypeFunction %void
97           %f = OpFunction %void None %fnTy
98       %entry = OpLabel
99           %s = OpSizeOf %i32 %ptr
100                OpReturn
101                OpFunctionEnd
102 )";
103 
104   CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_1);
105   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_1));
106 }
107 
108 const std::string ShaderClockSpirv = R"(
109 OpCapability Shader
110 OpCapability Int64
111 OpCapability ShaderClockKHR
112 OpExtension "SPV_KHR_shader_clock"
113 %1 = OpExtInstImport "GLSL.std.450"
114 OpMemoryModel Logical GLSL450
115 OpEntryPoint Fragment %main "main"
116 OpExecutionMode %main OriginUpperLeft
117 OpSource GLSL 450
118 OpSourceExtension "GL_ARB_gpu_shader_int64"
119 OpSourceExtension "GL_ARB_shader_clock"
120 OpSourceExtension "GL_EXT_shader_realtime_clock"
121 OpName %main "main"
122 OpName %time1 "time1"
123 %void = OpTypeVoid
124 )";
125 
TEST_F(ValidateMisc,ShaderClockInt64)126 TEST_F(ValidateMisc, ShaderClockInt64) {
127   const std::string spirv = ShaderClockSpirv + R"(
128 %3 = OpTypeFunction %void
129 %uint = OpTypeInt 32 0
130 %_ptr_Function_uint = OpTypePointer Function %uint
131 %uint_3 = OpConstant %uint 3
132 %uint_1 = OpConstant %uint 1
133 %main = OpFunction %void None %3
134 %5 = OpLabel
135 %time1 = OpVariable %_ptr_Function_uint Function
136 %11 = OpReadClockKHR %uint %uint_3
137 OpStore %time1 %11
138 OpReturn
139 OpFunctionEnd)";
140 
141   CompileSuccessfully(spirv);
142   EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
143   EXPECT_THAT(getDiagnosticString(), HasSubstr("or 64bit unsigned integer"));
144 }
145 
TEST_F(ValidateMisc,ShaderClockVec2)146 TEST_F(ValidateMisc, ShaderClockVec2) {
147   const std::string spirv = ShaderClockSpirv + R"(
148 %3 = OpTypeFunction %void
149 %ulong = OpTypeInt 64 0
150 %_ptr_Function_ulong = OpTypePointer Function %ulong
151 %uint = OpTypeInt 32 0
152 %uint_3 = OpConstant %uint 3
153 %v2uint = OpTypeVector %ulong 2
154 %_ptr_Function_v2uint = OpTypePointer Function %v2uint
155 %main = OpFunction %void None %3
156 %5 = OpLabel
157 %time1 = OpVariable %_ptr_Function_v2uint Function
158 %15 = OpReadClockKHR %v2uint %uint_3
159 OpStore %time1 %15
160 OpReturn
161 OpFunctionEnd)";
162 
163   CompileSuccessfully(spirv);
164   EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
165   EXPECT_THAT(getDiagnosticString(), HasSubstr("vector of two components"));
166 }
167 
TEST_F(ValidateMisc,ShaderClockInvalidScopeValue)168 TEST_F(ValidateMisc, ShaderClockInvalidScopeValue) {
169   const std::string spirv = ShaderClockSpirv + R"(
170 %3 = OpTypeFunction %void
171 %ulong = OpTypeInt 64 0
172 %uint = OpTypeInt 32 0
173 %_ptr_Function_ulong = OpTypePointer Function %ulong
174 %uint_10 = OpConstant %uint 10
175 %uint_1 = OpConstant %uint 1
176 %main = OpFunction %void None %3
177 %5 = OpLabel
178 %time1 = OpVariable %_ptr_Function_ulong Function
179 %11 = OpReadClockKHR %ulong %uint_10
180 OpStore %time1 %11
181 OpReturn
182 OpFunctionEnd)";
183 
184   CompileSuccessfully(spirv);
185   EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
186   EXPECT_THAT(getDiagnosticString(), HasSubstr("Invalid scope value"));
187 }
188 
TEST_F(ValidateMisc,ShaderClockSubgroupScope)189 TEST_F(ValidateMisc, ShaderClockSubgroupScope) {
190   const std::string spirv = ShaderClockSpirv + R"(
191 %3 = OpTypeFunction %void
192 %ulong = OpTypeInt 64 0
193 %uint = OpTypeInt 32 0
194 %_ptr_Function_ulong = OpTypePointer Function %ulong
195 %subgroup = OpConstant %uint 3
196 %uint_1 = OpConstant %uint 1
197 %main = OpFunction %void None %3
198 %5 = OpLabel
199 %time1 = OpVariable %_ptr_Function_ulong Function
200 %11 = OpReadClockKHR %ulong %subgroup
201 OpStore %time1 %11
202 OpReturn
203 OpFunctionEnd)";
204 
205   CompileSuccessfully(spirv);
206   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
207 }
208 
TEST_F(ValidateMisc,ShaderClockDeviceScope)209 TEST_F(ValidateMisc, ShaderClockDeviceScope) {
210   const std::string spirv = ShaderClockSpirv + R"(
211 %3 = OpTypeFunction %void
212 %ulong = OpTypeInt 64 0
213 %uint = OpTypeInt 32 0
214 %_ptr_Function_ulong = OpTypePointer Function %ulong
215 %device = OpConstant %uint 1
216 %uint_1 = OpConstant %uint 1
217 %main = OpFunction %void None %3
218 %5 = OpLabel
219 %time1 = OpVariable %_ptr_Function_ulong Function
220 %11 = OpReadClockKHR %ulong %device
221 OpStore %time1 %11
222 OpReturn
223 OpFunctionEnd)";
224 
225   CompileSuccessfully(spirv);
226   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
227 }
228 
TEST_F(ValidateMisc,ShaderClockWorkgroupScope)229 TEST_F(ValidateMisc, ShaderClockWorkgroupScope) {
230   const std::string spirv = ShaderClockSpirv + R"(
231 %3 = OpTypeFunction %void
232 %ulong = OpTypeInt 64 0
233 %uint = OpTypeInt 32 0
234 %_ptr_Function_ulong = OpTypePointer Function %ulong
235 %workgroup = OpConstant %uint 2
236 %uint_1 = OpConstant %uint 1
237 %main = OpFunction %void None %3
238 %5 = OpLabel
239 %time1 = OpVariable %_ptr_Function_ulong Function
240 %11 = OpReadClockKHR %ulong %workgroup
241 OpStore %time1 %11
242 OpReturn
243 OpFunctionEnd)";
244 
245   CompileSuccessfully(spirv);
246   EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
247   EXPECT_THAT(getDiagnosticString(),
248               HasSubstr("Scope must be Subgroup or Device"));
249 }
250 
TEST_F(ValidateMisc,VulkanShaderClockWorkgroupScope)251 TEST_F(ValidateMisc, VulkanShaderClockWorkgroupScope) {
252   const std::string spirv = ShaderClockSpirv + R"(
253 %3 = OpTypeFunction %void
254 %ulong = OpTypeInt 64 0
255 %uint = OpTypeInt 32 0
256 %_ptr_Function_ulong = OpTypePointer Function %ulong
257 %workgroup = OpConstant %uint 2
258 %uint_1 = OpConstant %uint 1
259 %main = OpFunction %void None %3
260 %5 = OpLabel
261 %time1 = OpVariable %_ptr_Function_ulong Function
262 %11 = OpReadClockKHR %ulong %workgroup
263 OpStore %time1 %11
264 OpReturn
265 OpFunctionEnd)";
266 
267   CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
268   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
269   EXPECT_THAT(getDiagnosticString(),
270               AnyVUID("VUID-StandaloneSpirv-OpReadClockKHR-04652"));
271   EXPECT_THAT(getDiagnosticString(),
272               HasSubstr("Scope must be Subgroup or Device"));
273 }
274 
GenKernelClockSpirv(const std::string & scope)275 std::string GenKernelClockSpirv(const std::string& scope) {
276   const std::string s = R"(
277 OpCapability Kernel
278 OpCapability Addresses
279 OpCapability Int64
280 OpCapability ShaderClockKHR
281 OpExtension "SPV_KHR_shader_clock"
282 OpMemoryModel Physical32 OpenCL
283 OpEntryPoint Kernel %main "main"
284 OpExecutionMode %main ContractionOff
285 OpSource OpenCL_C 200000
286 OpName %main "main"
287 OpName %time1 "time1"
288 %void = OpTypeVoid
289 %3 = OpTypeFunction %void
290 %ulong = OpTypeInt 64 0
291 %uint = OpTypeInt 32 0
292 %_ptr_Function_ulong = OpTypePointer Function %ulong
293 %scope = OpConstant %uint )" +
294                         scope + R"(
295 %main = OpFunction %void None %3
296 %5 = OpLabel
297 %time1 = OpVariable %_ptr_Function_ulong Function
298 %11 = OpReadClockKHR %ulong %scope
299 OpStore %time1 %11
300 OpReturn
301 OpFunctionEnd
302 )";
303   return s;
304 }
305 
TEST_F(ValidateMisc,KernelClockScopeDevice)306 TEST_F(ValidateMisc, KernelClockScopeDevice) {
307   CompileSuccessfully(GenKernelClockSpirv("1"), SPV_ENV_OPENCL_1_2);
308   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_OPENCL_1_2));
309 }
310 
TEST_F(ValidateMisc,KernelClockScopeWorkgroup)311 TEST_F(ValidateMisc, KernelClockScopeWorkgroup) {
312   CompileSuccessfully(GenKernelClockSpirv("2"), SPV_ENV_OPENCL_1_2);
313   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_OPENCL_1_2));
314 }
315 
TEST_F(ValidateMisc,KernelClockScopeSubgroup)316 TEST_F(ValidateMisc, KernelClockScopeSubgroup) {
317   CompileSuccessfully(GenKernelClockSpirv("3"), SPV_ENV_OPENCL_1_2);
318   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_OPENCL_1_2));
319 }
320 
TEST_F(ValidateMisc,KernelClockScopeInvalid)321 TEST_F(ValidateMisc, KernelClockScopeInvalid) {
322   CompileSuccessfully(GenKernelClockSpirv("0"), SPV_ENV_OPENCL_1_2);
323   EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_OPENCL_1_2));
324   EXPECT_THAT(getDiagnosticString(),
325               HasSubstr("Scope must be Subgroup, Workgroup, or Device"));
326 }
327 
TEST_F(ValidateMisc,UndefVoid)328 TEST_F(ValidateMisc, UndefVoid) {
329   const std::string spirv = R"(
330                OpCapability Shader
331           %1 = OpExtInstImport "GLSL.std.450"
332                OpMemoryModel Logical GLSL450
333                OpEntryPoint Fragment %4 "main"
334                OpExecutionMode %4 OriginUpperLeft
335                OpSource ESSL 320
336           %2 = OpTypeVoid
337          %10 = OpUndef %2
338           %3 = OpTypeFunction %2
339           %4 = OpFunction %2 None %3
340           %5 = OpLabel
341                OpReturn
342                OpFunctionEnd
343 )";
344 
345   CompileSuccessfully(spirv);
346   EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
347   EXPECT_THAT(getDiagnosticString(),
348               HasSubstr("Cannot create undefined values with void type"));
349 }
350 
TEST_F(ValidateMisc,VulkanInvalidStorageClass)351 TEST_F(ValidateMisc, VulkanInvalidStorageClass) {
352   const std::string spirv = R"(
353 OpCapability Shader
354 OpMemoryModel Logical GLSL450
355 OpEntryPoint Vertex %func "shader"
356 %int = OpTypeInt 32 0
357 %ptr = OpTypePointer CrossWorkgroup %int
358 %var = OpVariable %ptr CrossWorkgroup
359 %void   = OpTypeVoid
360 %void_f = OpTypeFunction %void
361 %func   = OpFunction %void None %void_f
362 %label  = OpLabel
363           OpReturn
364           OpFunctionEnd
365 )";
366 
367   CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
368   ASSERT_EQ(SPV_ERROR_INVALID_BINARY, ValidateInstructions(SPV_ENV_VULKAN_1_0));
369   EXPECT_THAT(getDiagnosticString(),
370               AnyVUID("VUID-StandaloneSpirv-None-04643"));
371   EXPECT_THAT(getDiagnosticString(),
372               HasSubstr("Invalid storage class for target environment"));
373 }
374 
TEST_F(ValidateMisc,CoopMat2WorkgroupLocalSizeIdPass)375 TEST_F(ValidateMisc, CoopMat2WorkgroupLocalSizeIdPass) {
376   const std::string body = R"(
377 OpCapability Shader
378 OpCapability Float16
379 OpCapability Int16
380 OpCapability CooperativeMatrixKHR
381 OpExtension "SPV_KHR_cooperative_matrix"
382 OpExtension "SPV_KHR_vulkan_memory_model"
383 OpMemoryModel Logical GLSL450
384 OpEntryPoint GLCompute %main "main"
385 OpExecutionModeId %main LocalSizeId %u32_16 %u32_16 %u32_16
386 %void = OpTypeVoid
387 %func = OpTypeFunction %void
388 %bool = OpTypeBool
389 %f16 = OpTypeFloat 16
390 %u32 = OpTypeInt 32 0
391 
392 %u32_16 = OpConstant %u32 16
393 %use_Acc = OpConstant %u32 2
394 %workgroup = OpConstant %u32 2
395 
396 %f16mat = OpTypeCooperativeMatrixKHR %f16 %workgroup %u32_16 %u32_16 %use_Acc
397 
398 %main = OpFunction %void None %func
399 %main_entry = OpLabel
400 
401 OpReturn
402 OpFunctionEnd)";
403 
404   CompileSuccessfully(body.c_str(), SPV_ENV_UNIVERSAL_1_3);
405   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
406 }
407 
TEST_F(ValidateMisc,CoopMat2WorkgroupLocalSizeIdConstantNotDeclaredYetFail)408 TEST_F(ValidateMisc, CoopMat2WorkgroupLocalSizeIdConstantNotDeclaredYetFail) {
409   const std::string body = R"(
410 OpCapability Shader
411 OpCapability Float16
412 OpCapability Int16
413 OpCapability CooperativeMatrixKHR
414 OpExtension "SPV_KHR_cooperative_matrix"
415 OpExtension "SPV_KHR_vulkan_memory_model"
416 OpMemoryModel Logical GLSL450
417 OpEntryPoint GLCompute %main "main"
418 OpExecutionModeId %main LocalSizeId %u32_16 %u32_8 %u32_16
419 %void = OpTypeVoid
420 %func = OpTypeFunction %void
421 %bool = OpTypeBool
422 %f16 = OpTypeFloat 16
423 %u32 = OpTypeInt 32 0
424 
425 %u32_16 = OpConstant %u32 16
426 %use_Acc = OpConstant %u32 2
427 %workgroup = OpConstant %u32 2
428 
429 %f16mat = OpTypeCooperativeMatrixKHR %f16 %workgroup %u32_16 %u32_16 %use_Acc
430 %u32_8 = OpConstant %u32 8
431 
432 %main = OpFunction %void None %func
433 %main_entry = OpLabel
434 
435 OpReturn
436 OpFunctionEnd)";
437 
438   CompileSuccessfully(body.c_str(), SPV_ENV_UNIVERSAL_1_3);
439   EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
440   EXPECT_THAT(getDiagnosticString(),
441               HasSubstr("OpTypeCooperativeMatrixKHR with ScopeWorkgroup used "
442                         "before LocalSizeId constant value"));
443 }
444 
445 }  // namespace
446 }  // namespace val
447 }  // namespace spvtools
448