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 ValidateLogicals = spvtest::ValidateBase<bool>; 31 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 %ext_inst = OpExtInstImport "GLSL.std.450" 44 OpMemoryModel Logical GLSL450 45 OpEntryPoint Fragment %main "main" 46 OpExecutionMode %main OriginUpperLeft 47 %void = OpTypeVoid 48 %func = OpTypeFunction %void 49 %bool = OpTypeBool 50 %f32 = OpTypeFloat 32 51 %u32 = OpTypeInt 32 0 52 %s32 = OpTypeInt 32 1 53 %f64 = OpTypeFloat 64 54 %u64 = OpTypeInt 64 0 55 %s64 = OpTypeInt 64 1 56 %boolvec2 = OpTypeVector %bool 2 57 %s32vec2 = OpTypeVector %s32 2 58 %u32vec2 = OpTypeVector %u32 2 59 %u64vec2 = OpTypeVector %u64 2 60 %f32vec2 = OpTypeVector %f32 2 61 %f64vec2 = OpTypeVector %f64 2 62 %boolvec3 = OpTypeVector %bool 3 63 %u32vec3 = OpTypeVector %u32 3 64 %u64vec3 = OpTypeVector %u64 3 65 %s32vec3 = OpTypeVector %s32 3 66 %f32vec3 = OpTypeVector %f32 3 67 %f64vec3 = OpTypeVector %f64 3 68 %boolvec4 = OpTypeVector %bool 4 69 %u32vec4 = OpTypeVector %u32 4 70 %u64vec4 = OpTypeVector %u64 4 71 %s32vec4 = OpTypeVector %s32 4 72 %f32vec4 = OpTypeVector %f32 4 73 %f64vec4 = OpTypeVector %f64 4 74 75 %f32_0 = OpConstant %f32 0 76 %f32_1 = OpConstant %f32 1 77 %f32_2 = OpConstant %f32 2 78 %f32_3 = OpConstant %f32 3 79 %f32_4 = OpConstant %f32 4 80 81 %s32_0 = OpConstant %s32 0 82 %s32_1 = OpConstant %s32 1 83 %s32_2 = OpConstant %s32 2 84 %s32_3 = OpConstant %s32 3 85 %s32_4 = OpConstant %s32 4 86 %s32_m1 = OpConstant %s32 -1 87 88 %u32_0 = OpConstant %u32 0 89 %u32_1 = OpConstant %u32 1 90 %u32_2 = OpConstant %u32 2 91 %u32_3 = OpConstant %u32 3 92 %u32_4 = OpConstant %u32 4 93 94 %f64_0 = OpConstant %f64 0 95 %f64_1 = OpConstant %f64 1 96 %f64_2 = OpConstant %f64 2 97 %f64_3 = OpConstant %f64 3 98 %f64_4 = OpConstant %f64 4 99 100 %s64_0 = OpConstant %s64 0 101 %s64_1 = OpConstant %s64 1 102 %s64_2 = OpConstant %s64 2 103 %s64_3 = OpConstant %s64 3 104 %s64_4 = OpConstant %s64 4 105 %s64_m1 = OpConstant %s64 -1 106 107 %u64_0 = OpConstant %u64 0 108 %u64_1 = OpConstant %u64 1 109 %u64_2 = OpConstant %u64 2 110 %u64_3 = OpConstant %u64 3 111 %u64_4 = OpConstant %u64 4 112 113 %u32vec2_01 = OpConstantComposite %u32vec2 %u32_0 %u32_1 114 %u32vec2_12 = OpConstantComposite %u32vec2 %u32_1 %u32_2 115 %u32vec3_012 = OpConstantComposite %u32vec3 %u32_0 %u32_1 %u32_2 116 %u32vec3_123 = OpConstantComposite %u32vec3 %u32_1 %u32_2 %u32_3 117 %u32vec4_0123 = OpConstantComposite %u32vec4 %u32_0 %u32_1 %u32_2 %u32_3 118 %u32vec4_1234 = OpConstantComposite %u32vec4 %u32_1 %u32_2 %u32_3 %u32_4 119 120 %s32vec2_01 = OpConstantComposite %s32vec2 %s32_0 %s32_1 121 %s32vec2_12 = OpConstantComposite %s32vec2 %s32_1 %s32_2 122 %s32vec3_012 = OpConstantComposite %s32vec3 %s32_0 %s32_1 %s32_2 123 %s32vec3_123 = OpConstantComposite %s32vec3 %s32_1 %s32_2 %s32_3 124 %s32vec4_0123 = OpConstantComposite %s32vec4 %s32_0 %s32_1 %s32_2 %s32_3 125 %s32vec4_1234 = OpConstantComposite %s32vec4 %s32_1 %s32_2 %s32_3 %s32_4 126 127 %f32vec2_01 = OpConstantComposite %f32vec2 %f32_0 %f32_1 128 %f32vec2_12 = OpConstantComposite %f32vec2 %f32_1 %f32_2 129 %f32vec3_012 = OpConstantComposite %f32vec3 %f32_0 %f32_1 %f32_2 130 %f32vec3_123 = OpConstantComposite %f32vec3 %f32_1 %f32_2 %f32_3 131 %f32vec4_0123 = OpConstantComposite %f32vec4 %f32_0 %f32_1 %f32_2 %f32_3 132 %f32vec4_1234 = OpConstantComposite %f32vec4 %f32_1 %f32_2 %f32_3 %f32_4 133 134 %f64vec2_01 = OpConstantComposite %f64vec2 %f64_0 %f64_1 135 %f64vec2_12 = OpConstantComposite %f64vec2 %f64_1 %f64_2 136 %f64vec3_012 = OpConstantComposite %f64vec3 %f64_0 %f64_1 %f64_2 137 %f64vec3_123 = OpConstantComposite %f64vec3 %f64_1 %f64_2 %f64_3 138 %f64vec4_0123 = OpConstantComposite %f64vec4 %f64_0 %f64_1 %f64_2 %f64_3 139 %f64vec4_1234 = OpConstantComposite %f64vec4 %f64_1 %f64_2 %f64_3 %f64_4 140 141 %true = OpConstantTrue %bool 142 %false = OpConstantFalse %bool 143 %boolvec2_tf = OpConstantComposite %boolvec2 %true %false 144 %boolvec3_tft = OpConstantComposite %boolvec3 %true %false %true 145 %boolvec4_tftf = OpConstantComposite %boolvec4 %true %false %true %false 146 147 %f32vec4ptr = OpTypePointer Function %f32vec4 148 149 %main = OpFunction %void None %func 150 %main_entry = OpLabel)"; 151 152 const std::string after_body = 153 R"( 154 OpReturn 155 OpFunctionEnd)"; 156 157 return capabilities + capabilities_and_extensions + 158 after_extension_before_body + body + after_body; 159 } 160 161 std::string GenerateKernelCode( 162 const std::string& body, 163 const std::string& capabilities_and_extensions = "") { 164 const std::string capabilities = 165 R"( 166 OpCapability Addresses 167 OpCapability Kernel 168 OpCapability Linkage 169 OpCapability Int64 170 OpCapability Float64)"; 171 172 const std::string after_extension_before_body = 173 R"( 174 OpMemoryModel Physical32 OpenCL 175 %void = OpTypeVoid 176 %func = OpTypeFunction %void 177 %bool = OpTypeBool 178 %f32 = OpTypeFloat 32 179 %u32 = OpTypeInt 32 0 180 %f64 = OpTypeFloat 64 181 %u64 = OpTypeInt 64 0 182 %boolvec2 = OpTypeVector %bool 2 183 %u32vec2 = OpTypeVector %u32 2 184 %u64vec2 = OpTypeVector %u64 2 185 %f32vec2 = OpTypeVector %f32 2 186 %f64vec2 = OpTypeVector %f64 2 187 %boolvec3 = OpTypeVector %bool 3 188 %u32vec3 = OpTypeVector %u32 3 189 %u64vec3 = OpTypeVector %u64 3 190 %f32vec3 = OpTypeVector %f32 3 191 %f64vec3 = OpTypeVector %f64 3 192 %boolvec4 = OpTypeVector %bool 4 193 %u32vec4 = OpTypeVector %u32 4 194 %u64vec4 = OpTypeVector %u64 4 195 %f32vec4 = OpTypeVector %f32 4 196 %f64vec4 = OpTypeVector %f64 4 197 198 %f32_0 = OpConstant %f32 0 199 %f32_1 = OpConstant %f32 1 200 %f32_2 = OpConstant %f32 2 201 %f32_3 = OpConstant %f32 3 202 %f32_4 = OpConstant %f32 4 203 204 %u32_0 = OpConstant %u32 0 205 %u32_1 = OpConstant %u32 1 206 %u32_2 = OpConstant %u32 2 207 %u32_3 = OpConstant %u32 3 208 %u32_4 = OpConstant %u32 4 209 210 %f64_0 = OpConstant %f64 0 211 %f64_1 = OpConstant %f64 1 212 %f64_2 = OpConstant %f64 2 213 %f64_3 = OpConstant %f64 3 214 %f64_4 = OpConstant %f64 4 215 216 %u64_0 = OpConstant %u64 0 217 %u64_1 = OpConstant %u64 1 218 %u64_2 = OpConstant %u64 2 219 %u64_3 = OpConstant %u64 3 220 %u64_4 = OpConstant %u64 4 221 222 %u32vec2_01 = OpConstantComposite %u32vec2 %u32_0 %u32_1 223 %u32vec2_12 = OpConstantComposite %u32vec2 %u32_1 %u32_2 224 %u32vec3_012 = OpConstantComposite %u32vec3 %u32_0 %u32_1 %u32_2 225 %u32vec3_123 = OpConstantComposite %u32vec3 %u32_1 %u32_2 %u32_3 226 %u32vec4_0123 = OpConstantComposite %u32vec4 %u32_0 %u32_1 %u32_2 %u32_3 227 %u32vec4_1234 = OpConstantComposite %u32vec4 %u32_1 %u32_2 %u32_3 %u32_4 228 229 %f32vec2_01 = OpConstantComposite %f32vec2 %f32_0 %f32_1 230 %f32vec2_12 = OpConstantComposite %f32vec2 %f32_1 %f32_2 231 %f32vec3_012 = OpConstantComposite %f32vec3 %f32_0 %f32_1 %f32_2 232 %f32vec3_123 = OpConstantComposite %f32vec3 %f32_1 %f32_2 %f32_3 233 %f32vec4_0123 = OpConstantComposite %f32vec4 %f32_0 %f32_1 %f32_2 %f32_3 234 %f32vec4_1234 = OpConstantComposite %f32vec4 %f32_1 %f32_2 %f32_3 %f32_4 235 236 %f64vec2_01 = OpConstantComposite %f64vec2 %f64_0 %f64_1 237 %f64vec2_12 = OpConstantComposite %f64vec2 %f64_1 %f64_2 238 %f64vec3_012 = OpConstantComposite %f64vec3 %f64_0 %f64_1 %f64_2 239 %f64vec3_123 = OpConstantComposite %f64vec3 %f64_1 %f64_2 %f64_3 240 %f64vec4_0123 = OpConstantComposite %f64vec4 %f64_0 %f64_1 %f64_2 %f64_3 241 %f64vec4_1234 = OpConstantComposite %f64vec4 %f64_1 %f64_2 %f64_3 %f64_4 242 243 %true = OpConstantTrue %bool 244 %false = OpConstantFalse %bool 245 %boolvec2_tf = OpConstantComposite %boolvec2 %true %false 246 %boolvec3_tft = OpConstantComposite %boolvec3 %true %false %true 247 %boolvec4_tftf = OpConstantComposite %boolvec4 %true %false %true %false 248 249 %f32vec4ptr = OpTypePointer Function %f32vec4 250 251 %main = OpFunction %void None %func 252 %main_entry = OpLabel)"; 253 254 const std::string after_body = 255 R"( 256 OpReturn 257 OpFunctionEnd)"; 258 259 return capabilities + capabilities_and_extensions + 260 after_extension_before_body + body + after_body; 261 } 262 263 TEST_F(ValidateLogicals, OpAnySuccess) { 264 const std::string body = R"( 265 %val1 = OpAny %bool %boolvec2_tf 266 %val2 = OpAny %bool %boolvec3_tft 267 %val3 = OpAny %bool %boolvec4_tftf 268 )"; 269 270 CompileSuccessfully(GenerateShaderCode(body).c_str()); 271 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); 272 } 273 274 TEST_F(ValidateLogicals, OpAnyWrongTypeId) { 275 const std::string body = R"( 276 %val = OpAny %u32 %boolvec2_tf 277 )"; 278 279 CompileSuccessfully(GenerateShaderCode(body).c_str()); 280 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 281 EXPECT_THAT(getDiagnosticString(), 282 HasSubstr("Expected bool scalar type as Result Type: Any")); 283 } 284 285 TEST_F(ValidateLogicals, OpAnyWrongOperand) { 286 const std::string body = R"( 287 %val = OpAny %bool %u32vec3_123 288 )"; 289 290 CompileSuccessfully(GenerateShaderCode(body).c_str()); 291 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 292 EXPECT_THAT(getDiagnosticString(), 293 HasSubstr("Expected operand to be vector bool: Any")); 294 } 295 296 TEST_F(ValidateLogicals, OpIsNanSuccess) { 297 const std::string body = R"( 298 %val1 = OpIsNan %bool %f32_1 299 %val2 = OpIsNan %bool %f64_0 300 %val3 = OpIsNan %boolvec2 %f32vec2_12 301 %val4 = OpIsNan %boolvec3 %f32vec3_123 302 %val5 = OpIsNan %boolvec4 %f32vec4_1234 303 )"; 304 305 CompileSuccessfully(GenerateShaderCode(body).c_str()); 306 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); 307 } 308 309 TEST_F(ValidateLogicals, OpIsNanWrongTypeId) { 310 const std::string body = R"( 311 %val1 = OpIsNan %u32 %f32_1 312 )"; 313 314 CompileSuccessfully(GenerateShaderCode(body).c_str()); 315 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 316 EXPECT_THAT( 317 getDiagnosticString(), 318 HasSubstr("Expected bool scalar or vector type as Result Type: IsNan")); 319 } 320 321 TEST_F(ValidateLogicals, OpIsNanOperandNotFloat) { 322 const std::string body = R"( 323 %val1 = OpIsNan %bool %u32_1 324 )"; 325 326 CompileSuccessfully(GenerateShaderCode(body).c_str()); 327 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 328 EXPECT_THAT( 329 getDiagnosticString(), 330 HasSubstr("Expected operand to be scalar or vector float: IsNan")); 331 } 332 333 TEST_F(ValidateLogicals, OpIsNanOperandWrongSize) { 334 const std::string body = R"( 335 %val1 = OpIsNan %bool %f32vec2_12 336 )"; 337 338 CompileSuccessfully(GenerateShaderCode(body).c_str()); 339 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 340 EXPECT_THAT( 341 getDiagnosticString(), 342 HasSubstr( 343 "Expected vector sizes of Result Type and the operand to be equal: " 344 "IsNan")); 345 } 346 347 TEST_F(ValidateLogicals, OpLessOrGreaterSuccess) { 348 const std::string body = R"( 349 %val1 = OpLessOrGreater %bool %f32_0 %f32_1 350 %val2 = OpLessOrGreater %bool %f64_0 %f64_0 351 %val3 = OpLessOrGreater %boolvec2 %f32vec2_12 %f32vec2_12 352 %val4 = OpLessOrGreater %boolvec3 %f32vec3_123 %f32vec3_123 353 %val5 = OpLessOrGreater %boolvec4 %f32vec4_1234 %f32vec4_1234 354 )"; 355 356 CompileSuccessfully(GenerateKernelCode(body).c_str()); 357 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); 358 } 359 360 TEST_F(ValidateLogicals, OpLessOrGreaterWrongTypeId) { 361 const std::string body = R"( 362 %val1 = OpLessOrGreater %u32 %f32_1 %f32_1 363 )"; 364 365 CompileSuccessfully(GenerateKernelCode(body).c_str()); 366 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 367 EXPECT_THAT( 368 getDiagnosticString(), 369 HasSubstr( 370 "Expected bool scalar or vector type as Result Type: LessOrGreater")); 371 } 372 373 TEST_F(ValidateLogicals, OpLessOrGreaterLeftOperandNotFloat) { 374 const std::string body = R"( 375 %val1 = OpLessOrGreater %bool %u32_1 %f32_1 376 )"; 377 378 CompileSuccessfully(GenerateKernelCode(body).c_str()); 379 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 380 EXPECT_THAT( 381 getDiagnosticString(), 382 HasSubstr( 383 "Expected operands to be scalar or vector float: LessOrGreater")); 384 } 385 386 TEST_F(ValidateLogicals, OpLessOrGreaterLeftOperandWrongSize) { 387 const std::string body = R"( 388 %val1 = OpLessOrGreater %bool %f32vec2_12 %f32_1 389 )"; 390 391 CompileSuccessfully(GenerateKernelCode(body).c_str()); 392 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 393 EXPECT_THAT( 394 getDiagnosticString(), 395 HasSubstr( 396 "Expected vector sizes of Result Type and the operands to be equal: " 397 "LessOrGreater")); 398 } 399 400 TEST_F(ValidateLogicals, OpLessOrGreaterOperandsDifferentType) { 401 const std::string body = R"( 402 %val1 = OpLessOrGreater %bool %f32_1 %f64_1 403 )"; 404 405 CompileSuccessfully(GenerateKernelCode(body).c_str()); 406 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 407 EXPECT_THAT( 408 getDiagnosticString(), 409 HasSubstr("Expected left and right operands to have the same type: " 410 "LessOrGreater")); 411 } 412 413 TEST_F(ValidateLogicals, OpFOrdEqualSuccess) { 414 const std::string body = R"( 415 %val1 = OpFOrdEqual %bool %f32_0 %f32_1 416 %val2 = OpFOrdEqual %bool %f64_0 %f64_0 417 %val3 = OpFOrdEqual %boolvec2 %f32vec2_12 %f32vec2_12 418 %val4 = OpFOrdEqual %boolvec3 %f32vec3_123 %f32vec3_123 419 %val5 = OpFOrdEqual %boolvec4 %f32vec4_1234 %f32vec4_1234 420 )"; 421 422 CompileSuccessfully(GenerateShaderCode(body).c_str()); 423 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); 424 } 425 426 TEST_F(ValidateLogicals, OpFOrdEqualWrongTypeId) { 427 const std::string body = R"( 428 %val1 = OpFOrdEqual %u32 %f32_1 %f32_1 429 )"; 430 431 CompileSuccessfully(GenerateShaderCode(body).c_str()); 432 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 433 EXPECT_THAT( 434 getDiagnosticString(), 435 HasSubstr( 436 "Expected bool scalar or vector type as Result Type: FOrdEqual")); 437 } 438 439 TEST_F(ValidateLogicals, OpFOrdEqualLeftOperandNotFloat) { 440 const std::string body = R"( 441 %val1 = OpFOrdEqual %bool %u32_1 %f32_1 442 )"; 443 444 CompileSuccessfully(GenerateShaderCode(body).c_str()); 445 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 446 EXPECT_THAT( 447 getDiagnosticString(), 448 HasSubstr("Expected operands to be scalar or vector float: FOrdEqual")); 449 } 450 451 TEST_F(ValidateLogicals, OpFOrdEqualLeftOperandWrongSize) { 452 const std::string body = R"( 453 %val1 = OpFOrdEqual %bool %f32vec2_12 %f32_1 454 )"; 455 456 CompileSuccessfully(GenerateShaderCode(body).c_str()); 457 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 458 EXPECT_THAT( 459 getDiagnosticString(), 460 HasSubstr( 461 "Expected vector sizes of Result Type and the operands to be equal: " 462 "FOrdEqual")); 463 } 464 465 TEST_F(ValidateLogicals, OpFOrdEqualOperandsDifferentType) { 466 const std::string body = R"( 467 %val1 = OpFOrdEqual %bool %f32_1 %f64_1 468 )"; 469 470 CompileSuccessfully(GenerateShaderCode(body).c_str()); 471 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 472 EXPECT_THAT( 473 getDiagnosticString(), 474 HasSubstr("Expected left and right operands to have the same type: " 475 "FOrdEqual")); 476 } 477 478 TEST_F(ValidateLogicals, OpLogicalEqualSuccess) { 479 const std::string body = R"( 480 %val1 = OpLogicalEqual %bool %true %false 481 %val2 = OpLogicalEqual %boolvec2 %boolvec2_tf %boolvec2_tf 482 %val3 = OpLogicalEqual %boolvec3 %boolvec3_tft %boolvec3_tft 483 %val4 = OpLogicalEqual %boolvec4 %boolvec4_tftf %boolvec4_tftf 484 )"; 485 486 CompileSuccessfully(GenerateKernelCode(body).c_str()); 487 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); 488 } 489 490 TEST_F(ValidateLogicals, OpLogicalEqualWrongTypeId) { 491 const std::string body = R"( 492 %val1 = OpLogicalEqual %u32 %true %false 493 )"; 494 495 CompileSuccessfully(GenerateKernelCode(body).c_str()); 496 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 497 EXPECT_THAT( 498 getDiagnosticString(), 499 HasSubstr( 500 "Expected bool scalar or vector type as Result Type: LogicalEqual")); 501 } 502 503 TEST_F(ValidateLogicals, OpLogicalEqualWrongLeftOperand) { 504 const std::string body = R"( 505 %val1 = OpLogicalEqual %bool %boolvec2_tf %false 506 )"; 507 508 CompileSuccessfully(GenerateKernelCode(body).c_str()); 509 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 510 EXPECT_THAT( 511 getDiagnosticString(), 512 HasSubstr("Expected both operands to be of Result Type: LogicalEqual")); 513 } 514 515 TEST_F(ValidateLogicals, OpLogicalEqualWrongRightOperand) { 516 const std::string body = R"( 517 %val1 = OpLogicalEqual %boolvec2 %boolvec2_tf %false 518 )"; 519 520 CompileSuccessfully(GenerateKernelCode(body).c_str()); 521 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 522 EXPECT_THAT( 523 getDiagnosticString(), 524 HasSubstr("Expected both operands to be of Result Type: LogicalEqual")); 525 } 526 527 TEST_F(ValidateLogicals, OpLogicalNotSuccess) { 528 const std::string body = R"( 529 %val1 = OpLogicalNot %bool %true 530 %val2 = OpLogicalNot %boolvec2 %boolvec2_tf 531 %val3 = OpLogicalNot %boolvec3 %boolvec3_tft 532 %val4 = OpLogicalNot %boolvec4 %boolvec4_tftf 533 )"; 534 535 CompileSuccessfully(GenerateKernelCode(body).c_str()); 536 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); 537 } 538 539 TEST_F(ValidateLogicals, OpLogicalNotWrongTypeId) { 540 const std::string body = R"( 541 %val1 = OpLogicalNot %u32 %true 542 )"; 543 544 CompileSuccessfully(GenerateKernelCode(body).c_str()); 545 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 546 EXPECT_THAT( 547 getDiagnosticString(), 548 HasSubstr( 549 "Expected bool scalar or vector type as Result Type: LogicalNot")); 550 } 551 552 TEST_F(ValidateLogicals, OpLogicalNotWrongOperand) { 553 const std::string body = R"( 554 %val1 = OpLogicalNot %bool %boolvec2_tf 555 )"; 556 557 CompileSuccessfully(GenerateKernelCode(body).c_str()); 558 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 559 EXPECT_THAT(getDiagnosticString(), 560 HasSubstr("Expected operand to be of Result Type: LogicalNot")); 561 } 562 563 TEST_F(ValidateLogicals, OpSelectSuccess) { 564 const std::string body = R"( 565 %val1 = OpSelect %u32 %true %u32_0 %u32_1 566 %val2 = OpSelect %f32 %true %f32_0 %f32_1 567 %val3 = OpSelect %f64 %true %f64_0 %f64_1 568 %val4 = OpSelect %f32vec2 %boolvec2_tf %f32vec2_01 %f32vec2_12 569 %val5 = OpSelect %f32vec4 %boolvec4_tftf %f32vec4_0123 %f32vec4_1234 570 )"; 571 572 CompileSuccessfully(GenerateShaderCode(body).c_str()); 573 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); 574 } 575 576 TEST_F(ValidateLogicals, OpSelectWrongTypeId) { 577 const std::string body = R"( 578 %val1 = OpSelect %void %true %u32_0 %u32_1 579 )"; 580 581 CompileSuccessfully(GenerateShaderCode(body).c_str()); 582 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 583 EXPECT_THAT( 584 getDiagnosticString(), 585 HasSubstr("Expected scalar or vector type as Result Type: Select")); 586 } 587 588 TEST_F(ValidateLogicals, OpSelectPointerNoCapability) { 589 const std::string body = R"( 590 %x = OpVariable %f32vec4ptr Function 591 %y = OpVariable %f32vec4ptr Function 592 OpStore %x %f32vec4_0123 593 OpStore %y %f32vec4_1234 594 %val1 = OpSelect %f32vec4ptr %true %x %y 595 )"; 596 597 CompileSuccessfully(GenerateShaderCode(body).c_str()); 598 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 599 EXPECT_THAT( 600 getDiagnosticString(), 601 HasSubstr( 602 "Using pointers with OpSelect requires capability VariablePointers " 603 "or VariablePointersStorageBuffer")); 604 } 605 606 TEST_F(ValidateLogicals, OpSelectPointerWithCapability1) { 607 const std::string body = R"( 608 %x = OpVariable %f32vec4ptr Function 609 %y = OpVariable %f32vec4ptr Function 610 OpStore %x %f32vec4_0123 611 OpStore %y %f32vec4_1234 612 %val1 = OpSelect %f32vec4ptr %true %x %y 613 )"; 614 615 const std::string extra_cap_ext = R"( 616 OpCapability VariablePointers 617 OpExtension "SPV_KHR_variable_pointers" 618 )"; 619 620 CompileSuccessfully(GenerateShaderCode(body, extra_cap_ext).c_str()); 621 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); 622 } 623 624 TEST_F(ValidateLogicals, OpSelectPointerWithCapability2) { 625 const std::string body = R"( 626 %x = OpVariable %f32vec4ptr Function 627 %y = OpVariable %f32vec4ptr Function 628 OpStore %x %f32vec4_0123 629 OpStore %y %f32vec4_1234 630 %val1 = OpSelect %f32vec4ptr %true %x %y 631 )"; 632 633 const std::string extra_cap_ext = R"( 634 OpCapability VariablePointersStorageBuffer 635 OpExtension "SPV_KHR_variable_pointers" 636 )"; 637 638 CompileSuccessfully(GenerateShaderCode(body, extra_cap_ext).c_str()); 639 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); 640 } 641 642 TEST_F(ValidateLogicals, OpSelectWrongCondition) { 643 const std::string body = R"( 644 %val1 = OpSelect %u32 %u32_1 %u32_0 %u32_1 645 )"; 646 647 CompileSuccessfully(GenerateShaderCode(body).c_str()); 648 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 649 EXPECT_THAT( 650 getDiagnosticString(), 651 HasSubstr("Expected bool scalar or vector type as condition: Select")); 652 } 653 654 TEST_F(ValidateLogicals, OpSelectWrongConditionDimension) { 655 const std::string body = R"( 656 %val1 = OpSelect %u32vec2 %true %u32vec2_01 %u32vec2_12 657 )"; 658 659 CompileSuccessfully(GenerateShaderCode(body).c_str()); 660 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 661 EXPECT_THAT( 662 getDiagnosticString(), 663 HasSubstr( 664 "Expected vector sizes of Result Type and the condition to be equal: " 665 "Select")); 666 } 667 668 TEST_F(ValidateLogicals, OpSelectWrongLeftObject) { 669 const std::string body = R"( 670 %val1 = OpSelect %bool %true %u32vec2_01 %u32_1 671 )"; 672 673 CompileSuccessfully(GenerateShaderCode(body).c_str()); 674 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 675 EXPECT_THAT(getDiagnosticString(), 676 HasSubstr("Expected both objects to be of Result Type: Select")); 677 } 678 679 TEST_F(ValidateLogicals, OpSelectWrongRightObject) { 680 const std::string body = R"( 681 %val1 = OpSelect %bool %true %u32_1 %u32vec2_01 682 )"; 683 684 CompileSuccessfully(GenerateShaderCode(body).c_str()); 685 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 686 EXPECT_THAT(getDiagnosticString(), 687 HasSubstr("Expected both objects to be of Result Type: Select")); 688 } 689 690 TEST_F(ValidateLogicals, OpIEqualSuccess) { 691 const std::string body = R"( 692 %val1 = OpIEqual %bool %u32_0 %s32_1 693 %val2 = OpIEqual %bool %s64_0 %u64_0 694 %val3 = OpIEqual %boolvec2 %s32vec2_12 %u32vec2_12 695 %val4 = OpIEqual %boolvec3 %s32vec3_123 %u32vec3_123 696 %val5 = OpIEqual %boolvec4 %s32vec4_1234 %u32vec4_1234 697 )"; 698 699 CompileSuccessfully(GenerateShaderCode(body).c_str()); 700 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); 701 } 702 703 TEST_F(ValidateLogicals, OpIEqualWrongTypeId) { 704 const std::string body = R"( 705 %val1 = OpIEqual %u32 %s32_1 %s32_1 706 )"; 707 708 CompileSuccessfully(GenerateShaderCode(body).c_str()); 709 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 710 EXPECT_THAT( 711 getDiagnosticString(), 712 HasSubstr("Expected bool scalar or vector type as Result Type: IEqual")); 713 } 714 715 TEST_F(ValidateLogicals, OpIEqualLeftOperandNotInt) { 716 const std::string body = R"( 717 %val1 = OpIEqual %bool %f32_1 %s32_1 718 )"; 719 720 CompileSuccessfully(GenerateShaderCode(body).c_str()); 721 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 722 EXPECT_THAT( 723 getDiagnosticString(), 724 HasSubstr("Expected operands to be scalar or vector int: IEqual")); 725 } 726 727 TEST_F(ValidateLogicals, OpIEqualLeftOperandWrongSize) { 728 const std::string body = R"( 729 %val1 = OpIEqual %bool %s32vec2_12 %s32_1 730 )"; 731 732 CompileSuccessfully(GenerateShaderCode(body).c_str()); 733 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 734 EXPECT_THAT( 735 getDiagnosticString(), 736 HasSubstr( 737 "Expected vector sizes of Result Type and the operands to be equal: " 738 "IEqual")); 739 } 740 741 TEST_F(ValidateLogicals, OpIEqualRightOperandNotInt) { 742 const std::string body = R"( 743 %val1 = OpIEqual %bool %u32_1 %f32_1 744 )"; 745 746 CompileSuccessfully(GenerateShaderCode(body).c_str()); 747 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 748 EXPECT_THAT( 749 getDiagnosticString(), 750 HasSubstr("Expected operands to be scalar or vector int: IEqual")); 751 } 752 753 TEST_F(ValidateLogicals, OpIEqualDifferentBitWidth) { 754 const std::string body = R"( 755 %val1 = OpIEqual %bool %u32_1 %u64_1 756 )"; 757 758 CompileSuccessfully(GenerateShaderCode(body).c_str()); 759 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 760 EXPECT_THAT(getDiagnosticString(), 761 HasSubstr("Expected both operands to have the same component bit " 762 "width: IEqual")); 763 } 764 765 TEST_F(ValidateLogicals, OpUGreaterThanSuccess) { 766 const std::string body = R"( 767 %val1 = OpUGreaterThan %bool %u32_0 %u32_1 768 %val2 = OpUGreaterThan %bool %s32_0 %u32_1 769 %val3 = OpUGreaterThan %bool %u64_0 %u64_0 770 %val4 = OpUGreaterThan %bool %u64_0 %s64_0 771 %val5 = OpUGreaterThan %boolvec2 %u32vec2_12 %u32vec2_12 772 %val6 = OpUGreaterThan %boolvec3 %s32vec3_123 %u32vec3_123 773 %val7 = OpUGreaterThan %boolvec4 %u32vec4_1234 %u32vec4_1234 774 )"; 775 776 CompileSuccessfully(GenerateShaderCode(body).c_str()); 777 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); 778 } 779 780 TEST_F(ValidateLogicals, OpUGreaterThanWrongTypeId) { 781 const std::string body = R"( 782 %val1 = OpUGreaterThan %u32 %u32_1 %u32_1 783 )"; 784 785 CompileSuccessfully(GenerateShaderCode(body).c_str()); 786 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 787 EXPECT_THAT( 788 getDiagnosticString(), 789 HasSubstr( 790 "Expected bool scalar or vector type as Result Type: UGreaterThan")); 791 } 792 793 TEST_F(ValidateLogicals, OpUGreaterThanLeftOperandNotInt) { 794 const std::string body = R"( 795 %val1 = OpUGreaterThan %bool %f32_1 %u32_1 796 )"; 797 798 CompileSuccessfully(GenerateShaderCode(body).c_str()); 799 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 800 EXPECT_THAT( 801 getDiagnosticString(), 802 HasSubstr("Expected operands to be scalar or vector int: UGreaterThan")); 803 } 804 805 TEST_F(ValidateLogicals, OpUGreaterThanLeftOperandWrongSize) { 806 const std::string body = R"( 807 %val1 = OpUGreaterThan %bool %u32vec2_12 %u32_1 808 )"; 809 810 CompileSuccessfully(GenerateShaderCode(body).c_str()); 811 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 812 EXPECT_THAT( 813 getDiagnosticString(), 814 HasSubstr( 815 "Expected vector sizes of Result Type and the operands to be equal: " 816 "UGreaterThan")); 817 } 818 819 TEST_F(ValidateLogicals, OpUGreaterThanRightOperandNotInt) { 820 const std::string body = R"( 821 %val1 = OpUGreaterThan %bool %u32_1 %f32_1 822 )"; 823 824 CompileSuccessfully(GenerateShaderCode(body).c_str()); 825 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 826 EXPECT_THAT( 827 getDiagnosticString(), 828 HasSubstr("Expected operands to be scalar or vector int: UGreaterThan")); 829 } 830 831 TEST_F(ValidateLogicals, OpUGreaterThanDifferentBitWidth) { 832 const std::string body = R"( 833 %val1 = OpUGreaterThan %bool %u32_1 %u64_1 834 )"; 835 836 CompileSuccessfully(GenerateShaderCode(body).c_str()); 837 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 838 EXPECT_THAT( 839 getDiagnosticString(), 840 HasSubstr("Expected both operands to have the same component bit width: " 841 "UGreaterThan")); 842 } 843 844 TEST_F(ValidateLogicals, OpSGreaterThanSuccess) { 845 const std::string body = R"( 846 %val1 = OpSGreaterThan %bool %s32_0 %s32_1 847 %val2 = OpSGreaterThan %bool %u32_0 %s32_1 848 %val3 = OpSGreaterThan %bool %s64_0 %s64_0 849 %val4 = OpSGreaterThan %bool %s64_0 %u64_0 850 %val5 = OpSGreaterThan %boolvec2 %s32vec2_12 %s32vec2_12 851 %val6 = OpSGreaterThan %boolvec3 %s32vec3_123 %u32vec3_123 852 %val7 = OpSGreaterThan %boolvec4 %s32vec4_1234 %s32vec4_1234 853 )"; 854 855 CompileSuccessfully(GenerateShaderCode(body).c_str()); 856 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); 857 } 858 859 TEST_F(ValidateLogicals, OpSGreaterThanWrongTypeId) { 860 const std::string body = R"( 861 %val1 = OpSGreaterThan %s32 %s32_1 %s32_1 862 )"; 863 864 CompileSuccessfully(GenerateShaderCode(body).c_str()); 865 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 866 EXPECT_THAT( 867 getDiagnosticString(), 868 HasSubstr( 869 "Expected bool scalar or vector type as Result Type: SGreaterThan")); 870 } 871 872 TEST_F(ValidateLogicals, OpSGreaterThanLeftOperandNotInt) { 873 const std::string body = R"( 874 %val1 = OpSGreaterThan %bool %f32_1 %s32_1 875 )"; 876 877 CompileSuccessfully(GenerateShaderCode(body).c_str()); 878 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 879 EXPECT_THAT( 880 getDiagnosticString(), 881 HasSubstr("Expected operands to be scalar or vector int: SGreaterThan")); 882 } 883 884 TEST_F(ValidateLogicals, OpSGreaterThanLeftOperandWrongSize) { 885 const std::string body = R"( 886 %val1 = OpSGreaterThan %bool %s32vec2_12 %s32_1 887 )"; 888 889 CompileSuccessfully(GenerateShaderCode(body).c_str()); 890 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 891 EXPECT_THAT( 892 getDiagnosticString(), 893 HasSubstr( 894 "Expected vector sizes of Result Type and the operands to be equal: " 895 "SGreaterThan")); 896 } 897 898 TEST_F(ValidateLogicals, OpSGreaterThanRightOperandNotInt) { 899 const std::string body = R"( 900 %val1 = OpSGreaterThan %bool %s32_1 %f32_1 901 )"; 902 903 CompileSuccessfully(GenerateShaderCode(body).c_str()); 904 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 905 EXPECT_THAT( 906 getDiagnosticString(), 907 HasSubstr("Expected operands to be scalar or vector int: SGreaterThan")); 908 } 909 910 TEST_F(ValidateLogicals, OpSGreaterThanDifferentBitWidth) { 911 const std::string body = R"( 912 %val1 = OpSGreaterThan %bool %s32_1 %s64_1 913 )"; 914 915 CompileSuccessfully(GenerateShaderCode(body).c_str()); 916 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); 917 EXPECT_THAT(getDiagnosticString(), 918 HasSubstr("Expected both operands to have the same component bit " 919 "width: SGreaterThan")); 920 } 921 922 } // namespace 923 } // namespace val 924 } // namespace spvtools 925