• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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