1 // Copyright (c) 2017 Google Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 // Tests for unique type declaration rules validator.
16
17 #include <string>
18
19 #include "gmock/gmock.h"
20 #include "test/unit_spirv.h"
21 #include "test/val/val_fixtures.h"
22
23 namespace spvtools {
24 namespace val {
25 namespace {
26
27 using ::testing::HasSubstr;
28 using ::testing::Not;
29
30 using ValidateBitwise = spvtest::ValidateBase<bool>;
31
GenerateShaderCode(const std::string & body,const std::string & capabilities_and_extensions="")32 std::string GenerateShaderCode(
33 const std::string& body,
34 const std::string& capabilities_and_extensions = "") {
35 const std::string capabilities =
36 R"(
37 OpCapability Shader
38 OpCapability Int64
39 OpCapability Float64)";
40
41 const std::string after_extension_before_body =
42 R"(
43 OpMemoryModel Logical GLSL450
44 OpEntryPoint Fragment %main "main"
45 OpExecutionMode %main OriginUpperLeft
46 %void = OpTypeVoid
47 %func = OpTypeFunction %void
48 %bool = OpTypeBool
49 %f32 = OpTypeFloat 32
50 %u32 = OpTypeInt 32 0
51 %s32 = OpTypeInt 32 1
52 %f64 = OpTypeFloat 64
53 %u64 = OpTypeInt 64 0
54 %s64 = OpTypeInt 64 1
55 %boolvec2 = OpTypeVector %bool 2
56 %s32vec2 = OpTypeVector %s32 2
57 %u32vec2 = OpTypeVector %u32 2
58 %u64vec2 = OpTypeVector %u64 2
59 %f32vec2 = OpTypeVector %f32 2
60 %f64vec2 = OpTypeVector %f64 2
61 %boolvec3 = OpTypeVector %bool 3
62 %u32vec3 = OpTypeVector %u32 3
63 %u64vec3 = OpTypeVector %u64 3
64 %s32vec3 = OpTypeVector %s32 3
65 %f32vec3 = OpTypeVector %f32 3
66 %f64vec3 = OpTypeVector %f64 3
67 %boolvec4 = OpTypeVector %bool 4
68 %u32vec4 = OpTypeVector %u32 4
69 %u64vec4 = OpTypeVector %u64 4
70 %s32vec4 = OpTypeVector %s32 4
71 %f32vec4 = OpTypeVector %f32 4
72 %f64vec4 = OpTypeVector %f64 4
73
74 %f32_0 = OpConstant %f32 0
75 %f32_1 = OpConstant %f32 1
76 %f32_2 = OpConstant %f32 2
77 %f32_3 = OpConstant %f32 3
78 %f32_4 = OpConstant %f32 4
79
80 %s32_0 = OpConstant %s32 0
81 %s32_1 = OpConstant %s32 1
82 %s32_2 = OpConstant %s32 2
83 %s32_3 = OpConstant %s32 3
84 %s32_4 = OpConstant %s32 4
85 %s32_m1 = OpConstant %s32 -1
86
87 %u32_0 = OpConstant %u32 0
88 %u32_1 = OpConstant %u32 1
89 %u32_2 = OpConstant %u32 2
90 %u32_3 = OpConstant %u32 3
91 %u32_4 = OpConstant %u32 4
92
93 %f64_0 = OpConstant %f64 0
94 %f64_1 = OpConstant %f64 1
95 %f64_2 = OpConstant %f64 2
96 %f64_3 = OpConstant %f64 3
97 %f64_4 = OpConstant %f64 4
98
99 %s64_0 = OpConstant %s64 0
100 %s64_1 = OpConstant %s64 1
101 %s64_2 = OpConstant %s64 2
102 %s64_3 = OpConstant %s64 3
103 %s64_4 = OpConstant %s64 4
104 %s64_m1 = OpConstant %s64 -1
105
106 %u64_0 = OpConstant %u64 0
107 %u64_1 = OpConstant %u64 1
108 %u64_2 = OpConstant %u64 2
109 %u64_3 = OpConstant %u64 3
110 %u64_4 = OpConstant %u64 4
111
112 %u32vec2_01 = OpConstantComposite %u32vec2 %u32_0 %u32_1
113 %u32vec2_12 = OpConstantComposite %u32vec2 %u32_1 %u32_2
114 %u32vec3_012 = OpConstantComposite %u32vec3 %u32_0 %u32_1 %u32_2
115 %u32vec3_123 = OpConstantComposite %u32vec3 %u32_1 %u32_2 %u32_3
116 %u32vec4_0123 = OpConstantComposite %u32vec4 %u32_0 %u32_1 %u32_2 %u32_3
117 %u32vec4_1234 = OpConstantComposite %u32vec4 %u32_1 %u32_2 %u32_3 %u32_4
118
119 %s32vec2_01 = OpConstantComposite %s32vec2 %s32_0 %s32_1
120 %s32vec2_12 = OpConstantComposite %s32vec2 %s32_1 %s32_2
121 %s32vec3_012 = OpConstantComposite %s32vec3 %s32_0 %s32_1 %s32_2
122 %s32vec3_123 = OpConstantComposite %s32vec3 %s32_1 %s32_2 %s32_3
123 %s32vec4_0123 = OpConstantComposite %s32vec4 %s32_0 %s32_1 %s32_2 %s32_3
124 %s32vec4_1234 = OpConstantComposite %s32vec4 %s32_1 %s32_2 %s32_3 %s32_4
125
126 %f32vec2_01 = OpConstantComposite %f32vec2 %f32_0 %f32_1
127 %f32vec2_12 = OpConstantComposite %f32vec2 %f32_1 %f32_2
128 %f32vec3_012 = OpConstantComposite %f32vec3 %f32_0 %f32_1 %f32_2
129 %f32vec3_123 = OpConstantComposite %f32vec3 %f32_1 %f32_2 %f32_3
130 %f32vec4_0123 = OpConstantComposite %f32vec4 %f32_0 %f32_1 %f32_2 %f32_3
131 %f32vec4_1234 = OpConstantComposite %f32vec4 %f32_1 %f32_2 %f32_3 %f32_4
132
133 %main = OpFunction %void None %func
134 %main_entry = OpLabel)";
135
136 const std::string after_body =
137 R"(
138 OpReturn
139 OpFunctionEnd)";
140
141 return capabilities + capabilities_and_extensions +
142 after_extension_before_body + body + after_body;
143 }
144
TEST_F(ValidateBitwise,ShiftAllSuccess)145 TEST_F(ValidateBitwise, ShiftAllSuccess) {
146 const std::string body = R"(
147 %val1 = OpShiftRightLogical %u64 %u64_1 %s32_2
148 %val2 = OpShiftRightArithmetic %s32vec2 %s32vec2_12 %s32vec2_12
149 %val3 = OpShiftLeftLogical %u32vec2 %s32vec2_12 %u32vec2_12
150 )";
151
152 CompileSuccessfully(GenerateShaderCode(body).c_str());
153 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
154 }
155
TEST_F(ValidateBitwise,OpShiftRightLogicalWrongResultType)156 TEST_F(ValidateBitwise, OpShiftRightLogicalWrongResultType) {
157 const std::string body = R"(
158 %val1 = OpShiftRightLogical %bool %u64_1 %s32_2
159 )";
160
161 CompileSuccessfully(GenerateShaderCode(body).c_str());
162 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
163 EXPECT_THAT(getDiagnosticString(),
164 HasSubstr("Expected int scalar or vector type as Result Type: "
165 "ShiftRightLogical"));
166 }
167
TEST_F(ValidateBitwise,OpShiftRightLogicalBaseNotInt)168 TEST_F(ValidateBitwise, OpShiftRightLogicalBaseNotInt) {
169 const std::string body = R"(
170 %val1 = OpShiftRightLogical %u32 %f32_1 %s32_2
171 )";
172
173 CompileSuccessfully(GenerateShaderCode(body).c_str());
174 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
175 EXPECT_THAT(
176 getDiagnosticString(),
177 HasSubstr("Expected Base to be int scalar or vector: ShiftRightLogical"));
178 }
179
TEST_F(ValidateBitwise,OpShiftRightLogicalBaseWrongDimension)180 TEST_F(ValidateBitwise, OpShiftRightLogicalBaseWrongDimension) {
181 const std::string body = R"(
182 %val1 = OpShiftRightLogical %u32 %u32vec2_12 %s32_2
183 )";
184
185 CompileSuccessfully(GenerateShaderCode(body).c_str());
186 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
187 EXPECT_THAT(
188 getDiagnosticString(),
189 HasSubstr("Expected Base to have the same dimension as Result Type: "
190 "ShiftRightLogical"));
191 }
192
TEST_F(ValidateBitwise,OpShiftRightLogicalBaseWrongBitWidth)193 TEST_F(ValidateBitwise, OpShiftRightLogicalBaseWrongBitWidth) {
194 const std::string body = R"(
195 %val1 = OpShiftRightLogical %u64 %u32_1 %s32_2
196 )";
197
198 CompileSuccessfully(GenerateShaderCode(body).c_str());
199 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
200 EXPECT_THAT(
201 getDiagnosticString(),
202 HasSubstr("Expected Base to have the same bit width as Result Type: "
203 "ShiftRightLogical"));
204 }
205
TEST_F(ValidateBitwise,OpShiftRightLogicalShiftNotInt)206 TEST_F(ValidateBitwise, OpShiftRightLogicalShiftNotInt) {
207 const std::string body = R"(
208 %val1 = OpShiftRightLogical %u32 %u32_1 %f32_2
209 )";
210
211 CompileSuccessfully(GenerateShaderCode(body).c_str());
212 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
213 EXPECT_THAT(
214 getDiagnosticString(),
215 HasSubstr(
216 "Expected Shift to be int scalar or vector: ShiftRightLogical"));
217 }
218
TEST_F(ValidateBitwise,OpShiftRightLogicalShiftWrongDimension)219 TEST_F(ValidateBitwise, OpShiftRightLogicalShiftWrongDimension) {
220 const std::string body = R"(
221 %val1 = OpShiftRightLogical %u32 %u32_1 %s32vec2_12
222 )";
223
224 CompileSuccessfully(GenerateShaderCode(body).c_str());
225 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
226 EXPECT_THAT(
227 getDiagnosticString(),
228 HasSubstr("Expected Shift to have the same dimension as Result Type: "
229 "ShiftRightLogical"));
230 }
231
TEST_F(ValidateBitwise,LogicAllSuccess)232 TEST_F(ValidateBitwise, LogicAllSuccess) {
233 const std::string body = R"(
234 %val1 = OpBitwiseOr %u64 %u64_1 %s64_0
235 %val2 = OpBitwiseAnd %s64 %s64_1 %u64_0
236 %val3 = OpBitwiseXor %s32vec2 %s32vec2_12 %u32vec2_01
237 %val4 = OpNot %s32vec2 %u32vec2_01
238 )";
239
240 CompileSuccessfully(GenerateShaderCode(body).c_str());
241 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
242 }
243
TEST_F(ValidateBitwise,OpBitwiseAndWrongResultType)244 TEST_F(ValidateBitwise, OpBitwiseAndWrongResultType) {
245 const std::string body = R"(
246 %val1 = OpBitwiseAnd %bool %u64_1 %s32_2
247 )";
248
249 CompileSuccessfully(GenerateShaderCode(body).c_str());
250 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
251 EXPECT_THAT(
252 getDiagnosticString(),
253 HasSubstr(
254 "Expected int scalar or vector type as Result Type: BitwiseAnd"));
255 }
256
TEST_F(ValidateBitwise,OpBitwiseAndLeftNotInt)257 TEST_F(ValidateBitwise, OpBitwiseAndLeftNotInt) {
258 const std::string body = R"(
259 %val1 = OpBitwiseAnd %u32 %f32_1 %s32_2
260 )";
261
262 CompileSuccessfully(GenerateShaderCode(body).c_str());
263 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
264 EXPECT_THAT(getDiagnosticString(),
265 HasSubstr("Expected int scalar or vector as operand: BitwiseAnd "
266 "operand index 2"));
267 }
268
TEST_F(ValidateBitwise,OpBitwiseAndRightNotInt)269 TEST_F(ValidateBitwise, OpBitwiseAndRightNotInt) {
270 const std::string body = R"(
271 %val1 = OpBitwiseAnd %u32 %u32_1 %f32_2
272 )";
273
274 CompileSuccessfully(GenerateShaderCode(body).c_str());
275 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
276 EXPECT_THAT(getDiagnosticString(),
277 HasSubstr("Expected int scalar or vector as operand: BitwiseAnd "
278 "operand index 3"));
279 }
280
TEST_F(ValidateBitwise,OpBitwiseAndLeftWrongDimension)281 TEST_F(ValidateBitwise, OpBitwiseAndLeftWrongDimension) {
282 const std::string body = R"(
283 %val1 = OpBitwiseAnd %u32 %u32vec2_12 %s32_2
284 )";
285
286 CompileSuccessfully(GenerateShaderCode(body).c_str());
287 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
288 EXPECT_THAT(
289 getDiagnosticString(),
290 HasSubstr("Expected operands to have the same dimension as Result Type: "
291 "BitwiseAnd operand index 2"));
292 }
293
TEST_F(ValidateBitwise,OpBitwiseAndRightWrongDimension)294 TEST_F(ValidateBitwise, OpBitwiseAndRightWrongDimension) {
295 const std::string body = R"(
296 %val1 = OpBitwiseAnd %u32 %s32_2 %u32vec2_12
297 )";
298
299 CompileSuccessfully(GenerateShaderCode(body).c_str());
300 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
301 EXPECT_THAT(
302 getDiagnosticString(),
303 HasSubstr("Expected operands to have the same dimension as Result Type: "
304 "BitwiseAnd operand index 3"));
305 }
306
TEST_F(ValidateBitwise,OpBitwiseAndLeftWrongBitWidth)307 TEST_F(ValidateBitwise, OpBitwiseAndLeftWrongBitWidth) {
308 const std::string body = R"(
309 %val1 = OpBitwiseAnd %u64 %u32_1 %s64_2
310 )";
311
312 CompileSuccessfully(GenerateShaderCode(body).c_str());
313 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
314 EXPECT_THAT(
315 getDiagnosticString(),
316 HasSubstr("Expected operands to have the same bit width as Result Type: "
317 "BitwiseAnd operand index 2"));
318 }
319
TEST_F(ValidateBitwise,OpBitwiseAndRightWrongBitWidth)320 TEST_F(ValidateBitwise, OpBitwiseAndRightWrongBitWidth) {
321 const std::string body = R"(
322 %val1 = OpBitwiseAnd %u64 %u64_1 %s32_2
323 )";
324
325 CompileSuccessfully(GenerateShaderCode(body).c_str());
326 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
327 EXPECT_THAT(
328 getDiagnosticString(),
329 HasSubstr("Expected operands to have the same bit width as Result Type: "
330 "BitwiseAnd operand index 3"));
331 }
332
TEST_F(ValidateBitwise,OpBitFieldInsertSuccess)333 TEST_F(ValidateBitwise, OpBitFieldInsertSuccess) {
334 const std::string body = R"(
335 %val1 = OpBitFieldInsert %u64 %u64_1 %u64_2 %s32_1 %s32_2
336 %val2 = OpBitFieldInsert %s32vec2 %s32vec2_12 %s32vec2_12 %s32_1 %u32_2
337 )";
338
339 CompileSuccessfully(GenerateShaderCode(body).c_str());
340 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
341 }
342
TEST_F(ValidateBitwise,OpBitFieldInsertVulkanSuccess)343 TEST_F(ValidateBitwise, OpBitFieldInsertVulkanSuccess) {
344 const std::string body = R"(
345 %val1 = OpBitFieldInsert %u32 %u32_1 %u32_2 %s32_1 %s32_2
346 %val2 = OpBitFieldInsert %s32vec2 %s32vec2_12 %s32vec2_12 %s32_1 %u32_2
347 )";
348
349 CompileSuccessfully(GenerateShaderCode(body).c_str(), SPV_ENV_VULKAN_1_0);
350 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
351 }
352
TEST_F(ValidateBitwise,OpBitFieldInsertWrongResultType)353 TEST_F(ValidateBitwise, OpBitFieldInsertWrongResultType) {
354 const std::string body = R"(
355 %val1 = OpBitFieldInsert %bool %u64_1 %u64_2 %s32_1 %s32_2
356 )";
357
358 CompileSuccessfully(GenerateShaderCode(body).c_str());
359 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
360 EXPECT_THAT(
361 getDiagnosticString(),
362 HasSubstr(
363 "Expected Base Type to be equal to Result Type: BitFieldInsert"));
364 }
365
TEST_F(ValidateBitwise,OpBitFieldInsertWrongBaseType)366 TEST_F(ValidateBitwise, OpBitFieldInsertWrongBaseType) {
367 const std::string body = R"(
368 %val1 = OpBitFieldInsert %u64 %s64_1 %u64_2 %s32_1 %s32_2
369 )";
370
371 CompileSuccessfully(GenerateShaderCode(body).c_str());
372 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
373 EXPECT_THAT(
374 getDiagnosticString(),
375 HasSubstr(
376 "Expected Base Type to be equal to Result Type: BitFieldInsert"));
377 }
378
TEST_F(ValidateBitwise,OpBitFieldInsertWrongInsertType)379 TEST_F(ValidateBitwise, OpBitFieldInsertWrongInsertType) {
380 const std::string body = R"(
381 %val1 = OpBitFieldInsert %u64 %u64_1 %s64_2 %s32_1 %s32_2
382 )";
383
384 CompileSuccessfully(GenerateShaderCode(body).c_str());
385 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
386 EXPECT_THAT(
387 getDiagnosticString(),
388 HasSubstr(
389 "Expected Insert Type to be equal to Result Type: BitFieldInsert"));
390 }
391
TEST_F(ValidateBitwise,OpBitFieldInsertOffsetNotInt)392 TEST_F(ValidateBitwise, OpBitFieldInsertOffsetNotInt) {
393 const std::string body = R"(
394 %val1 = OpBitFieldInsert %u64 %u64_1 %u64_2 %f32_1 %s32_2
395 )";
396
397 CompileSuccessfully(GenerateShaderCode(body).c_str());
398 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
399 EXPECT_THAT(
400 getDiagnosticString(),
401 HasSubstr("Expected Offset Type to be int scalar: BitFieldInsert"));
402 }
403
TEST_F(ValidateBitwise,OpBitFieldInsertCountNotInt)404 TEST_F(ValidateBitwise, OpBitFieldInsertCountNotInt) {
405 const std::string body = R"(
406 %val1 = OpBitFieldInsert %u64 %u64_1 %u64_2 %u32_1 %f32_2
407 )";
408
409 CompileSuccessfully(GenerateShaderCode(body).c_str());
410 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
411 EXPECT_THAT(
412 getDiagnosticString(),
413 HasSubstr("Expected Count Type to be int scalar: BitFieldInsert"));
414 }
415
TEST_F(ValidateBitwise,OpBitFieldInsertNot32Vulkan)416 TEST_F(ValidateBitwise, OpBitFieldInsertNot32Vulkan) {
417 const std::string body = R"(
418 %val1 = OpBitFieldInsert %u64 %u64_1 %u64_2 %s32_1 %s32_2
419 )";
420
421 CompileSuccessfully(GenerateShaderCode(body).c_str(), SPV_ENV_VULKAN_1_0);
422 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
423 EXPECT_THAT(getDiagnosticString(),
424 AnyVUID("VUID-StandaloneSpirv-Base-04781"));
425 EXPECT_THAT(
426 getDiagnosticString(),
427 HasSubstr("Expected 32-bit int type for Base operand: BitFieldInsert"));
428 }
429
TEST_F(ValidateBitwise,OpBitFieldSExtractSuccess)430 TEST_F(ValidateBitwise, OpBitFieldSExtractSuccess) {
431 const std::string body = R"(
432 %val1 = OpBitFieldSExtract %u64 %u64_1 %s32_1 %s32_2
433 %val2 = OpBitFieldSExtract %s32vec2 %s32vec2_12 %s32_1 %u32_2
434 )";
435
436 CompileSuccessfully(GenerateShaderCode(body).c_str());
437 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
438 }
439
TEST_F(ValidateBitwise,OpBitFieldSExtractVulkanSuccess)440 TEST_F(ValidateBitwise, OpBitFieldSExtractVulkanSuccess) {
441 const std::string body = R"(
442 %val1 = OpBitFieldSExtract %u32 %u32_1 %s32_1 %s32_2
443 %val2 = OpBitFieldSExtract %s32vec2 %s32vec2_12 %s32_1 %u32_2
444 )";
445
446 CompileSuccessfully(GenerateShaderCode(body).c_str(), SPV_ENV_VULKAN_1_0);
447 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
448 }
449
TEST_F(ValidateBitwise,OpBitFieldSExtractWrongResultType)450 TEST_F(ValidateBitwise, OpBitFieldSExtractWrongResultType) {
451 const std::string body = R"(
452 %val1 = OpBitFieldSExtract %bool %u64_1 %s32_1 %s32_2
453 )";
454
455 CompileSuccessfully(GenerateShaderCode(body).c_str());
456 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
457 EXPECT_THAT(
458 getDiagnosticString(),
459 HasSubstr(
460 "Expected Base Type to be equal to Result Type: BitFieldSExtract"));
461 }
462
TEST_F(ValidateBitwise,OpBitFieldSExtractWrongBaseType)463 TEST_F(ValidateBitwise, OpBitFieldSExtractWrongBaseType) {
464 const std::string body = R"(
465 %val1 = OpBitFieldSExtract %u64 %s64_1 %s32_1 %s32_2
466 )";
467
468 CompileSuccessfully(GenerateShaderCode(body).c_str());
469 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
470 EXPECT_THAT(
471 getDiagnosticString(),
472 HasSubstr(
473 "Expected Base Type to be equal to Result Type: BitFieldSExtract"));
474 }
475
TEST_F(ValidateBitwise,OpBitFieldSExtractOffsetNotInt)476 TEST_F(ValidateBitwise, OpBitFieldSExtractOffsetNotInt) {
477 const std::string body = R"(
478 %val1 = OpBitFieldSExtract %u64 %u64_1 %f32_1 %s32_2
479 )";
480
481 CompileSuccessfully(GenerateShaderCode(body).c_str());
482 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
483 EXPECT_THAT(
484 getDiagnosticString(),
485 HasSubstr("Expected Offset Type to be int scalar: BitFieldSExtract"));
486 }
487
TEST_F(ValidateBitwise,OpBitFieldSExtractCountNotInt)488 TEST_F(ValidateBitwise, OpBitFieldSExtractCountNotInt) {
489 const std::string body = R"(
490 %val1 = OpBitFieldSExtract %u64 %u64_1 %u32_1 %f32_2
491 )";
492
493 CompileSuccessfully(GenerateShaderCode(body).c_str());
494 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
495 EXPECT_THAT(
496 getDiagnosticString(),
497 HasSubstr("Expected Count Type to be int scalar: BitFieldSExtract"));
498 }
499
TEST_F(ValidateBitwise,OpBitFieldSExtractNot32Vulkan)500 TEST_F(ValidateBitwise, OpBitFieldSExtractNot32Vulkan) {
501 const std::string body = R"(
502 %val1 = OpBitFieldSExtract %u64 %u64_1 %s32_1 %s32_2
503 )";
504
505 CompileSuccessfully(GenerateShaderCode(body).c_str(), SPV_ENV_VULKAN_1_0);
506 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
507 EXPECT_THAT(getDiagnosticString(),
508 AnyVUID("VUID-StandaloneSpirv-Base-04781"));
509 EXPECT_THAT(
510 getDiagnosticString(),
511 HasSubstr("Expected 32-bit int type for Base operand: BitFieldSExtract"));
512 }
513
TEST_F(ValidateBitwise,OpBitReverseSuccess)514 TEST_F(ValidateBitwise, OpBitReverseSuccess) {
515 const std::string body = R"(
516 %val1 = OpBitReverse %u64 %u64_1
517 %val2 = OpBitReverse %s32vec2 %s32vec2_12
518 )";
519
520 CompileSuccessfully(GenerateShaderCode(body).c_str());
521 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
522 }
523
TEST_F(ValidateBitwise,OpBitReverseVulkanSuccess)524 TEST_F(ValidateBitwise, OpBitReverseVulkanSuccess) {
525 const std::string body = R"(
526 %val1 = OpBitReverse %u32 %u32_1
527 %val2 = OpBitReverse %s32vec2 %s32vec2_12
528 )";
529
530 CompileSuccessfully(GenerateShaderCode(body).c_str(), SPV_ENV_VULKAN_1_0);
531 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
532 }
533
TEST_F(ValidateBitwise,OpBitReverseWrongResultType)534 TEST_F(ValidateBitwise, OpBitReverseWrongResultType) {
535 const std::string body = R"(
536 %val1 = OpBitReverse %bool %u64_1
537 )";
538
539 CompileSuccessfully(GenerateShaderCode(body).c_str());
540 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
541 EXPECT_THAT(
542 getDiagnosticString(),
543 HasSubstr("Expected Base Type to be equal to Result Type: BitReverse"));
544 }
545
TEST_F(ValidateBitwise,OpBitReverseWrongBaseType)546 TEST_F(ValidateBitwise, OpBitReverseWrongBaseType) {
547 const std::string body = R"(
548 %val1 = OpBitReverse %u64 %s64_1
549 )";
550
551 CompileSuccessfully(GenerateShaderCode(body).c_str());
552 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
553 EXPECT_THAT(
554 getDiagnosticString(),
555 HasSubstr("Expected Base Type to be equal to Result Type: BitReverse"));
556 }
557
TEST_F(ValidateBitwise,OpBitReverseNot32Vulkan)558 TEST_F(ValidateBitwise, OpBitReverseNot32Vulkan) {
559 const std::string body = R"(
560 %val1 = OpBitReverse %u64 %u64_1
561 )";
562
563 CompileSuccessfully(GenerateShaderCode(body).c_str(), SPV_ENV_VULKAN_1_0);
564 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
565 EXPECT_THAT(getDiagnosticString(),
566 AnyVUID("VUID-StandaloneSpirv-Base-04781"));
567 EXPECT_THAT(
568 getDiagnosticString(),
569 HasSubstr("Expected 32-bit int type for Base operand: BitReverse"));
570 }
571
TEST_F(ValidateBitwise,OpBitCountSuccess)572 TEST_F(ValidateBitwise, OpBitCountSuccess) {
573 const std::string body = R"(
574 %val1 = OpBitCount %s32 %u64_1
575 %val2 = OpBitCount %u32vec2 %s32vec2_12
576 %val3 = OpBitCount %s64 %s64_1
577 )";
578
579 CompileSuccessfully(GenerateShaderCode(body).c_str());
580 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
581 }
582
TEST_F(ValidateBitwise,OpBitCountVulkanSuccess)583 TEST_F(ValidateBitwise, OpBitCountVulkanSuccess) {
584 const std::string body = R"(
585 %val1 = OpBitCount %s32 %u32_1
586 %val2 = OpBitCount %u32vec2 %s32vec2_12
587 )";
588
589 CompileSuccessfully(GenerateShaderCode(body).c_str(), SPV_ENV_VULKAN_1_0);
590 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
591 }
592
TEST_F(ValidateBitwise,OpBitCountWrongResultType)593 TEST_F(ValidateBitwise, OpBitCountWrongResultType) {
594 const std::string body = R"(
595 %val1 = OpBitCount %bool %u64_1
596 )";
597
598 CompileSuccessfully(GenerateShaderCode(body).c_str());
599 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
600 EXPECT_THAT(
601 getDiagnosticString(),
602 HasSubstr("Expected int scalar or vector type as Result Type: BitCount"));
603 }
604
TEST_F(ValidateBitwise,OpBitCountBaseNotInt)605 TEST_F(ValidateBitwise, OpBitCountBaseNotInt) {
606 const std::string body = R"(
607 %val1 = OpBitCount %u32 %f64_1
608 )";
609
610 CompileSuccessfully(GenerateShaderCode(body).c_str(), SPV_ENV_VULKAN_1_0);
611 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
612 EXPECT_THAT(getDiagnosticString(),
613 AnyVUID("VUID-StandaloneSpirv-Base-04781"));
614 EXPECT_THAT(
615 getDiagnosticString(),
616 HasSubstr(
617 "Expected int scalar or vector type for Base operand: BitCount"));
618 }
619
TEST_F(ValidateBitwise,OpBitCountBaseWrongDimension)620 TEST_F(ValidateBitwise, OpBitCountBaseWrongDimension) {
621 const std::string body = R"(
622 %val1 = OpBitCount %u32 %u32vec2_12
623 )";
624
625 CompileSuccessfully(GenerateShaderCode(body).c_str());
626 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
627 EXPECT_THAT(
628 getDiagnosticString(),
629 HasSubstr("Expected Base dimension to be equal to Result Type dimension: "
630 "BitCount"));
631 }
632
TEST_F(ValidateBitwise,OpBitCountNot32Vulkan)633 TEST_F(ValidateBitwise, OpBitCountNot32Vulkan) {
634 const std::string body = R"(
635 %val1 = OpBitCount %s64 %s64_1
636 )";
637
638 CompileSuccessfully(GenerateShaderCode(body).c_str(), SPV_ENV_VULKAN_1_0);
639 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
640 EXPECT_THAT(getDiagnosticString(),
641 AnyVUID("VUID-StandaloneSpirv-Base-04781"));
642 EXPECT_THAT(getDiagnosticString(),
643 HasSubstr("Expected 32-bit int type for Base operand: BitCount"));
644 }
645
TEST_F(ValidateBitwise,OpBitCountPointer)646 TEST_F(ValidateBitwise, OpBitCountPointer) {
647 const std::string body = R"(
648 OpCapability Shader
649 OpMemoryModel Logical GLSL450
650 OpEntryPoint GLCompute %main "main"
651 OpExecutionMode %main LocalSize 1 1 1
652 %void = OpTypeVoid
653 %int = OpTypeInt 32 0
654 %ptr_int = OpTypePointer Function %int
655 %void_fn = OpTypeFunction %void
656 %main = OpFunction %void None %void_fn
657 %entry = OpLabel
658 %var = OpVariable %ptr_int Function
659 %count = OpBitCount %int %var
660 OpReturn
661 OpFunctionEnd
662 )";
663
664 CompileSuccessfully(body);
665 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
666 EXPECT_THAT(
667 getDiagnosticString(),
668 HasSubstr(
669 "Expected int scalar or vector type for Base operand: BitCount"));
670 }
671
672 } // namespace
673 } // namespace val
674 } // namespace spvtools
675