1fd4e5da5Sopenharmony_ci// Copyright (c) 2019 Google LLC.
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 misc instructions
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_fixtures.h"
23fd4e5da5Sopenharmony_ci
24fd4e5da5Sopenharmony_cinamespace spvtools {
25fd4e5da5Sopenharmony_cinamespace val {
26fd4e5da5Sopenharmony_cinamespace {
27fd4e5da5Sopenharmony_ci
28fd4e5da5Sopenharmony_ciusing ::testing::Eq;
29fd4e5da5Sopenharmony_ciusing ::testing::HasSubstr;
30fd4e5da5Sopenharmony_ci
31fd4e5da5Sopenharmony_ciusing ValidateMisc = spvtest::ValidateBase<bool>;
32fd4e5da5Sopenharmony_ci
33fd4e5da5Sopenharmony_ciTEST_F(ValidateMisc, UndefRestrictedShort) {
34fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
35fd4e5da5Sopenharmony_ciOpCapability Shader
36fd4e5da5Sopenharmony_ciOpCapability Linkage
37fd4e5da5Sopenharmony_ciOpCapability StorageBuffer16BitAccess
38fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_16bit_storage"
39fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
40fd4e5da5Sopenharmony_ci%short = OpTypeInt 16 0
41fd4e5da5Sopenharmony_ci%undef = OpUndef %short
42fd4e5da5Sopenharmony_ci)";
43fd4e5da5Sopenharmony_ci
44fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv);
45fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
46fd4e5da5Sopenharmony_ci  EXPECT_THAT(
47fd4e5da5Sopenharmony_ci      getDiagnosticString(),
48fd4e5da5Sopenharmony_ci      HasSubstr("Cannot create undefined values with 8- or 16-bit types"));
49fd4e5da5Sopenharmony_ci}
50fd4e5da5Sopenharmony_ci
51fd4e5da5Sopenharmony_ciTEST_F(ValidateMisc, UndefRestrictedChar) {
52fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
53fd4e5da5Sopenharmony_ciOpCapability Shader
54fd4e5da5Sopenharmony_ciOpCapability Linkage
55fd4e5da5Sopenharmony_ciOpCapability StorageBuffer8BitAccess
56fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_8bit_storage"
57fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
58fd4e5da5Sopenharmony_ci%char = OpTypeInt 8 0
59fd4e5da5Sopenharmony_ci%undef = OpUndef %char
60fd4e5da5Sopenharmony_ci)";
61fd4e5da5Sopenharmony_ci
62fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv);
63fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
64fd4e5da5Sopenharmony_ci  EXPECT_THAT(
65fd4e5da5Sopenharmony_ci      getDiagnosticString(),
66fd4e5da5Sopenharmony_ci      HasSubstr("Cannot create undefined values with 8- or 16-bit types"));
67fd4e5da5Sopenharmony_ci}
68fd4e5da5Sopenharmony_ci
69fd4e5da5Sopenharmony_ciTEST_F(ValidateMisc, UndefRestrictedHalf) {
70fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
71fd4e5da5Sopenharmony_ciOpCapability Shader
72fd4e5da5Sopenharmony_ciOpCapability Linkage
73fd4e5da5Sopenharmony_ciOpCapability StorageBuffer16BitAccess
74fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_16bit_storage"
75fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
76fd4e5da5Sopenharmony_ci%half = OpTypeFloat 16
77fd4e5da5Sopenharmony_ci%undef = OpUndef %half
78fd4e5da5Sopenharmony_ci)";
79fd4e5da5Sopenharmony_ci
80fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv);
81fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
82fd4e5da5Sopenharmony_ci  EXPECT_THAT(
83fd4e5da5Sopenharmony_ci      getDiagnosticString(),
84fd4e5da5Sopenharmony_ci      HasSubstr("Cannot create undefined values with 8- or 16-bit types"));
85fd4e5da5Sopenharmony_ci}
86fd4e5da5Sopenharmony_ci
87fd4e5da5Sopenharmony_ciconst std::string ShaderClockSpriv = R"(
88fd4e5da5Sopenharmony_ciOpCapability Shader
89fd4e5da5Sopenharmony_ciOpCapability Int64
90fd4e5da5Sopenharmony_ciOpCapability ShaderClockKHR
91fd4e5da5Sopenharmony_ciOpExtension "SPV_KHR_shader_clock"
92fd4e5da5Sopenharmony_ci%1 = OpExtInstImport "GLSL.std.450"
93fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
94fd4e5da5Sopenharmony_ciOpEntryPoint Fragment %main "main"
95fd4e5da5Sopenharmony_ciOpExecutionMode %main OriginUpperLeft
96fd4e5da5Sopenharmony_ciOpSource GLSL 450
97fd4e5da5Sopenharmony_ciOpSourceExtension "GL_ARB_gpu_shader_int64"
98fd4e5da5Sopenharmony_ciOpSourceExtension "GL_ARB_shader_clock"
99fd4e5da5Sopenharmony_ciOpSourceExtension "GL_EXT_shader_realtime_clock"
100fd4e5da5Sopenharmony_ciOpName %main "main"
101fd4e5da5Sopenharmony_ciOpName %time1 "time1"
102fd4e5da5Sopenharmony_ci%void = OpTypeVoid
103fd4e5da5Sopenharmony_ci)";
104fd4e5da5Sopenharmony_ci
105fd4e5da5Sopenharmony_ciTEST_F(ValidateMisc, ShaderClockInt64) {
106fd4e5da5Sopenharmony_ci  const std::string spirv = ShaderClockSpriv + R"(
107fd4e5da5Sopenharmony_ci%3 = OpTypeFunction %void
108fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
109fd4e5da5Sopenharmony_ci%_ptr_Function_uint = OpTypePointer Function %uint
110fd4e5da5Sopenharmony_ci%uint_3 = OpConstant %uint 3
111fd4e5da5Sopenharmony_ci%uint_1 = OpConstant %uint 1
112fd4e5da5Sopenharmony_ci%main = OpFunction %void None %3
113fd4e5da5Sopenharmony_ci%5 = OpLabel
114fd4e5da5Sopenharmony_ci%time1 = OpVariable %_ptr_Function_uint Function
115fd4e5da5Sopenharmony_ci%11 = OpReadClockKHR %uint %uint_3
116fd4e5da5Sopenharmony_ciOpStore %time1 %11
117fd4e5da5Sopenharmony_ciOpReturn
118fd4e5da5Sopenharmony_ciOpFunctionEnd)";
119fd4e5da5Sopenharmony_ci
120fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv);
121fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
122fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(), HasSubstr("or 64bit unsigned integer"));
123fd4e5da5Sopenharmony_ci}
124fd4e5da5Sopenharmony_ci
125fd4e5da5Sopenharmony_ciTEST_F(ValidateMisc, ShaderClockVec2) {
126fd4e5da5Sopenharmony_ci  const std::string spirv = ShaderClockSpriv + R"(
127fd4e5da5Sopenharmony_ci%3 = OpTypeFunction %void
128fd4e5da5Sopenharmony_ci%ulong = OpTypeInt 64 0
129fd4e5da5Sopenharmony_ci%_ptr_Function_ulong = OpTypePointer Function %ulong
130fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
131fd4e5da5Sopenharmony_ci%uint_3 = OpConstant %uint 3
132fd4e5da5Sopenharmony_ci%v2uint = OpTypeVector %ulong 2
133fd4e5da5Sopenharmony_ci%_ptr_Function_v2uint = OpTypePointer Function %v2uint
134fd4e5da5Sopenharmony_ci%main = OpFunction %void None %3
135fd4e5da5Sopenharmony_ci%5 = OpLabel
136fd4e5da5Sopenharmony_ci%time1 = OpVariable %_ptr_Function_v2uint Function
137fd4e5da5Sopenharmony_ci%15 = OpReadClockKHR %v2uint %uint_3
138fd4e5da5Sopenharmony_ciOpStore %time1 %15
139fd4e5da5Sopenharmony_ciOpReturn
140fd4e5da5Sopenharmony_ciOpFunctionEnd)";
141fd4e5da5Sopenharmony_ci
142fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv);
143fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
144fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(), HasSubstr("vector of two components"));
145fd4e5da5Sopenharmony_ci}
146fd4e5da5Sopenharmony_ci
147fd4e5da5Sopenharmony_ciTEST_F(ValidateMisc, ShaderClockInvalidScopeValue) {
148fd4e5da5Sopenharmony_ci  const std::string spirv = ShaderClockSpriv + R"(
149fd4e5da5Sopenharmony_ci%3 = OpTypeFunction %void
150fd4e5da5Sopenharmony_ci%ulong = OpTypeInt 64 0
151fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
152fd4e5da5Sopenharmony_ci%_ptr_Function_ulong = OpTypePointer Function %ulong
153fd4e5da5Sopenharmony_ci%uint_10 = OpConstant %uint 10
154fd4e5da5Sopenharmony_ci%uint_1 = OpConstant %uint 1
155fd4e5da5Sopenharmony_ci%main = OpFunction %void None %3
156fd4e5da5Sopenharmony_ci%5 = OpLabel
157fd4e5da5Sopenharmony_ci%time1 = OpVariable %_ptr_Function_ulong Function
158fd4e5da5Sopenharmony_ci%11 = OpReadClockKHR %ulong %uint_10
159fd4e5da5Sopenharmony_ciOpStore %time1 %11
160fd4e5da5Sopenharmony_ciOpReturn
161fd4e5da5Sopenharmony_ciOpFunctionEnd)";
162fd4e5da5Sopenharmony_ci
163fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv);
164fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
165fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(), HasSubstr("Invalid scope value"));
166fd4e5da5Sopenharmony_ci}
167fd4e5da5Sopenharmony_ci
168fd4e5da5Sopenharmony_ciTEST_F(ValidateMisc, ShaderClockSubgroupScope) {
169fd4e5da5Sopenharmony_ci  const std::string spirv = ShaderClockSpriv + R"(
170fd4e5da5Sopenharmony_ci%3 = OpTypeFunction %void
171fd4e5da5Sopenharmony_ci%ulong = OpTypeInt 64 0
172fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
173fd4e5da5Sopenharmony_ci%_ptr_Function_ulong = OpTypePointer Function %ulong
174fd4e5da5Sopenharmony_ci%subgroup = OpConstant %uint 3
175fd4e5da5Sopenharmony_ci%uint_1 = OpConstant %uint 1
176fd4e5da5Sopenharmony_ci%main = OpFunction %void None %3
177fd4e5da5Sopenharmony_ci%5 = OpLabel
178fd4e5da5Sopenharmony_ci%time1 = OpVariable %_ptr_Function_ulong Function
179fd4e5da5Sopenharmony_ci%11 = OpReadClockKHR %ulong %subgroup
180fd4e5da5Sopenharmony_ciOpStore %time1 %11
181fd4e5da5Sopenharmony_ciOpReturn
182fd4e5da5Sopenharmony_ciOpFunctionEnd)";
183fd4e5da5Sopenharmony_ci
184fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv);
185fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
186fd4e5da5Sopenharmony_ci}
187fd4e5da5Sopenharmony_ci
188fd4e5da5Sopenharmony_ciTEST_F(ValidateMisc, ShaderClockDeviceScope) {
189fd4e5da5Sopenharmony_ci  const std::string spirv = ShaderClockSpriv + R"(
190fd4e5da5Sopenharmony_ci%3 = OpTypeFunction %void
191fd4e5da5Sopenharmony_ci%ulong = OpTypeInt 64 0
192fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
193fd4e5da5Sopenharmony_ci%_ptr_Function_ulong = OpTypePointer Function %ulong
194fd4e5da5Sopenharmony_ci%device = OpConstant %uint 1
195fd4e5da5Sopenharmony_ci%uint_1 = OpConstant %uint 1
196fd4e5da5Sopenharmony_ci%main = OpFunction %void None %3
197fd4e5da5Sopenharmony_ci%5 = OpLabel
198fd4e5da5Sopenharmony_ci%time1 = OpVariable %_ptr_Function_ulong Function
199fd4e5da5Sopenharmony_ci%11 = OpReadClockKHR %ulong %device
200fd4e5da5Sopenharmony_ciOpStore %time1 %11
201fd4e5da5Sopenharmony_ciOpReturn
202fd4e5da5Sopenharmony_ciOpFunctionEnd)";
203fd4e5da5Sopenharmony_ci
204fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv);
205fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
206fd4e5da5Sopenharmony_ci}
207fd4e5da5Sopenharmony_ci
208fd4e5da5Sopenharmony_ciTEST_F(ValidateMisc, ShaderClockWorkgroupScope) {
209fd4e5da5Sopenharmony_ci  const std::string spirv = ShaderClockSpriv + R"(
210fd4e5da5Sopenharmony_ci%3 = OpTypeFunction %void
211fd4e5da5Sopenharmony_ci%ulong = OpTypeInt 64 0
212fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
213fd4e5da5Sopenharmony_ci%_ptr_Function_ulong = OpTypePointer Function %ulong
214fd4e5da5Sopenharmony_ci%workgroup = OpConstant %uint 2
215fd4e5da5Sopenharmony_ci%uint_1 = OpConstant %uint 1
216fd4e5da5Sopenharmony_ci%main = OpFunction %void None %3
217fd4e5da5Sopenharmony_ci%5 = OpLabel
218fd4e5da5Sopenharmony_ci%time1 = OpVariable %_ptr_Function_ulong Function
219fd4e5da5Sopenharmony_ci%11 = OpReadClockKHR %ulong %workgroup
220fd4e5da5Sopenharmony_ciOpStore %time1 %11
221fd4e5da5Sopenharmony_ciOpReturn
222fd4e5da5Sopenharmony_ciOpFunctionEnd)";
223fd4e5da5Sopenharmony_ci
224fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv);
225fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
226fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
227fd4e5da5Sopenharmony_ci              HasSubstr("Scope must be Subgroup or Device"));
228fd4e5da5Sopenharmony_ci}
229fd4e5da5Sopenharmony_ci
230fd4e5da5Sopenharmony_ciTEST_F(ValidateMisc, VulkanShaderClockWorkgroupScope) {
231fd4e5da5Sopenharmony_ci  const std::string spirv = ShaderClockSpriv + R"(
232fd4e5da5Sopenharmony_ci%3 = OpTypeFunction %void
233fd4e5da5Sopenharmony_ci%ulong = OpTypeInt 64 0
234fd4e5da5Sopenharmony_ci%uint = OpTypeInt 32 0
235fd4e5da5Sopenharmony_ci%_ptr_Function_ulong = OpTypePointer Function %ulong
236fd4e5da5Sopenharmony_ci%workgroup = OpConstant %uint 2
237fd4e5da5Sopenharmony_ci%uint_1 = OpConstant %uint 1
238fd4e5da5Sopenharmony_ci%main = OpFunction %void None %3
239fd4e5da5Sopenharmony_ci%5 = OpLabel
240fd4e5da5Sopenharmony_ci%time1 = OpVariable %_ptr_Function_ulong Function
241fd4e5da5Sopenharmony_ci%11 = OpReadClockKHR %ulong %workgroup
242fd4e5da5Sopenharmony_ciOpStore %time1 %11
243fd4e5da5Sopenharmony_ciOpReturn
244fd4e5da5Sopenharmony_ciOpFunctionEnd)";
245fd4e5da5Sopenharmony_ci
246fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
247fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
248fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
249fd4e5da5Sopenharmony_ci              AnyVUID("VUID-StandaloneSpirv-OpReadClockKHR-04652"));
250fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
251fd4e5da5Sopenharmony_ci              HasSubstr("Scope must be Subgroup or Device"));
252fd4e5da5Sopenharmony_ci}
253fd4e5da5Sopenharmony_ci
254fd4e5da5Sopenharmony_ciTEST_F(ValidateMisc, UndefVoid) {
255fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
256fd4e5da5Sopenharmony_ci               OpCapability Shader
257fd4e5da5Sopenharmony_ci          %1 = OpExtInstImport "GLSL.std.450"
258fd4e5da5Sopenharmony_ci               OpMemoryModel Logical GLSL450
259fd4e5da5Sopenharmony_ci               OpEntryPoint Fragment %4 "main"
260fd4e5da5Sopenharmony_ci               OpExecutionMode %4 OriginUpperLeft
261fd4e5da5Sopenharmony_ci               OpSource ESSL 320
262fd4e5da5Sopenharmony_ci          %2 = OpTypeVoid
263fd4e5da5Sopenharmony_ci         %10 = OpUndef %2
264fd4e5da5Sopenharmony_ci          %3 = OpTypeFunction %2
265fd4e5da5Sopenharmony_ci          %4 = OpFunction %2 None %3
266fd4e5da5Sopenharmony_ci          %5 = OpLabel
267fd4e5da5Sopenharmony_ci               OpReturn
268fd4e5da5Sopenharmony_ci               OpFunctionEnd
269fd4e5da5Sopenharmony_ci)";
270fd4e5da5Sopenharmony_ci
271fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv);
272fd4e5da5Sopenharmony_ci  EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
273fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
274fd4e5da5Sopenharmony_ci              HasSubstr("Cannot create undefined values with void type"));
275fd4e5da5Sopenharmony_ci}
276fd4e5da5Sopenharmony_ci
277fd4e5da5Sopenharmony_ciTEST_F(ValidateMisc, VulkanInvalidStorageClass) {
278fd4e5da5Sopenharmony_ci  const std::string spirv = R"(
279fd4e5da5Sopenharmony_ciOpCapability Shader
280fd4e5da5Sopenharmony_ciOpMemoryModel Logical GLSL450
281fd4e5da5Sopenharmony_ciOpEntryPoint Vertex %func "shader"
282fd4e5da5Sopenharmony_ci%int = OpTypeInt 32 0
283fd4e5da5Sopenharmony_ci%ptr = OpTypePointer CrossWorkgroup %int
284fd4e5da5Sopenharmony_ci%var = OpVariable %ptr CrossWorkgroup
285fd4e5da5Sopenharmony_ci%void   = OpTypeVoid
286fd4e5da5Sopenharmony_ci%void_f = OpTypeFunction %void
287fd4e5da5Sopenharmony_ci%func   = OpFunction %void None %void_f
288fd4e5da5Sopenharmony_ci%label  = OpLabel
289fd4e5da5Sopenharmony_ci          OpReturn
290fd4e5da5Sopenharmony_ci          OpFunctionEnd
291fd4e5da5Sopenharmony_ci)";
292fd4e5da5Sopenharmony_ci
293fd4e5da5Sopenharmony_ci  CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
294fd4e5da5Sopenharmony_ci  ASSERT_EQ(SPV_ERROR_INVALID_BINARY, ValidateInstructions(SPV_ENV_VULKAN_1_0));
295fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
296fd4e5da5Sopenharmony_ci              AnyVUID("VUID-StandaloneSpirv-None-04643"));
297fd4e5da5Sopenharmony_ci  EXPECT_THAT(getDiagnosticString(),
298fd4e5da5Sopenharmony_ci              HasSubstr("Invalid storage class for target environment"));
299fd4e5da5Sopenharmony_ci}
300fd4e5da5Sopenharmony_ci}  // namespace
301fd4e5da5Sopenharmony_ci}  // namespace val
302fd4e5da5Sopenharmony_ci}  // namespace spvtools
303