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 23namespace spvtools { 24namespace val { 25namespace { 26 27using ::testing::HasSubstr; 28using ::testing::Not; 29 30using ValidateBitwise = spvtest::ValidateBase<bool>; 31 32std::string GenerateShaderCode( 33 const std::string& body, 34 const std::string& capabilities_and_extensions = "") { 35 const std::string capabilities = 36 R"( 37OpCapability Shader 38OpCapability Int64 39OpCapability Float64)"; 40 41 const std::string after_extension_before_body = 42 R"( 43OpMemoryModel Logical GLSL450 44OpEntryPoint Fragment %main "main" 45OpExecutionMode %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"( 138OpReturn 139OpFunctionEnd)"; 140 141 return capabilities + capabilities_and_extensions + 142 after_extension_before_body + body + after_body; 143} 144 145TEST_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 156TEST_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 168TEST_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 180TEST_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 193TEST_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 206TEST_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 219TEST_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 232TEST_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 244TEST_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 257TEST_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 269TEST_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 281TEST_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 294TEST_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 307TEST_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 320TEST_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 333TEST_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 343TEST_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 353TEST_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 366TEST_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 379TEST_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 392TEST_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 404TEST_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 416TEST_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 430TEST_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 440TEST_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 450TEST_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 463TEST_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 476TEST_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 488TEST_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 500TEST_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 514TEST_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 524TEST_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 534TEST_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 546TEST_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 558TEST_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 572TEST_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 583TEST_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 593TEST_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 605TEST_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 620TEST_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 633TEST_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 646TEST_F(ValidateBitwise, OpBitCountPointer) { 647 const std::string body = R"( 648OpCapability Shader 649OpMemoryModel Logical GLSL450 650OpEntryPoint GLCompute %main "main" 651OpExecutionMode %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 660OpReturn 661OpFunctionEnd 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