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,OpBitFieldInsertWrongResultType)343 TEST_F(ValidateBitwise, OpBitFieldInsertWrongResultType) {
344   const std::string body = R"(
345 %val1 = OpBitFieldInsert %bool %u64_1 %u64_2 %s32_1 %s32_2
346 )";
347 
348   CompileSuccessfully(GenerateShaderCode(body).c_str());
349   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
350   EXPECT_THAT(
351       getDiagnosticString(),
352       HasSubstr(
353           "Expected int scalar or vector type as Result Type: BitFieldInsert"));
354 }
355 
TEST_F(ValidateBitwise,OpBitFieldInsertWrongBaseType)356 TEST_F(ValidateBitwise, OpBitFieldInsertWrongBaseType) {
357   const std::string body = R"(
358 %val1 = OpBitFieldInsert %u64 %s64_1 %u64_2 %s32_1 %s32_2
359 )";
360 
361   CompileSuccessfully(GenerateShaderCode(body).c_str());
362   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
363   EXPECT_THAT(
364       getDiagnosticString(),
365       HasSubstr(
366           "Expected Base Type to be equal to Result Type: BitFieldInsert"));
367 }
368 
TEST_F(ValidateBitwise,OpBitFieldInsertWrongInsertType)369 TEST_F(ValidateBitwise, OpBitFieldInsertWrongInsertType) {
370   const std::string body = R"(
371 %val1 = OpBitFieldInsert %u64 %u64_1 %s64_2 %s32_1 %s32_2
372 )";
373 
374   CompileSuccessfully(GenerateShaderCode(body).c_str());
375   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
376   EXPECT_THAT(
377       getDiagnosticString(),
378       HasSubstr(
379           "Expected Insert Type to be equal to Result Type: BitFieldInsert"));
380 }
381 
TEST_F(ValidateBitwise,OpBitFieldInsertOffsetNotInt)382 TEST_F(ValidateBitwise, OpBitFieldInsertOffsetNotInt) {
383   const std::string body = R"(
384 %val1 = OpBitFieldInsert %u64 %u64_1 %u64_2 %f32_1 %s32_2
385 )";
386 
387   CompileSuccessfully(GenerateShaderCode(body).c_str());
388   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
389   EXPECT_THAT(
390       getDiagnosticString(),
391       HasSubstr("Expected Offset Type to be int scalar: BitFieldInsert"));
392 }
393 
TEST_F(ValidateBitwise,OpBitFieldInsertCountNotInt)394 TEST_F(ValidateBitwise, OpBitFieldInsertCountNotInt) {
395   const std::string body = R"(
396 %val1 = OpBitFieldInsert %u64 %u64_1 %u64_2 %u32_1 %f32_2
397 )";
398 
399   CompileSuccessfully(GenerateShaderCode(body).c_str());
400   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
401   EXPECT_THAT(
402       getDiagnosticString(),
403       HasSubstr("Expected Count Type to be int scalar: BitFieldInsert"));
404 }
405 
TEST_F(ValidateBitwise,OpBitFieldSExtractSuccess)406 TEST_F(ValidateBitwise, OpBitFieldSExtractSuccess) {
407   const std::string body = R"(
408 %val1 = OpBitFieldSExtract %u64 %u64_1 %s32_1 %s32_2
409 %val2 = OpBitFieldSExtract %s32vec2 %s32vec2_12 %s32_1 %u32_2
410 )";
411 
412   CompileSuccessfully(GenerateShaderCode(body).c_str());
413   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
414 }
415 
TEST_F(ValidateBitwise,OpBitFieldSExtractWrongResultType)416 TEST_F(ValidateBitwise, OpBitFieldSExtractWrongResultType) {
417   const std::string body = R"(
418 %val1 = OpBitFieldSExtract %bool %u64_1 %s32_1 %s32_2
419 )";
420 
421   CompileSuccessfully(GenerateShaderCode(body).c_str());
422   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
423   EXPECT_THAT(getDiagnosticString(),
424               HasSubstr("Expected int scalar or vector type as Result Type: "
425                         "BitFieldSExtract"));
426 }
427 
TEST_F(ValidateBitwise,OpBitFieldSExtractWrongBaseType)428 TEST_F(ValidateBitwise, OpBitFieldSExtractWrongBaseType) {
429   const std::string body = R"(
430 %val1 = OpBitFieldSExtract %u64 %s64_1 %s32_1 %s32_2
431 )";
432 
433   CompileSuccessfully(GenerateShaderCode(body).c_str());
434   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
435   EXPECT_THAT(
436       getDiagnosticString(),
437       HasSubstr(
438           "Expected Base Type to be equal to Result Type: BitFieldSExtract"));
439 }
440 
TEST_F(ValidateBitwise,OpBitFieldSExtractOffsetNotInt)441 TEST_F(ValidateBitwise, OpBitFieldSExtractOffsetNotInt) {
442   const std::string body = R"(
443 %val1 = OpBitFieldSExtract %u64 %u64_1 %f32_1 %s32_2
444 )";
445 
446   CompileSuccessfully(GenerateShaderCode(body).c_str());
447   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
448   EXPECT_THAT(
449       getDiagnosticString(),
450       HasSubstr("Expected Offset Type to be int scalar: BitFieldSExtract"));
451 }
452 
TEST_F(ValidateBitwise,OpBitFieldSExtractCountNotInt)453 TEST_F(ValidateBitwise, OpBitFieldSExtractCountNotInt) {
454   const std::string body = R"(
455 %val1 = OpBitFieldSExtract %u64 %u64_1 %u32_1 %f32_2
456 )";
457 
458   CompileSuccessfully(GenerateShaderCode(body).c_str());
459   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
460   EXPECT_THAT(
461       getDiagnosticString(),
462       HasSubstr("Expected Count Type to be int scalar: BitFieldSExtract"));
463 }
464 
TEST_F(ValidateBitwise,OpBitReverseSuccess)465 TEST_F(ValidateBitwise, OpBitReverseSuccess) {
466   const std::string body = R"(
467 %val1 = OpBitReverse %u64 %u64_1
468 %val2 = OpBitReverse %s32vec2 %s32vec2_12
469 )";
470 
471   CompileSuccessfully(GenerateShaderCode(body).c_str());
472   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
473 }
474 
TEST_F(ValidateBitwise,OpBitReverseWrongResultType)475 TEST_F(ValidateBitwise, OpBitReverseWrongResultType) {
476   const std::string body = R"(
477 %val1 = OpBitReverse %bool %u64_1
478 )";
479 
480   CompileSuccessfully(GenerateShaderCode(body).c_str());
481   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
482   EXPECT_THAT(
483       getDiagnosticString(),
484       HasSubstr(
485           "Expected int scalar or vector type as Result Type: BitReverse"));
486 }
487 
TEST_F(ValidateBitwise,OpBitReverseWrongBaseType)488 TEST_F(ValidateBitwise, OpBitReverseWrongBaseType) {
489   const std::string body = R"(
490 %val1 = OpBitReverse %u64 %s64_1
491 )";
492 
493   CompileSuccessfully(GenerateShaderCode(body).c_str());
494   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
495   EXPECT_THAT(
496       getDiagnosticString(),
497       HasSubstr("Expected Base Type to be equal to Result Type: BitReverse"));
498 }
499 
TEST_F(ValidateBitwise,OpBitCountSuccess)500 TEST_F(ValidateBitwise, OpBitCountSuccess) {
501   const std::string body = R"(
502 %val1 = OpBitCount %s32 %u64_1
503 %val2 = OpBitCount %u32vec2 %s32vec2_12
504 )";
505 
506   CompileSuccessfully(GenerateShaderCode(body).c_str());
507   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
508 }
509 
TEST_F(ValidateBitwise,OpBitCountWrongResultType)510 TEST_F(ValidateBitwise, OpBitCountWrongResultType) {
511   const std::string body = R"(
512 %val1 = OpBitCount %bool %u64_1
513 )";
514 
515   CompileSuccessfully(GenerateShaderCode(body).c_str());
516   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
517   EXPECT_THAT(
518       getDiagnosticString(),
519       HasSubstr("Expected int scalar or vector type as Result Type: BitCount"));
520 }
521 
TEST_F(ValidateBitwise,OpBitCountBaseNotInt)522 TEST_F(ValidateBitwise, OpBitCountBaseNotInt) {
523   const std::string body = R"(
524 %val1 = OpBitCount %u32 %f64_1
525 )";
526 
527   CompileSuccessfully(GenerateShaderCode(body).c_str());
528   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
529   EXPECT_THAT(
530       getDiagnosticString(),
531       HasSubstr("Expected Base Type to be int scalar or vector: BitCount"));
532 }
533 
TEST_F(ValidateBitwise,OpBitCountBaseWrongDimension)534 TEST_F(ValidateBitwise, OpBitCountBaseWrongDimension) {
535   const std::string body = R"(
536 %val1 = OpBitCount %u32 %u32vec2_12
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 dimension to be equal to Result Type dimension: "
544                 "BitCount"));
545 }
546 
547 }  // namespace
548 }  // namespace val
549 }  // namespace spvtools
550