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