1// Copyright (c) 2021 Shiyu Liu 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#include "gtest/gtest.h" 16#include "source/fuzz/fuzzer_util.h" 17#include "test/fuzz/fuzz_test_util.h" 18 19namespace spvtools { 20namespace fuzz { 21namespace { 22 23TEST(FuzzerUtilMaybeFindBlockTest, BasicTest) { 24 std::string shader = R"( 25 OpCapability Shader 26 %1 = OpExtInstImport "GLSL.std.450" 27 OpMemoryModel Logical GLSL450 28 OpEntryPoint Fragment %4 "main" 29 OpExecutionMode %4 OriginUpperLeft 30 OpSource ESSL 310 31 OpDecorate %8 RelaxedPrecision 32 %2 = OpTypeVoid 33 %3 = OpTypeFunction %2 34 %6 = OpTypeInt 32 1 35 %7 = OpTypePointer Function %6 36 %9 = OpConstant %6 1 37 %10 = OpConstant %6 2 38 %4 = OpFunction %2 None %3 39 %5 = OpLabel 40 %8 = OpVariable %7 Function 41 OpBranch %11 42 %11 = OpLabel 43 OpStore %8 %9 44 OpBranch %12 45 %12 = OpLabel 46 OpStore %8 %10 47 OpReturn 48 OpFunctionEnd 49 )"; 50 51 const auto env = SPV_ENV_UNIVERSAL_1_4; 52 const auto consumer = nullptr; 53 const std::unique_ptr<opt::IRContext> context = 54 BuildModule(env, consumer, shader, kFuzzAssembleOption); 55 spvtools::ValidatorOptions validator_options; 56 ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 57 kConsoleMessageConsumer)); 58 59 // Only blocks with id 11 and 12 can be found. 60 // Should return nullptr when id is not a label or id was not found. 61 uint32_t block_id1 = 11; 62 uint32_t block_id2 = 12; 63 uint32_t block_id3 = 13; 64 uint32_t block_id4 = 8; 65 66 opt::IRContext* ir_context = context.get(); 67 // Block with id 11 should be found. 68 ASSERT_TRUE(fuzzerutil::MaybeFindBlock(ir_context, block_id1) != nullptr); 69 // Block with id 12 should be found. 70 ASSERT_TRUE(fuzzerutil::MaybeFindBlock(ir_context, block_id2) != nullptr); 71 // Block with id 13 cannot be found. 72 ASSERT_FALSE(fuzzerutil::MaybeFindBlock(ir_context, block_id3) != nullptr); 73 // Block with id 8 exists but don't not of type OpLabel. 74 ASSERT_FALSE(fuzzerutil::MaybeFindBlock(ir_context, block_id4) != nullptr); 75} 76 77TEST(FuzzerutilTest, FuzzerUtilMaybeGetBoolConstantTest) { 78 std::string shader = R"( 79 OpCapability Shader 80 %1 = OpExtInstImport "GLSL.std.450" 81 OpMemoryModel Logical GLSL450 82 OpEntryPoint Fragment %4 "main" %36 83 OpExecutionMode %4 OriginUpperLeft 84 OpSource ESSL 310 85 OpName %4 "main" 86 OpName %8 "b1" 87 OpName %10 "b2" 88 OpName %12 "b3" 89 OpName %13 "b4" 90 OpName %16 "f1" 91 OpName %18 "f2" 92 OpName %20 "cf1" 93 OpName %22 "cf2" 94 OpName %26 "i1" 95 OpName %28 "i2" 96 OpName %30 "ci1" 97 OpName %32 "ci2" 98 OpName %36 "value" 99 OpDecorate %26 RelaxedPrecision 100 OpDecorate %28 RelaxedPrecision 101 OpDecorate %30 RelaxedPrecision 102 OpDecorate %32 RelaxedPrecision 103 OpDecorate %36 Location 0 104 %2 = OpTypeVoid 105 %3 = OpTypeFunction %2 106 %6 = OpTypeBool 107 %7 = OpTypePointer Function %6 108 %9 = OpConstantTrue %6 109 %11 = OpConstantFalse %6 110 %14 = OpTypeFloat 32 111 %15 = OpTypePointer Function %14 112 %17 = OpConstant %14 1.23000002 113 %19 = OpConstant %14 1.11000001 114 %21 = OpConstant %14 2 115 %23 = OpConstant %14 3.29999995 116 %24 = OpTypeInt 32 1 117 %25 = OpTypePointer Function %24 118 %27 = OpConstant %24 1 119 %29 = OpConstant %24 100 120 %31 = OpConstant %24 123 121 %33 = OpConstant %24 1111 122 %35 = OpTypePointer Input %14 123 %36 = OpVariable %35 Input 124 %4 = OpFunction %2 None %3 125 %5 = OpLabel 126 %8 = OpVariable %7 Function 127 %10 = OpVariable %7 Function 128 %12 = OpVariable %7 Function 129 %13 = OpVariable %7 Function 130 %16 = OpVariable %15 Function 131 %18 = OpVariable %15 Function 132 %20 = OpVariable %15 Function 133 %22 = OpVariable %15 Function 134 %26 = OpVariable %25 Function 135 %28 = OpVariable %25 Function 136 %30 = OpVariable %25 Function 137 %32 = OpVariable %25 Function 138 OpStore %8 %9 139 OpStore %10 %11 140 OpStore %12 %9 141 OpStore %13 %11 142 OpStore %16 %17 143 OpStore %18 %19 144 OpStore %20 %21 145 OpStore %22 %23 146 OpStore %26 %27 147 OpStore %28 %29 148 OpStore %30 %31 149 OpStore %32 %33 150 OpReturn 151 OpFunctionEnd 152 )"; 153 154 const auto env = SPV_ENV_UNIVERSAL_1_4; 155 const auto consumer = nullptr; 156 const std::unique_ptr<opt::IRContext> context = 157 BuildModule(env, consumer, shader, kFuzzAssembleOption); 158 spvtools::ValidatorOptions validator_options; 159 ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 160 kConsoleMessageConsumer)); 161 TransformationContext transformation_context( 162 MakeUnique<FactManager>(context.get()), validator_options); 163 164 opt::IRContext* ir_context = context.get(); 165 // A bool constant with value false exists and the id is 11. 166 ASSERT_EQ(11, fuzzerutil::MaybeGetBoolConstant( 167 ir_context, transformation_context, false, false)); 168 // A bool constant with value true exists and the id is 9. 169 ASSERT_EQ(9, fuzzerutil::MaybeGetBoolConstant( 170 ir_context, transformation_context, true, false)); 171} 172 173TEST(FuzzerutilTest, FuzzerUtilMaybeGetBoolTypeTest) { 174 std::string shader = R"( 175 OpCapability Shader 176 %1 = OpExtInstImport "GLSL.std.450" 177 OpMemoryModel Logical GLSL450 178 OpEntryPoint Fragment %4 "main" %92 %52 %53 179 OpExecutionMode %4 OriginUpperLeft 180 OpSource ESSL 310 181 OpDecorate %92 BuiltIn FragCoord 182 %2 = OpTypeVoid 183 %3 = OpTypeFunction %2 184 %6 = OpTypeInt 32 1 185 %7 = OpTypeFloat 32 186 %8 = OpTypeStruct %6 %7 187 %9 = OpTypePointer Function %8 188 %10 = OpTypeFunction %6 %9 189 %14 = OpConstant %6 0 190 %15 = OpTypePointer Function %6 191 %51 = OpTypePointer Private %6 192 %21 = OpConstant %6 2 193 %23 = OpConstant %6 1 194 %24 = OpConstant %7 1 195 %25 = OpTypePointer Function %7 196 %50 = OpTypePointer Private %7 197 %34 = OpTypeBool 198 %35 = OpConstantFalse %34 199 %52 = OpVariable %50 Private 200 %53 = OpVariable %51 Private 201 %80 = OpConstantComposite %8 %21 %24 202 %90 = OpTypeVector %7 4 203 %91 = OpTypePointer Input %90 204 %92 = OpVariable %91 Input 205 %93 = OpConstantComposite %90 %24 %24 %24 %24 206 %4 = OpFunction %2 None %3 207 %5 = OpLabel 208 %20 = OpVariable %9 Function 209 %27 = OpVariable %9 Function 210 %22 = OpAccessChain %15 %20 %14 211 %44 = OpCopyObject %9 %20 212 %26 = OpAccessChain %25 %20 %23 213 %29 = OpFunctionCall %6 %12 %27 214 %30 = OpAccessChain %15 %20 %14 215 %45 = OpCopyObject %15 %30 216 %81 = OpCopyObject %9 %27 217 %33 = OpAccessChain %15 %20 %14 218 OpSelectionMerge %37 None 219 OpBranchConditional %35 %36 %37 220 %36 = OpLabel 221 %38 = OpAccessChain %15 %20 %14 222 %40 = OpAccessChain %15 %20 %14 223 %43 = OpAccessChain %15 %20 %14 224 %82 = OpCopyObject %9 %27 225 OpBranch %37 226 %37 = OpLabel 227 OpReturn 228 OpFunctionEnd 229 %12 = OpFunction %6 None %10 230 %11 = OpFunctionParameter %9 231 %13 = OpLabel 232 %46 = OpCopyObject %9 %11 233 %16 = OpAccessChain %15 %11 %14 234 %95 = OpCopyObject %8 %80 235 OpReturnValue %21 236 %100 = OpLabel 237 OpUnreachable 238 OpFunctionEnd 239 )"; 240 241 const auto env = SPV_ENV_UNIVERSAL_1_4; 242 const auto consumer = nullptr; 243 const std::unique_ptr<opt::IRContext> context = 244 BuildModule(env, consumer, shader, kFuzzAssembleOption); 245 spvtools::ValidatorOptions validator_options; 246 ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 247 kConsoleMessageConsumer)); 248 249 opt::IRContext* ir_context = context.get(); 250 // A bool type with result id of 34 exists. 251 ASSERT_TRUE(fuzzerutil::MaybeGetBoolType(ir_context)); 252} 253 254TEST(FuzzerutilTest, FuzzerUtilMaybeGetCompositeConstantTest) { 255 std::string shader = R"( 256 OpCapability Shader 257 %1 = OpExtInstImport "GLSL.std.450" 258 OpMemoryModel Logical GLSL450 259 OpEntryPoint Fragment %4 "main" %54 260 OpExecutionMode %4 OriginUpperLeft 261 OpSource ESSL 310 262 OpName %4 "main" 263 OpName %8 "b1" 264 OpName %10 "b2" 265 OpName %12 "b3" 266 OpName %13 "b4" 267 OpName %16 "f1" 268 OpName %18 "f2" 269 OpName %22 "zc" 270 OpName %24 "i1" 271 OpName %28 "i2" 272 OpName %30 "i3" 273 OpName %32 "i4" 274 OpName %37 "f_arr" 275 OpName %47 "i_arr" 276 OpName %54 "value" 277 OpDecorate %22 RelaxedPrecision 278 OpDecorate %24 RelaxedPrecision 279 OpDecorate %28 RelaxedPrecision 280 OpDecorate %30 RelaxedPrecision 281 OpDecorate %32 RelaxedPrecision 282 OpDecorate %47 RelaxedPrecision 283 OpDecorate %54 Location 0 284 %2 = OpTypeVoid 285 %3 = OpTypeFunction %2 286 %6 = OpTypeBool 287 %7 = OpTypePointer Function %6 288 %9 = OpConstantTrue %6 289 %11 = OpConstantFalse %6 290 %14 = OpTypeFloat 32 291 %15 = OpTypePointer Function %14 292 %17 = OpConstant %14 1.23000002 293 %19 = OpConstant %14 1.11000001 294 %20 = OpTypeInt 32 1 295 %21 = OpTypePointer Function %20 296 %23 = OpConstant %20 0 297 %25 = OpConstant %20 1 298 %26 = OpTypeInt 32 0 299 %27 = OpTypePointer Function %26 300 %29 = OpConstant %26 100 301 %31 = OpConstant %20 -1 302 %33 = OpConstant %20 -99 303 %34 = OpConstant %26 5 304 %35 = OpTypeArray %14 %34 305 %36 = OpTypePointer Function %35 306 %38 = OpConstant %14 5.5 307 %39 = OpConstant %14 4.4000001 308 %40 = OpConstant %14 3.29999995 309 %41 = OpConstant %14 2.20000005 310 %42 = OpConstant %14 1.10000002 311 %43 = OpConstantComposite %35 %38 %39 %40 %41 %42 312 %44 = OpConstant %26 3 313 %45 = OpTypeArray %20 %44 314 %46 = OpTypePointer Function %45 315 %48 = OpConstant %20 3 316 %49 = OpConstant %20 7 317 %50 = OpConstant %20 9 318 %51 = OpConstantComposite %45 %48 %49 %50 319 %53 = OpTypePointer Input %14 320 %54 = OpVariable %53 Input 321 %4 = OpFunction %2 None %3 322 %5 = OpLabel 323 %8 = OpVariable %7 Function 324 %10 = OpVariable %7 Function 325 %12 = OpVariable %7 Function 326 %13 = OpVariable %7 Function 327 %16 = OpVariable %15 Function 328 %18 = OpVariable %15 Function 329 %22 = OpVariable %21 Function 330 %24 = OpVariable %21 Function 331 %28 = OpVariable %27 Function 332 %30 = OpVariable %21 Function 333 %32 = OpVariable %21 Function 334 %37 = OpVariable %36 Function 335 %47 = OpVariable %46 Function 336 OpStore %8 %9 337 OpStore %10 %11 338 OpStore %12 %9 339 OpStore %13 %11 340 OpStore %16 %17 341 OpStore %18 %19 342 OpStore %22 %23 343 OpStore %24 %25 344 OpStore %28 %29 345 OpStore %30 %31 346 OpStore %32 %33 347 OpStore %37 %43 348 OpStore %47 %51 349 OpReturn 350 OpFunctionEnd 351 )"; 352 353 const auto env = SPV_ENV_UNIVERSAL_1_4; 354 const auto consumer = nullptr; 355 const std::unique_ptr<opt::IRContext> context = 356 BuildModule(env, consumer, shader, kFuzzAssembleOption); 357 spvtools::ValidatorOptions validator_options; 358 ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 359 kConsoleMessageConsumer)); 360 TransformationContext transformation_context( 361 MakeUnique<FactManager>(context.get()), validator_options); 362 363 opt::IRContext* ir_context = context.get(); 364 365 // %43 = OpConstantComposite %35 %38 %39 %40 %41 %42 366 // %51 = OpConstantComposite %45 %48 %49 %50 367 // This should pass as a float array with 5 elements exist and its id is 43. 368 ASSERT_EQ(43, fuzzerutil::MaybeGetCompositeConstant( 369 ir_context, transformation_context, {38, 39, 40, 41, 42}, 370 35, false)); 371 // This should pass as an int array with 3 elements exist and its id is 51. 372 ASSERT_EQ(51, 373 fuzzerutil::MaybeGetCompositeConstant( 374 ir_context, transformation_context, {48, 49, 50}, 45, false)); 375 // An int array with 2 elements does not exist. 376 ASSERT_EQ(0, fuzzerutil::MaybeGetCompositeConstant( 377 ir_context, transformation_context, {48, 49}, 45, false)); 378} 379 380TEST(FuzzerutilTest, FuzzerUtilMaybeGetFloatConstantTest) { 381 std::string shader = R"( 382 OpCapability Shader 383 %1 = OpExtInstImport "GLSL.std.450" 384 OpMemoryModel Logical GLSL450 385 OpEntryPoint Fragment %4 "main" %36 386 OpExecutionMode %4 OriginUpperLeft 387 OpSource ESSL 310 388 OpName %4 "main" 389 OpName %8 "b1" 390 OpName %10 "b2" 391 OpName %12 "b3" 392 OpName %13 "b4" 393 OpName %16 "f1" 394 OpName %18 "f2" 395 OpName %20 "cf1" 396 OpName %22 "cf2" 397 OpName %26 "i1" 398 OpName %28 "i2" 399 OpName %30 "ci1" 400 OpName %32 "ci2" 401 OpName %36 "value" 402 OpDecorate %26 RelaxedPrecision 403 OpDecorate %28 RelaxedPrecision 404 OpDecorate %30 RelaxedPrecision 405 OpDecorate %32 RelaxedPrecision 406 OpDecorate %36 Location 0 407 %2 = OpTypeVoid 408 %3 = OpTypeFunction %2 409 %6 = OpTypeBool 410 %7 = OpTypePointer Function %6 411 %9 = OpConstantTrue %6 412 %11 = OpConstantFalse %6 413 %14 = OpTypeFloat 32 414 %15 = OpTypePointer Function %14 415 %17 = OpConstant %14 1.23000002 416 %19 = OpConstant %14 1.11000001 417 %21 = OpConstant %14 2 418 %23 = OpConstant %14 3.29999995 419 %24 = OpTypeInt 32 1 420 %25 = OpTypePointer Function %24 421 %27 = OpConstant %24 1 422 %29 = OpConstant %24 100 423 %31 = OpConstant %24 123 424 %33 = OpConstant %24 1111 425 %35 = OpTypePointer Input %14 426 %36 = OpVariable %35 Input 427 %4 = OpFunction %2 None %3 428 %5 = OpLabel 429 %8 = OpVariable %7 Function 430 %10 = OpVariable %7 Function 431 %12 = OpVariable %7 Function 432 %13 = OpVariable %7 Function 433 %16 = OpVariable %15 Function 434 %18 = OpVariable %15 Function 435 %20 = OpVariable %15 Function 436 %22 = OpVariable %15 Function 437 %26 = OpVariable %25 Function 438 %28 = OpVariable %25 Function 439 %30 = OpVariable %25 Function 440 %32 = OpVariable %25 Function 441 OpStore %8 %9 442 OpStore %10 %11 443 OpStore %12 %9 444 OpStore %13 %11 445 OpStore %16 %17 446 OpStore %18 %19 447 OpStore %20 %21 448 OpStore %22 %23 449 OpStore %26 %27 450 OpStore %28 %29 451 OpStore %30 %31 452 OpStore %32 %33 453 OpReturn 454 OpFunctionEnd 455 )"; 456 457 const auto env = SPV_ENV_UNIVERSAL_1_4; 458 const auto consumer = nullptr; 459 const std::unique_ptr<opt::IRContext> context = 460 BuildModule(env, consumer, shader, kFuzzAssembleOption); 461 spvtools::ValidatorOptions validator_options; 462 ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 463 kConsoleMessageConsumer)); 464 TransformationContext transformation_context( 465 MakeUnique<FactManager>(context.get()), validator_options); 466 467 opt::IRContext* ir_context = context.get(); 468 469 uint32_t word1 = fuzzerutil::FloatToWord(2); 470 uint32_t word2 = fuzzerutil::FloatToWord(1.23f); 471 472 // A 32 bit float constant of value 2 exists and its id is 21. 473 ASSERT_EQ(21, fuzzerutil::MaybeGetFloatConstant( 474 ir_context, transformation_context, 475 std::vector<uint32_t>{word1}, 32, false)); 476 // A 32 bit float constant of value 1.23 exists and its id is 17. 477 ASSERT_EQ(17, fuzzerutil::MaybeGetFloatConstant( 478 ir_context, transformation_context, 479 std::vector<uint32_t>{word2}, 32, false)); 480} 481 482TEST(FuzzerutilTest, FuzzerUtilMaybeGetFloatTypeTest) { 483 std::string shader = R"( 484 OpCapability Shader 485 %1 = OpExtInstImport "GLSL.std.450" 486 OpMemoryModel Logical GLSL450 487 OpEntryPoint Fragment %4 "main" %92 %52 %53 488 OpExecutionMode %4 OriginUpperLeft 489 OpSource ESSL 310 490 OpDecorate %92 BuiltIn FragCoord 491 %2 = OpTypeVoid 492 %3 = OpTypeFunction %2 493 %6 = OpTypeInt 32 1 494 %7 = OpTypeFloat 32 495 %8 = OpTypeStruct %6 %7 496 %9 = OpTypePointer Function %8 497 %10 = OpTypeFunction %6 %9 498 %14 = OpConstant %6 0 499 %15 = OpTypePointer Function %6 500 %51 = OpTypePointer Private %6 501 %21 = OpConstant %6 2 502 %23 = OpConstant %6 1 503 %24 = OpConstant %7 1 504 %25 = OpTypePointer Function %7 505 %50 = OpTypePointer Private %7 506 %34 = OpTypeBool 507 %35 = OpConstantFalse %34 508 %52 = OpVariable %50 Private 509 %53 = OpVariable %51 Private 510 %80 = OpConstantComposite %8 %21 %24 511 %90 = OpTypeVector %7 4 512 %91 = OpTypePointer Input %90 513 %92 = OpVariable %91 Input 514 %93 = OpConstantComposite %90 %24 %24 %24 %24 515 %4 = OpFunction %2 None %3 516 %5 = OpLabel 517 %20 = OpVariable %9 Function 518 %27 = OpVariable %9 Function 519 %22 = OpAccessChain %15 %20 %14 520 %44 = OpCopyObject %9 %20 521 %26 = OpAccessChain %25 %20 %23 522 %29 = OpFunctionCall %6 %12 %27 523 %30 = OpAccessChain %15 %20 %14 524 %45 = OpCopyObject %15 %30 525 %81 = OpCopyObject %9 %27 526 %33 = OpAccessChain %15 %20 %14 527 OpSelectionMerge %37 None 528 OpBranchConditional %35 %36 %37 529 %36 = OpLabel 530 %38 = OpAccessChain %15 %20 %14 531 %40 = OpAccessChain %15 %20 %14 532 %43 = OpAccessChain %15 %20 %14 533 %82 = OpCopyObject %9 %27 534 OpBranch %37 535 %37 = OpLabel 536 OpReturn 537 OpFunctionEnd 538 %12 = OpFunction %6 None %10 539 %11 = OpFunctionParameter %9 540 %13 = OpLabel 541 %46 = OpCopyObject %9 %11 542 %16 = OpAccessChain %15 %11 %14 543 %95 = OpCopyObject %8 %80 544 OpReturnValue %21 545 %100 = OpLabel 546 OpUnreachable 547 OpFunctionEnd 548 )"; 549 550 const auto env = SPV_ENV_UNIVERSAL_1_4; 551 const auto consumer = nullptr; 552 const std::unique_ptr<opt::IRContext> context = 553 BuildModule(env, consumer, shader, kFuzzAssembleOption); 554 spvtools::ValidatorOptions validator_options; 555 ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 556 kConsoleMessageConsumer)); 557 558 opt::IRContext* ir_context = context.get(); 559 // A float type with width = 32 and result id of 7 exists. 560 ASSERT_EQ(7, fuzzerutil::MaybeGetFloatType(ir_context, 32)); 561 562 // A float int type with width = 32 exists, but the id should be 7. 563 ASSERT_NE(5, fuzzerutil::MaybeGetFloatType(ir_context, 32)); 564 565 // A float type with width 30 does not exist. 566 ASSERT_EQ(0, fuzzerutil::MaybeGetFloatType(ir_context, 30)); 567} 568 569TEST(FuzzerutilTest, FuzzerUtilMaybeGetIntegerConstantFromValueAndTypeTest) { 570 std::string shader = R"( 571 OpCapability Shader 572 %1 = OpExtInstImport "GLSL.std.450" 573 OpMemoryModel Logical GLSL450 574 OpEntryPoint Fragment %4 "main" %36 575 OpExecutionMode %4 OriginUpperLeft 576 OpSource ESSL 310 577 OpName %4 "main" 578 OpName %8 "b1" 579 OpName %10 "b2" 580 OpName %12 "b3" 581 OpName %13 "b4" 582 OpName %16 "f1" 583 OpName %18 "f2" 584 OpName %22 "zc" 585 OpName %24 "i1" 586 OpName %28 "i2" 587 OpName %30 "i3" 588 OpName %32 "i4" 589 OpName %36 "value" 590 OpDecorate %22 RelaxedPrecision 591 OpDecorate %24 RelaxedPrecision 592 OpDecorate %28 RelaxedPrecision 593 OpDecorate %30 RelaxedPrecision 594 OpDecorate %32 RelaxedPrecision 595 OpDecorate %36 Location 0 596 %2 = OpTypeVoid 597 %3 = OpTypeFunction %2 598 %6 = OpTypeBool 599 %7 = OpTypePointer Function %6 600 %9 = OpConstantTrue %6 601 %11 = OpConstantFalse %6 602 %14 = OpTypeFloat 32 603 %15 = OpTypePointer Function %14 604 %17 = OpConstant %14 1.23000002 605 %19 = OpConstant %14 1.11000001 606 %20 = OpTypeInt 32 1 607 %21 = OpTypePointer Function %20 608 %23 = OpConstant %20 0 609 %25 = OpConstant %20 1 610 %26 = OpTypeInt 32 0 611 %27 = OpTypePointer Function %26 612 %29 = OpConstant %26 100 613 %31 = OpConstant %20 -1 614 %33 = OpConstant %20 -99 615 %35 = OpTypePointer Input %14 616 %36 = OpVariable %35 Input 617 %4 = OpFunction %2 None %3 618 %5 = OpLabel 619 %8 = OpVariable %7 Function 620 %10 = OpVariable %7 Function 621 %12 = OpVariable %7 Function 622 %13 = OpVariable %7 Function 623 %16 = OpVariable %15 Function 624 %18 = OpVariable %15 Function 625 %22 = OpVariable %21 Function 626 %24 = OpVariable %21 Function 627 %28 = OpVariable %27 Function 628 %30 = OpVariable %21 Function 629 %32 = OpVariable %21 Function 630 OpStore %8 %9 631 OpStore %10 %11 632 OpStore %12 %9 633 OpStore %13 %11 634 OpStore %16 %17 635 OpStore %18 %19 636 OpStore %22 %23 637 OpStore %24 %25 638 OpStore %28 %29 639 OpStore %30 %31 640 OpStore %32 %33 641 OpReturn 642 OpFunctionEnd 643 )"; 644 645 const auto env = SPV_ENV_UNIVERSAL_1_4; 646 const auto consumer = nullptr; 647 const std::unique_ptr<opt::IRContext> context = 648 BuildModule(env, consumer, shader, kFuzzAssembleOption); 649 spvtools::ValidatorOptions validator_options; 650 ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 651 kConsoleMessageConsumer)); 652 653 opt::IRContext* ir_context = context.get(); 654 655 // A 32 bit signed int constant (with int type id 20) with value 1 exists and 656 // the id is 25. 657 ASSERT_EQ(25, fuzzerutil::MaybeGetIntegerConstantFromValueAndType(ir_context, 658 1, 20)); 659 // A 32 bit unsigned int constant (with int type id 0) with value 100 exists 660 // and the id is 29. 661 ASSERT_EQ(29, fuzzerutil::MaybeGetIntegerConstantFromValueAndType(ir_context, 662 100, 26)); 663 // A 32 bit unsigned int constant with value 50 does not exist. 664 ASSERT_EQ(0, fuzzerutil::MaybeGetIntegerConstantFromValueAndType(ir_context, 665 50, 26)); 666} 667 668TEST(FuzzerutilTest, FuzzerUtilMaybeGetIntegerConstantTest) { 669 std::string shader = R"( 670OpCapability Shader 671 OpCapability Shader 672 %1 = OpExtInstImport "GLSL.std.450" 673 OpMemoryModel Logical GLSL450 674 OpEntryPoint Fragment %4 "main" %36 675 OpExecutionMode %4 OriginUpperLeft 676 OpSource ESSL 310 677 OpName %4 "main" 678 OpName %8 "b1" 679 OpName %10 "b2" 680 OpName %12 "b3" 681 OpName %13 "b4" 682 OpName %16 "f1" 683 OpName %18 "f2" 684 OpName %22 "zc" 685 OpName %24 "i1" 686 OpName %28 "i2" 687 OpName %30 "i3" 688 OpName %32 "i4" 689 OpName %36 "value" 690 OpDecorate %22 RelaxedPrecision 691 OpDecorate %24 RelaxedPrecision 692 OpDecorate %28 RelaxedPrecision 693 OpDecorate %30 RelaxedPrecision 694 OpDecorate %32 RelaxedPrecision 695 OpDecorate %36 Location 0 696 %2 = OpTypeVoid 697 %3 = OpTypeFunction %2 698 %6 = OpTypeBool 699 %7 = OpTypePointer Function %6 700 %9 = OpConstantTrue %6 701 %11 = OpConstantFalse %6 702 %14 = OpTypeFloat 32 703 %15 = OpTypePointer Function %14 704 %17 = OpConstant %14 1.23000002 705 %19 = OpConstant %14 1.11000001 706 %20 = OpTypeInt 32 1 707 %21 = OpTypePointer Function %20 708 %23 = OpConstant %20 0 709 %25 = OpConstant %20 1 710 %26 = OpTypeInt 32 0 711 %27 = OpTypePointer Function %26 712 %29 = OpConstant %26 100 713 %31 = OpConstant %20 -1 714 %33 = OpConstant %20 -99 715 %35 = OpTypePointer Input %14 716 %36 = OpVariable %35 Input 717 %4 = OpFunction %2 None %3 718 %5 = OpLabel 719 %8 = OpVariable %7 Function 720 %10 = OpVariable %7 Function 721 %12 = OpVariable %7 Function 722 %13 = OpVariable %7 Function 723 %16 = OpVariable %15 Function 724 %18 = OpVariable %15 Function 725 %22 = OpVariable %21 Function 726 %24 = OpVariable %21 Function 727 %28 = OpVariable %27 Function 728 %30 = OpVariable %21 Function 729 %32 = OpVariable %21 Function 730 OpStore %8 %9 731 OpStore %10 %11 732 OpStore %12 %9 733 OpStore %13 %11 734 OpStore %16 %17 735 OpStore %18 %19 736 OpStore %22 %23 737 OpStore %24 %25 738 OpStore %28 %29 739 OpStore %30 %31 740 OpStore %32 %33 741 OpReturn 742 OpFunctionEnd 743 )"; 744 745 const auto env = SPV_ENV_UNIVERSAL_1_4; 746 const auto consumer = nullptr; 747 const std::unique_ptr<opt::IRContext> context = 748 BuildModule(env, consumer, shader, kFuzzAssembleOption); 749 spvtools::ValidatorOptions validator_options; 750 ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 751 kConsoleMessageConsumer)); 752 TransformationContext transformation_context( 753 MakeUnique<FactManager>(context.get()), validator_options); 754 755 opt::IRContext* ir_context = context.get(); 756 757 // A 32 bit unsigned int constant with value 1 exists and the id is 25. 758 ASSERT_EQ(25, fuzzerutil::MaybeGetIntegerConstant( 759 ir_context, transformation_context, 760 std::vector<uint32_t>{1}, 32, true, false)); 761 // A 32 bit unsigned int constant with value 100 exists and the id is 29. 762 ASSERT_EQ(29, fuzzerutil::MaybeGetIntegerConstant( 763 ir_context, transformation_context, 764 std::vector<uint32_t>{100}, 32, false, false)); 765 // A 32 bit signed int constant with value 99 doesn't not exist and should 766 // return 0. 767 ASSERT_EQ(0, fuzzerutil::MaybeGetIntegerConstant( 768 ir_context, transformation_context, 769 std::vector<uint32_t>{99}, 32, true, false)); 770} 771 772TEST(FuzzerutilTest, FuzzerUtilMaybeGetIntegerTypeTest) { 773 std::string shader = R"( 774 OpCapability Shader 775 %1 = OpExtInstImport "GLSL.std.450" 776 OpMemoryModel Logical GLSL450 777 OpEntryPoint Fragment %4 "main" %92 %52 %53 778 OpExecutionMode %4 OriginUpperLeft 779 OpSource ESSL 310 780 OpDecorate %92 BuiltIn FragCoord 781 %2 = OpTypeVoid 782 %3 = OpTypeFunction %2 783 %6 = OpTypeInt 32 1 784 %7 = OpTypeFloat 32 785 %8 = OpTypeStruct %6 %7 786 %9 = OpTypePointer Function %8 787 %10 = OpTypeFunction %6 %9 788 %14 = OpConstant %6 0 789 %15 = OpTypePointer Function %6 790 %51 = OpTypePointer Private %6 791 %21 = OpConstant %6 2 792 %23 = OpConstant %6 1 793 %24 = OpConstant %7 1 794 %25 = OpTypePointer Function %7 795 %50 = OpTypePointer Private %7 796 %34 = OpTypeBool 797 %35 = OpConstantFalse %34 798 %52 = OpVariable %50 Private 799 %53 = OpVariable %51 Private 800 %80 = OpConstantComposite %8 %21 %24 801 %90 = OpTypeVector %7 4 802 %91 = OpTypePointer Input %90 803 %92 = OpVariable %91 Input 804 %93 = OpConstantComposite %90 %24 %24 %24 %24 805 %4 = OpFunction %2 None %3 806 %5 = OpLabel 807 %20 = OpVariable %9 Function 808 %27 = OpVariable %9 Function 809 %22 = OpAccessChain %15 %20 %14 810 %44 = OpCopyObject %9 %20 811 %26 = OpAccessChain %25 %20 %23 812 %29 = OpFunctionCall %6 %12 %27 813 %30 = OpAccessChain %15 %20 %14 814 %45 = OpCopyObject %15 %30 815 %81 = OpCopyObject %9 %27 816 %33 = OpAccessChain %15 %20 %14 817 OpSelectionMerge %37 None 818 OpBranchConditional %35 %36 %37 819 %36 = OpLabel 820 %38 = OpAccessChain %15 %20 %14 821 %40 = OpAccessChain %15 %20 %14 822 %43 = OpAccessChain %15 %20 %14 823 %82 = OpCopyObject %9 %27 824 OpBranch %37 825 %37 = OpLabel 826 OpReturn 827 OpFunctionEnd 828 %12 = OpFunction %6 None %10 829 %11 = OpFunctionParameter %9 830 %13 = OpLabel 831 %46 = OpCopyObject %9 %11 832 %16 = OpAccessChain %15 %11 %14 833 %95 = OpCopyObject %8 %80 834 OpReturnValue %21 835 %100 = OpLabel 836 OpUnreachable 837 OpFunctionEnd 838 )"; 839 840 const auto env = SPV_ENV_UNIVERSAL_1_4; 841 const auto consumer = nullptr; 842 const std::unique_ptr<opt::IRContext> context = 843 BuildModule(env, consumer, shader, kFuzzAssembleOption); 844 spvtools::ValidatorOptions validator_options; 845 ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 846 kConsoleMessageConsumer)); 847 848 opt::IRContext* ir_context = context.get(); 849 850 // A signed int type with width = 32 and result id of 6 exists. 851 ASSERT_EQ(6, fuzzerutil::MaybeGetIntegerType(ir_context, 32, true)); 852 853 // A signed int type with width = 32 exists, but the id should be 6. 854 ASSERT_FALSE(fuzzerutil::MaybeGetIntegerType(ir_context, 32, true) == 5); 855 856 // A int type with width = 32 and result id of 6 exists, but it should be a 857 // signed int. 858 ASSERT_EQ(0, fuzzerutil::MaybeGetIntegerType(ir_context, 32, false)); 859 // A signed int type with width 30 does not exist. 860 ASSERT_EQ(0, fuzzerutil::MaybeGetIntegerType(ir_context, 30, true)); 861 // An unsigned int type with width 22 does not exist. 862 ASSERT_EQ(0, fuzzerutil::MaybeGetIntegerType(ir_context, 22, false)); 863} 864 865TEST(FuzzerutilTest, FuzzerUtilMaybeGetPointerTypeTest) { 866 std::string shader = R"( 867 OpCapability Shader 868 %1 = OpExtInstImport "GLSL.std.450" 869 OpMemoryModel Logical GLSL450 870 OpEntryPoint Fragment %4 "main" %92 %52 %53 871 OpExecutionMode %4 OriginUpperLeft 872 OpSource ESSL 310 873 OpDecorate %92 BuiltIn FragCoord 874 %2 = OpTypeVoid 875 %3 = OpTypeFunction %2 876 %6 = OpTypeInt 32 1 877 %7 = OpTypeFloat 32 878 %8 = OpTypeStruct %6 %7 879 %9 = OpTypePointer Function %8 880 %10 = OpTypeFunction %6 %9 881 %14 = OpConstant %6 0 882 %15 = OpTypePointer Function %6 883 %51 = OpTypePointer Private %6 884 %21 = OpConstant %6 2 885 %23 = OpConstant %6 1 886 %24 = OpConstant %7 1 887 %25 = OpTypePointer Function %7 888 %50 = OpTypePointer Private %7 889 %34 = OpTypeBool 890 %35 = OpConstantFalse %34 891 %52 = OpVariable %50 Private 892 %53 = OpVariable %51 Private 893 %80 = OpConstantComposite %8 %21 %24 894 %90 = OpTypeVector %7 4 895 %91 = OpTypePointer Input %90 896 %92 = OpVariable %91 Input 897 %93 = OpConstantComposite %90 %24 %24 %24 %24 898 %4 = OpFunction %2 None %3 899 %5 = OpLabel 900 %20 = OpVariable %9 Function 901 %27 = OpVariable %9 Function 902 %22 = OpAccessChain %15 %20 %14 903 %44 = OpCopyObject %9 %20 904 %26 = OpAccessChain %25 %20 %23 905 %29 = OpFunctionCall %6 %12 %27 906 %30 = OpAccessChain %15 %20 %14 907 %45 = OpCopyObject %15 %30 908 %81 = OpCopyObject %9 %27 909 %33 = OpAccessChain %15 %20 %14 910 OpSelectionMerge %37 None 911 OpBranchConditional %35 %36 %37 912 %36 = OpLabel 913 %38 = OpAccessChain %15 %20 %14 914 %40 = OpAccessChain %15 %20 %14 915 %43 = OpAccessChain %15 %20 %14 916 %82 = OpCopyObject %9 %27 917 OpBranch %37 918 %37 = OpLabel 919 OpReturn 920 OpFunctionEnd 921 %12 = OpFunction %6 None %10 922 %11 = OpFunctionParameter %9 923 %13 = OpLabel 924 %46 = OpCopyObject %9 %11 925 %16 = OpAccessChain %15 %11 %14 926 %95 = OpCopyObject %8 %80 927 OpReturnValue %21 928 %100 = OpLabel 929 OpUnreachable 930 OpFunctionEnd 931 )"; 932 933 const auto env = SPV_ENV_UNIVERSAL_1_4; 934 const auto consumer = nullptr; 935 const std::unique_ptr<opt::IRContext> context = 936 BuildModule(env, consumer, shader, kFuzzAssembleOption); 937 spvtools::ValidatorOptions validator_options; 938 ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 939 kConsoleMessageConsumer)); 940 941 opt::IRContext* ir_context = context.get(); 942 auto private_storage_class = spv::StorageClass::Private; 943 auto function_storage_class = spv::StorageClass::Function; 944 auto input_storage_class = spv::StorageClass::Input; 945 946 // A valid pointer must have the correct |pointee_type_id| and |storageClass|. 947 // A function type pointer with id = 9 and pointee type id 8 should be found. 948 ASSERT_EQ(9, fuzzerutil::MaybeGetPointerType(ir_context, 8, 949 function_storage_class)); 950 // A function type pointer with id = 15 and pointee type id 6 should be found. 951 ASSERT_EQ(15, fuzzerutil::MaybeGetPointerType(ir_context, 6, 952 function_storage_class)); 953 // A function type pointer with id = 25 and pointee type id 7 should be found. 954 ASSERT_EQ(25, fuzzerutil::MaybeGetPointerType(ir_context, 7, 955 function_storage_class)); 956 957 // A private type pointer with id=51 and pointee type id 6 should be found. 958 ASSERT_EQ(51, fuzzerutil::MaybeGetPointerType(ir_context, 6, 959 private_storage_class)); 960 // A function pointer with id=50 and pointee type id 7 should be found. 961 ASSERT_EQ(50, fuzzerutil::MaybeGetPointerType(ir_context, 7, 962 private_storage_class)); 963 964 // A input type pointer with id=91 and pointee type id 90 should be found. 965 ASSERT_EQ( 966 91, fuzzerutil::MaybeGetPointerType(ir_context, 90, input_storage_class)); 967 968 // A pointer with id=91 and pointee type 90 exists, but the type should be 969 // input. 970 ASSERT_EQ(0, fuzzerutil::MaybeGetPointerType(ir_context, 90, 971 function_storage_class)); 972 // A input type pointer with id=91 exists but the pointee id should be 90. 973 ASSERT_EQ( 974 0, fuzzerutil::MaybeGetPointerType(ir_context, 89, input_storage_class)); 975 // A input type pointer with pointee id 90 exists but result id of the pointer 976 // should be 91. 977 ASSERT_NE( 978 58, fuzzerutil::MaybeGetPointerType(ir_context, 90, input_storage_class)); 979} 980 981TEST(FuzzerutilTest, FuzzerUtilMaybeGetScalarConstantTest) { 982 std::string shader = R"( 983 OpCapability Shader 984 %1 = OpExtInstImport "GLSL.std.450" 985 OpMemoryModel Logical GLSL450 986 OpEntryPoint Fragment %4 "main" %56 987 OpExecutionMode %4 OriginUpperLeft 988 OpSource ESSL 310 989 OpName %4 "main" 990 OpName %8 "b1" 991 OpName %10 "b2" 992 OpName %12 "b3" 993 OpName %13 "b4" 994 OpName %16 "f1" 995 OpName %18 "f2" 996 OpName %22 "zc" 997 OpName %24 "i1" 998 OpName %28 "i2" 999 OpName %30 "i" 1000 OpName %32 "i3" 1001 OpName %34 "i4" 1002 OpName %39 "f_arr" 1003 OpName %49 "i_arr" 1004 OpName %56 "value" 1005 OpDecorate %22 RelaxedPrecision 1006 OpDecorate %24 RelaxedPrecision 1007 OpDecorate %28 RelaxedPrecision 1008 OpDecorate %30 RelaxedPrecision 1009 OpDecorate %32 RelaxedPrecision 1010 OpDecorate %34 RelaxedPrecision 1011 OpDecorate %49 RelaxedPrecision 1012 OpDecorate %56 Location 0 1013 %2 = OpTypeVoid 1014 %3 = OpTypeFunction %2 1015 %6 = OpTypeBool 1016 %7 = OpTypePointer Function %6 1017 %9 = OpConstantTrue %6 1018 %11 = OpConstantFalse %6 1019 %14 = OpTypeFloat 32 1020 %15 = OpTypePointer Function %14 1021 %17 = OpConstant %14 1.23000002 1022 %19 = OpConstant %14 1.11000001 1023 %20 = OpTypeInt 32 1 1024 %21 = OpTypePointer Function %20 1025 %23 = OpConstant %20 0 1026 %25 = OpConstant %20 1 1027 %26 = OpTypeInt 32 0 1028 %27 = OpTypePointer Function %26 1029 %29 = OpConstant %26 100 1030 %31 = OpConstant %26 0 1031 %33 = OpConstant %20 -1 1032 %35 = OpConstant %20 -99 1033 %36 = OpConstant %26 5 1034 %37 = OpTypeArray %14 %36 1035 %38 = OpTypePointer Function %37 1036 %40 = OpConstant %14 5.5 1037 %41 = OpConstant %14 4.4000001 1038 %42 = OpConstant %14 3.29999995 1039 %43 = OpConstant %14 2.20000005 1040 %44 = OpConstant %14 1.10000002 1041 %45 = OpConstantComposite %37 %40 %41 %42 %43 %44 1042 %46 = OpConstant %26 3 1043 %47 = OpTypeArray %20 %46 1044 %48 = OpTypePointer Function %47 1045 %50 = OpConstant %20 3 1046 %51 = OpConstant %20 7 1047 %52 = OpConstant %20 9 1048 %53 = OpConstantComposite %47 %50 %51 %52 1049 %55 = OpTypePointer Input %14 1050 %56 = OpVariable %55 Input 1051 %4 = OpFunction %2 None %3 1052 %5 = OpLabel 1053 %8 = OpVariable %7 Function 1054 %10 = OpVariable %7 Function 1055 %12 = OpVariable %7 Function 1056 %13 = OpVariable %7 Function 1057 %16 = OpVariable %15 Function 1058 %18 = OpVariable %15 Function 1059 %22 = OpVariable %21 Function 1060 %24 = OpVariable %21 Function 1061 %28 = OpVariable %27 Function 1062 %30 = OpVariable %27 Function 1063 %32 = OpVariable %21 Function 1064 %34 = OpVariable %21 Function 1065 %39 = OpVariable %38 Function 1066 %49 = OpVariable %48 Function 1067 OpStore %8 %9 1068 OpStore %10 %11 1069 OpStore %12 %9 1070 OpStore %13 %11 1071 OpStore %16 %17 1072 OpStore %18 %19 1073 OpStore %22 %23 1074 OpStore %24 %25 1075 OpStore %28 %29 1076 OpStore %30 %31 1077 OpStore %32 %33 1078 OpStore %34 %35 1079 OpStore %39 %45 1080 OpStore %49 %53 1081 OpReturn 1082 OpFunctionEnd 1083 )"; 1084 1085 const auto env = SPV_ENV_UNIVERSAL_1_4; 1086 const auto consumer = nullptr; 1087 const std::unique_ptr<opt::IRContext> context = 1088 BuildModule(env, consumer, shader, kFuzzAssembleOption); 1089 spvtools::ValidatorOptions validator_options; 1090 ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 1091 kConsoleMessageConsumer)); 1092 TransformationContext transformation_context( 1093 MakeUnique<FactManager>(context.get()), validator_options); 1094 1095 opt::IRContext* ir_context = context.get(); 1096 1097 std::vector<uint32_t> uint_words1 = fuzzerutil::IntToWords(100, 32, false); 1098 std::vector<uint32_t> uint_words2 = fuzzerutil::IntToWords(0, 32, false); 1099 std::vector<uint32_t> int_words1 = fuzzerutil::IntToWords(-99, 32, true); 1100 std::vector<uint32_t> int_words2 = fuzzerutil::IntToWords(1, 32, true); 1101 uint32_t float_word1 = fuzzerutil::FloatToWord(1.11f); 1102 uint32_t float_word2 = fuzzerutil::FloatToWord(4.4f); 1103 1104 // A unsigned int of value 100 that has a scalar type id of 26 exists and its 1105 // id is 29. 1106 ASSERT_EQ( 1107 29, fuzzerutil::MaybeGetScalarConstant(ir_context, transformation_context, 1108 uint_words1, 26, false)); 1109 // A unsigned int of value 0 that has a scalar type id of 26 exists and its id 1110 // is 29. 1111 ASSERT_EQ( 1112 31, fuzzerutil::MaybeGetScalarConstant(ir_context, transformation_context, 1113 uint_words2, 26, false)); 1114 // A signed int of value -99 that has a scalar type id of 20 exists and its id 1115 // is 35. 1116 ASSERT_EQ(35, fuzzerutil::MaybeGetScalarConstant( 1117 ir_context, transformation_context, int_words1, 20, false)); 1118 // A signed int of value 1 that has a scalar type id of 20 exists and its id 1119 // is 25. 1120 ASSERT_EQ(25, fuzzerutil::MaybeGetScalarConstant( 1121 ir_context, transformation_context, int_words2, 20, false)); 1122 // A float of value 1.11 that has a scalar type id of 14 exists and its id 1123 // is 19. 1124 ASSERT_EQ(19, fuzzerutil::MaybeGetScalarConstant( 1125 ir_context, transformation_context, 1126 std::vector<uint32_t>{float_word1}, 14, false)); 1127 // A signed int of value 1 that has a scalar type id of 20 exists and its id 1128 // is 25. 1129 ASSERT_EQ(41, fuzzerutil::MaybeGetScalarConstant( 1130 ir_context, transformation_context, 1131 std::vector<uint32_t>{float_word2}, 14, false)); 1132} 1133 1134TEST(FuzzerutilTest, FuzzerUtilMaybeGetStructTypeTest) { 1135 std::string shader = R"( 1136 OpCapability Shader 1137 %1 = OpExtInstImport "GLSL.std.450" 1138 OpMemoryModel Logical GLSL450 1139 OpEntryPoint Fragment %4 "main" %92 %52 %53 1140 OpExecutionMode %4 OriginUpperLeft 1141 OpSource ESSL 310 1142 OpDecorate %92 BuiltIn FragCoord 1143 %2 = OpTypeVoid 1144 %3 = OpTypeFunction %2 1145 %6 = OpTypeInt 32 1 1146 %7 = OpTypeFloat 32 1147 %8 = OpTypeStruct %6 %7 1148 %9 = OpTypePointer Function %8 1149 %10 = OpTypeFunction %6 %9 1150 %14 = OpConstant %6 0 1151 %15 = OpTypePointer Function %6 1152 %51 = OpTypePointer Private %6 1153 %21 = OpConstant %6 2 1154 %23 = OpConstant %6 1 1155 %24 = OpConstant %7 1 1156 %25 = OpTypePointer Function %7 1157 %50 = OpTypePointer Private %7 1158 %34 = OpTypeBool 1159 %35 = OpConstantFalse %34 1160 %52 = OpVariable %50 Private 1161 %53 = OpVariable %51 Private 1162 %80 = OpConstantComposite %8 %21 %24 1163 %90 = OpTypeVector %7 4 1164 %91 = OpTypePointer Input %90 1165 %92 = OpVariable %91 Input 1166 %93 = OpConstantComposite %90 %24 %24 %24 %24 1167 %4 = OpFunction %2 None %3 1168 %5 = OpLabel 1169 %20 = OpVariable %9 Function 1170 %27 = OpVariable %9 Function 1171 %22 = OpAccessChain %15 %20 %14 1172 %44 = OpCopyObject %9 %20 1173 %26 = OpAccessChain %25 %20 %23 1174 %29 = OpFunctionCall %6 %12 %27 1175 %30 = OpAccessChain %15 %20 %14 1176 %45 = OpCopyObject %15 %30 1177 %81 = OpCopyObject %9 %27 1178 %33 = OpAccessChain %15 %20 %14 1179 OpSelectionMerge %37 None 1180 OpBranchConditional %35 %36 %37 1181 %36 = OpLabel 1182 %38 = OpAccessChain %15 %20 %14 1183 %40 = OpAccessChain %15 %20 %14 1184 %43 = OpAccessChain %15 %20 %14 1185 %82 = OpCopyObject %9 %27 1186 OpBranch %37 1187 %37 = OpLabel 1188 OpReturn 1189 OpFunctionEnd 1190 %12 = OpFunction %6 None %10 1191 %11 = OpFunctionParameter %9 1192 %13 = OpLabel 1193 %46 = OpCopyObject %9 %11 1194 %16 = OpAccessChain %15 %11 %14 1195 %95 = OpCopyObject %8 %80 1196 OpReturnValue %21 1197 %100 = OpLabel 1198 OpUnreachable 1199 OpFunctionEnd 1200 )"; 1201 1202 const auto env = SPV_ENV_UNIVERSAL_1_4; 1203 const auto consumer = nullptr; 1204 const std::unique_ptr<opt::IRContext> context = 1205 BuildModule(env, consumer, shader, kFuzzAssembleOption); 1206 spvtools::ValidatorOptions validator_options; 1207 ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 1208 kConsoleMessageConsumer)); 1209 1210 opt::IRContext* ir_context = context.get(); 1211 1212 // 6 and 7 are all valid ids from OpTypeInt and OpTypeFloat 1213 // so the result id of 8 should be found. 1214 ASSERT_EQ(8, fuzzerutil::MaybeGetStructType(ir_context, 1215 std::vector<uint32_t>{6, 7})); 1216 1217 // |component_type_id| of 16 does not exist in the module, so such a struct 1218 // type cannot be found. 1219 ASSERT_EQ(0, fuzzerutil::MaybeGetStructType(ir_context, 1220 std::vector<uint32_t>(6, 16))); 1221 1222 // |component_type_id| of 10 is of OpTypeFunction type and thus the struct 1223 // cannot be found. 1224 ASSERT_EQ(0, fuzzerutil::MaybeGetStructType(ir_context, 1225 std::vector<uint32_t>(6, 10))); 1226} 1227 1228TEST(FuzzerutilTest, FuzzerUtilMaybeGetVectorTypeTest) { 1229 std::string shader = R"( 1230 OpCapability Shader 1231 %1 = OpExtInstImport "GLSL.std.450" 1232 OpMemoryModel Logical GLSL450 1233 OpEntryPoint Fragment %4 "main" %92 %52 %53 1234 OpExecutionMode %4 OriginUpperLeft 1235 OpSource ESSL 310 1236 OpDecorate %92 BuiltIn FragCoord 1237 %2 = OpTypeVoid 1238 %3 = OpTypeFunction %2 1239 %6 = OpTypeInt 32 1 1240 %7 = OpTypeFloat 32 1241 %8 = OpTypeStruct %6 %7 1242 %9 = OpTypePointer Function %8 1243 %10 = OpTypeFunction %6 %9 1244 %14 = OpConstant %6 0 1245 %15 = OpTypePointer Function %6 1246 %51 = OpTypePointer Private %6 1247 %21 = OpConstant %6 2 1248 %23 = OpConstant %6 1 1249 %24 = OpConstant %7 1 1250 %25 = OpTypePointer Function %7 1251 %50 = OpTypePointer Private %7 1252 %34 = OpTypeBool 1253 %35 = OpConstantFalse %34 1254 %52 = OpVariable %50 Private 1255 %53 = OpVariable %51 Private 1256 %80 = OpConstantComposite %8 %21 %24 1257 %90 = OpTypeVector %7 4 1258 %91 = OpTypePointer Input %90 1259 %92 = OpVariable %91 Input 1260 %93 = OpConstantComposite %90 %24 %24 %24 %24 1261 %4 = OpFunction %2 None %3 1262 %5 = OpLabel 1263 %20 = OpVariable %9 Function 1264 %27 = OpVariable %9 Function 1265 %22 = OpAccessChain %15 %20 %14 1266 %44 = OpCopyObject %9 %20 1267 %26 = OpAccessChain %25 %20 %23 1268 %29 = OpFunctionCall %6 %12 %27 1269 %30 = OpAccessChain %15 %20 %14 1270 %45 = OpCopyObject %15 %30 1271 %81 = OpCopyObject %9 %27 1272 %33 = OpAccessChain %15 %20 %14 1273 OpSelectionMerge %37 None 1274 OpBranchConditional %35 %36 %37 1275 %36 = OpLabel 1276 %38 = OpAccessChain %15 %20 %14 1277 %40 = OpAccessChain %15 %20 %14 1278 %43 = OpAccessChain %15 %20 %14 1279 %82 = OpCopyObject %9 %27 1280 OpBranch %37 1281 %37 = OpLabel 1282 OpReturn 1283 OpFunctionEnd 1284 %12 = OpFunction %6 None %10 1285 %11 = OpFunctionParameter %9 1286 %13 = OpLabel 1287 %46 = OpCopyObject %9 %11 1288 %16 = OpAccessChain %15 %11 %14 1289 %95 = OpCopyObject %8 %80 1290 OpReturnValue %21 1291 %100 = OpLabel 1292 OpUnreachable 1293 OpFunctionEnd 1294 )"; 1295 1296 const auto env = SPV_ENV_UNIVERSAL_1_4; 1297 const auto consumer = nullptr; 1298 const std::unique_ptr<opt::IRContext> context = 1299 BuildModule(env, consumer, shader, kFuzzAssembleOption); 1300 spvtools::ValidatorOptions validator_options; 1301 ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 1302 kConsoleMessageConsumer)); 1303 1304 opt::IRContext* ir_context = context.get(); 1305 // The vector type with |element_count| 4 and |component_type_id| 7 1306 // is present and has a result id of 90. 1307 ASSERT_EQ(90, fuzzerutil::MaybeGetVectorType(ir_context, 7, 4)); 1308 1309 // The vector type with |element_count| 3 and |component_type_id| 7 1310 // is not present in the module. 1311 ASSERT_EQ(0, fuzzerutil::MaybeGetVectorType(ir_context, 7, 3)); 1312 1313#ifndef NDEBUG 1314 // It should abort with |component_type_id| of 100 1315 // |component_type_id| must be a valid result id of an OpTypeInt, 1316 // OpTypeFloat or OpTypeBool instruction in the module. 1317 ASSERT_DEATH(fuzzerutil::MaybeGetVectorType(ir_context, 100, 4), 1318 "\\|component_type_id\\| is invalid"); 1319 1320 // It should abort with |element_count| of 5. 1321 // |element_count| must be in the range [2,4]. 1322 ASSERT_DEATH(fuzzerutil::MaybeGetVectorType(ir_context, 7, 5), 1323 "Precondition: component count must be in range \\[2, 4\\]."); 1324#endif 1325} 1326 1327TEST(FuzzerutilTest, FuzzerUtilMaybeGetVoidTypeTest) { 1328 std::string shader = R"( 1329 OpCapability Shader 1330 %1 = OpExtInstImport "GLSL.std.450" 1331 OpMemoryModel Logical GLSL450 1332 OpEntryPoint Fragment %4 "main" %92 %52 %53 1333 OpExecutionMode %4 OriginUpperLeft 1334 OpSource ESSL 310 1335 OpDecorate %92 BuiltIn FragCoord 1336 %2 = OpTypeVoid 1337 %3 = OpTypeFunction %2 1338 %6 = OpTypeInt 32 1 1339 %7 = OpTypeFloat 32 1340 %8 = OpTypeStruct %6 %7 1341 %9 = OpTypePointer Function %8 1342 %10 = OpTypeFunction %6 %9 1343 %14 = OpConstant %6 0 1344 %15 = OpTypePointer Function %6 1345 %51 = OpTypePointer Private %6 1346 %21 = OpConstant %6 2 1347 %23 = OpConstant %6 1 1348 %24 = OpConstant %7 1 1349 %25 = OpTypePointer Function %7 1350 %50 = OpTypePointer Private %7 1351 %34 = OpTypeBool 1352 %35 = OpConstantFalse %34 1353 %52 = OpVariable %50 Private 1354 %53 = OpVariable %51 Private 1355 %80 = OpConstantComposite %8 %21 %24 1356 %90 = OpTypeVector %7 4 1357 %91 = OpTypePointer Input %90 1358 %92 = OpVariable %91 Input 1359 %93 = OpConstantComposite %90 %24 %24 %24 %24 1360 %4 = OpFunction %2 None %3 1361 %5 = OpLabel 1362 %20 = OpVariable %9 Function 1363 %27 = OpVariable %9 Function 1364 %22 = OpAccessChain %15 %20 %14 1365 %44 = OpCopyObject %9 %20 1366 %26 = OpAccessChain %25 %20 %23 1367 %29 = OpFunctionCall %6 %12 %27 1368 %30 = OpAccessChain %15 %20 %14 1369 %45 = OpCopyObject %15 %30 1370 %81 = OpCopyObject %9 %27 1371 %33 = OpAccessChain %15 %20 %14 1372 OpSelectionMerge %37 None 1373 OpBranchConditional %35 %36 %37 1374 %36 = OpLabel 1375 %38 = OpAccessChain %15 %20 %14 1376 %40 = OpAccessChain %15 %20 %14 1377 %43 = OpAccessChain %15 %20 %14 1378 %82 = OpCopyObject %9 %27 1379 OpBranch %37 1380 %37 = OpLabel 1381 OpReturn 1382 OpFunctionEnd 1383 %12 = OpFunction %6 None %10 1384 %11 = OpFunctionParameter %9 1385 %13 = OpLabel 1386 %46 = OpCopyObject %9 %11 1387 %16 = OpAccessChain %15 %11 %14 1388 %95 = OpCopyObject %8 %80 1389 OpReturnValue %21 1390 %100 = OpLabel 1391 OpUnreachable 1392 OpFunctionEnd 1393 )"; 1394 1395 const auto env = SPV_ENV_UNIVERSAL_1_4; 1396 const auto consumer = nullptr; 1397 const std::unique_ptr<opt::IRContext> context = 1398 BuildModule(env, consumer, shader, kFuzzAssembleOption); 1399 spvtools::ValidatorOptions validator_options; 1400 ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 1401 kConsoleMessageConsumer)); 1402 1403 opt::IRContext* ir_context = context.get(); 1404 // A void type with a result id of 2 can be found. 1405 ASSERT_EQ(2, fuzzerutil::MaybeGetVoidType(ir_context)); 1406} 1407 1408TEST(FuzzerutilTest, FuzzerUtilMaybeGetZeroConstantTest) { 1409 std::string shader = R"( 1410 OpCapability Shader 1411 %1 = OpExtInstImport "GLSL.std.450" 1412 OpMemoryModel Logical GLSL450 1413 OpEntryPoint Fragment %4 "main" %56 1414 OpExecutionMode %4 OriginUpperLeft 1415 OpSource ESSL 310 1416 OpName %4 "main" 1417 OpName %8 "b1" 1418 OpName %10 "b2" 1419 OpName %12 "b3" 1420 OpName %13 "b4" 1421 OpName %16 "f1" 1422 OpName %18 "f2" 1423 OpName %22 "zc" 1424 OpName %24 "i1" 1425 OpName %28 "i2" 1426 OpName %30 "i" 1427 OpName %32 "i3" 1428 OpName %34 "i4" 1429 OpName %39 "f_arr" 1430 OpName %49 "i_arr" 1431 OpName %56 "value" 1432 OpDecorate %22 RelaxedPrecision 1433 OpDecorate %24 RelaxedPrecision 1434 OpDecorate %28 RelaxedPrecision 1435 OpDecorate %30 RelaxedPrecision 1436 OpDecorate %32 RelaxedPrecision 1437 OpDecorate %34 RelaxedPrecision 1438 OpDecorate %49 RelaxedPrecision 1439 OpDecorate %56 Location 0 1440 %2 = OpTypeVoid 1441 %3 = OpTypeFunction %2 1442 %6 = OpTypeBool 1443 %7 = OpTypePointer Function %6 1444 %9 = OpConstantTrue %6 1445 %11 = OpConstantFalse %6 1446 %14 = OpTypeFloat 32 1447 %15 = OpTypePointer Function %14 1448 %17 = OpConstant %14 1.23000002 1449 %19 = OpConstant %14 1.11000001 1450 %20 = OpTypeInt 32 1 1451 %21 = OpTypePointer Function %20 1452 %23 = OpConstant %20 0 1453 %25 = OpConstant %20 1 1454 %26 = OpTypeInt 32 0 1455 %27 = OpTypePointer Function %26 1456 %29 = OpConstant %26 100 1457 %31 = OpConstant %26 0 1458 %33 = OpConstant %20 -1 1459 %35 = OpConstant %20 -99 1460 %36 = OpConstant %26 5 1461 %37 = OpTypeArray %14 %36 1462 %38 = OpTypePointer Function %37 1463 %40 = OpConstant %14 5.5 1464 %41 = OpConstant %14 4.4000001 1465 %42 = OpConstant %14 3.29999995 1466 %43 = OpConstant %14 2.20000005 1467 %44 = OpConstant %14 1.10000002 1468 %45 = OpConstantComposite %37 %40 %41 %42 %43 %44 1469 %46 = OpConstant %26 3 1470 %47 = OpTypeArray %20 %46 1471 %48 = OpTypePointer Function %47 1472 %50 = OpConstant %20 3 1473 %51 = OpConstant %20 7 1474 %52 = OpConstant %20 9 1475 %53 = OpConstantComposite %47 %50 %51 %52 1476 %55 = OpTypePointer Input %14 1477 %56 = OpVariable %55 Input 1478 %4 = OpFunction %2 None %3 1479 %5 = OpLabel 1480 %8 = OpVariable %7 Function 1481 %10 = OpVariable %7 Function 1482 %12 = OpVariable %7 Function 1483 %13 = OpVariable %7 Function 1484 %16 = OpVariable %15 Function 1485 %18 = OpVariable %15 Function 1486 %22 = OpVariable %21 Function 1487 %24 = OpVariable %21 Function 1488 %28 = OpVariable %27 Function 1489 %30 = OpVariable %27 Function 1490 %32 = OpVariable %21 Function 1491 %34 = OpVariable %21 Function 1492 %39 = OpVariable %38 Function 1493 %49 = OpVariable %48 Function 1494 OpStore %8 %9 1495 OpStore %10 %11 1496 OpStore %12 %9 1497 OpStore %13 %11 1498 OpStore %16 %17 1499 OpStore %18 %19 1500 OpStore %22 %23 1501 OpStore %24 %25 1502 OpStore %28 %29 1503 OpStore %30 %31 1504 OpStore %32 %33 1505 OpStore %34 %35 1506 OpStore %39 %45 1507 OpStore %49 %53 1508 OpReturn 1509 OpFunctionEnd 1510 )"; 1511 1512 const auto env = SPV_ENV_UNIVERSAL_1_4; 1513 const auto consumer = nullptr; 1514 const std::unique_ptr<opt::IRContext> context = 1515 BuildModule(env, consumer, shader, kFuzzAssembleOption); 1516 spvtools::ValidatorOptions validator_options; 1517 ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 1518 kConsoleMessageConsumer)); 1519 TransformationContext transformation_context( 1520 MakeUnique<FactManager>(context.get()), validator_options); 1521 1522 opt::IRContext* ir_context = context.get(); 1523 1524 // The id of a boolean constant will be returned give boolean type id 6. 1525 uint32_t maybe_bool_id = fuzzerutil::MaybeGetZeroConstant( 1526 ir_context, transformation_context, 6, false); 1527 // The id of a 32 bit float constant will be returned given the float type 1528 // id 14. 1529 uint32_t maybe_float_id = fuzzerutil::MaybeGetZeroConstant( 1530 ir_context, transformation_context, 14, false); 1531 uint32_t maybe_signed_int_id = fuzzerutil::MaybeGetZeroConstant( 1532 ir_context, transformation_context, 20, false); 1533 uint32_t maybe_unsigned_int_id = fuzzerutil::MaybeGetZeroConstant( 1534 ir_context, transformation_context, 26, false); 1535 1536 // Lists of possible ids for float, signed int, unsigned int and array. 1537 std::vector<uint32_t> float_ids{17, 19}; 1538 std::vector<uint32_t> signed_int_ids{23, 25, 31, 33}; 1539 1540 ASSERT_TRUE(maybe_bool_id == 9 || maybe_bool_id == 11); 1541 ASSERT_TRUE(std::find(signed_int_ids.begin(), signed_int_ids.end(), 1542 maybe_signed_int_id) != signed_int_ids.end()); 1543 1544 // There is a unsigned int typed zero constant and its id is 31. 1545 ASSERT_EQ(31, maybe_unsigned_int_id); 1546 1547 // There is no zero float constant. 1548 ASSERT_TRUE(std::find(float_ids.begin(), float_ids.end(), maybe_float_id) == 1549 float_ids.end()); 1550} 1551 1552TEST(FuzzerutilTest, TypesAreCompatible) { 1553 const std::string shader = R"( 1554 OpCapability Shader 1555 %1 = OpExtInstImport "GLSL.std.450" 1556 OpMemoryModel Logical GLSL450 1557 OpEntryPoint Fragment %4 "main" 1558 OpExecutionMode %4 OriginUpperLeft 1559 OpSource ESSL 320 1560 %2 = OpTypeVoid 1561 %3 = OpTypeFunction %2 1562 %6 = OpTypeInt 32 1 1563 %9 = OpTypeInt 32 0 1564 %8 = OpTypeStruct %6 1565 %10 = OpTypePointer StorageBuffer %8 1566 %11 = OpVariable %10 StorageBuffer 1567 %86 = OpTypeStruct %9 1568 %87 = OpTypePointer Workgroup %86 1569 %88 = OpVariable %87 Workgroup 1570 %89 = OpTypePointer Workgroup %9 1571 %19 = OpConstant %9 0 1572 %18 = OpConstant %9 1 1573 %12 = OpConstant %6 0 1574 %13 = OpTypePointer StorageBuffer %6 1575 %15 = OpConstant %6 2 1576 %16 = OpConstant %6 7 1577 %20 = OpConstant %9 64 1578 %4 = OpFunction %2 None %3 1579 %5 = OpLabel 1580 %14 = OpAccessChain %13 %11 %12 1581 %90 = OpAccessChain %89 %88 %19 1582 %21 = OpAtomicLoad %6 %14 %15 %20 1583 %22 = OpAtomicExchange %6 %14 %15 %20 %16 1584 %23 = OpAtomicCompareExchange %6 %14 %15 %20 %12 %16 %15 1585 %24 = OpAtomicIIncrement %6 %14 %15 %20 1586 %25 = OpAtomicIDecrement %6 %14 %15 %20 1587 %26 = OpAtomicIAdd %6 %14 %15 %20 %16 1588 %27 = OpAtomicISub %6 %14 %15 %20 %16 1589 %28 = OpAtomicSMin %6 %14 %15 %20 %16 1590 %29 = OpAtomicUMin %9 %90 %15 %20 %18 1591 %30 = OpAtomicSMax %6 %14 %15 %20 %15 1592 %31 = OpAtomicUMax %9 %90 %15 %20 %18 1593 %32 = OpAtomicAnd %6 %14 %15 %20 %16 1594 %33 = OpAtomicOr %6 %14 %15 %20 %16 1595 %34 = OpAtomicXor %6 %14 %15 %20 %16 1596 OpAtomicStore %14 %15 %20 %16 1597 OpReturn 1598 OpFunctionEnd 1599 )"; 1600 1601 const auto env = SPV_ENV_UNIVERSAL_1_3; 1602 const auto consumer = nullptr; 1603 const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); 1604 spvtools::ValidatorOptions validator_options; 1605 ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options, 1606 kConsoleMessageConsumer)); 1607 1608 const uint32_t int_type = 6; // The id of OpTypeInt 32 1 1609 const uint32_t uint_type = 9; // The id of OpTypeInt 32 0 1610 1611 // OpAtomicLoad 1612#ifndef NDEBUG 1613 ASSERT_DEATH( 1614 fuzzerutil::TypesAreCompatible(context.get(), spv::Op::OpAtomicLoad, 0, 1615 int_type, uint_type), 1616 "Signedness check should not occur on a pointer operand."); 1617#endif 1618 ASSERT_TRUE(fuzzerutil::TypesAreCompatible( 1619 context.get(), spv::Op::OpAtomicLoad, 1, int_type, uint_type)); 1620 ASSERT_TRUE(fuzzerutil::TypesAreCompatible( 1621 context.get(), spv::Op::OpAtomicLoad, 2, int_type, uint_type)); 1622 1623 // OpAtomicExchange 1624#ifndef NDEBUG 1625 ASSERT_DEATH( 1626 fuzzerutil::TypesAreCompatible(context.get(), spv::Op::OpAtomicExchange, 1627 0, int_type, uint_type), 1628 "Signedness check should not occur on a pointer operand."); 1629#endif 1630 ASSERT_TRUE(fuzzerutil::TypesAreCompatible( 1631 context.get(), spv::Op::OpAtomicExchange, 1, int_type, uint_type)); 1632 ASSERT_TRUE(fuzzerutil::TypesAreCompatible( 1633 context.get(), spv::Op::OpAtomicExchange, 2, int_type, uint_type)); 1634 ASSERT_FALSE(fuzzerutil::TypesAreCompatible( 1635 context.get(), spv::Op::OpAtomicExchange, 3, int_type, uint_type)); 1636 1637 // OpAtomicStore 1638#ifndef NDEBUG 1639 ASSERT_DEATH( 1640 fuzzerutil::TypesAreCompatible(context.get(), spv::Op::OpAtomicStore, 0, 1641 int_type, uint_type), 1642 "Signedness check should not occur on a pointer operand."); 1643#endif 1644 ASSERT_TRUE(fuzzerutil::TypesAreCompatible( 1645 context.get(), spv::Op::OpAtomicStore, 1, int_type, uint_type)); 1646 ASSERT_TRUE(fuzzerutil::TypesAreCompatible( 1647 context.get(), spv::Op::OpAtomicStore, 2, int_type, uint_type)); 1648 ASSERT_FALSE(fuzzerutil::TypesAreCompatible( 1649 context.get(), spv::Op::OpAtomicStore, 3, int_type, uint_type)); 1650 1651 // OpAtomicCompareExchange 1652#ifndef NDEBUG 1653 ASSERT_DEATH(fuzzerutil::TypesAreCompatible(context.get(), 1654 spv::Op::OpAtomicCompareExchange, 1655 0, int_type, uint_type), 1656 "Signedness check should not occur on a pointer operand."); 1657#endif 1658 ASSERT_TRUE(fuzzerutil::TypesAreCompatible( 1659 context.get(), spv::Op::OpAtomicCompareExchange, 1, int_type, uint_type)); 1660 ASSERT_TRUE(fuzzerutil::TypesAreCompatible( 1661 context.get(), spv::Op::OpAtomicCompareExchange, 2, int_type, uint_type)); 1662 ASSERT_TRUE(fuzzerutil::TypesAreCompatible( 1663 context.get(), spv::Op::OpAtomicCompareExchange, 3, int_type, uint_type)); 1664 ASSERT_FALSE(fuzzerutil::TypesAreCompatible( 1665 context.get(), spv::Op::OpAtomicCompareExchange, 4, int_type, uint_type)); 1666 1667 // OpAtomicIIncrement 1668#ifndef NDEBUG 1669 ASSERT_DEATH( 1670 fuzzerutil::TypesAreCompatible(context.get(), spv::Op::OpAtomicIIncrement, 1671 0, int_type, uint_type), 1672 "Signedness check should not occur on a pointer operand."); 1673#endif 1674 ASSERT_TRUE(fuzzerutil::TypesAreCompatible( 1675 context.get(), spv::Op::OpAtomicIIncrement, 1, int_type, uint_type)); 1676 ASSERT_TRUE(fuzzerutil::TypesAreCompatible( 1677 context.get(), spv::Op::OpAtomicIIncrement, 2, int_type, uint_type)); 1678 1679// OpAtomicIDecrement 1680#ifndef NDEBUG 1681 ASSERT_DEATH( 1682 fuzzerutil::TypesAreCompatible(context.get(), spv::Op::OpAtomicStore, 0, 1683 int_type, uint_type), 1684 "Signedness check should not occur on a pointer operand."); 1685#endif 1686 ASSERT_TRUE(fuzzerutil::TypesAreCompatible( 1687 context.get(), spv::Op::OpAtomicStore, 1, int_type, uint_type)); 1688 ASSERT_TRUE(fuzzerutil::TypesAreCompatible( 1689 context.get(), spv::Op::OpAtomicStore, 2, int_type, uint_type)); 1690 1691// OpAtomicIAdd 1692#ifndef NDEBUG 1693 ASSERT_DEATH( 1694 fuzzerutil::TypesAreCompatible(context.get(), spv::Op::OpAtomicIAdd, 0, 1695 int_type, uint_type), 1696 "Signedness check should not occur on a pointer operand."); 1697#endif 1698 ASSERT_TRUE(fuzzerutil::TypesAreCompatible( 1699 context.get(), spv::Op::OpAtomicIAdd, 1, int_type, uint_type)); 1700 ASSERT_TRUE(fuzzerutil::TypesAreCompatible( 1701 context.get(), spv::Op::OpAtomicIAdd, 2, int_type, uint_type)); 1702 ASSERT_FALSE(fuzzerutil::TypesAreCompatible( 1703 context.get(), spv::Op::OpAtomicIAdd, 3, int_type, uint_type)); 1704 1705// OpAtomicISub 1706#ifndef NDEBUG 1707 ASSERT_DEATH( 1708 fuzzerutil::TypesAreCompatible(context.get(), spv::Op::OpAtomicISub, 0, 1709 int_type, uint_type), 1710 "Signedness check should not occur on a pointer operand."); 1711#endif 1712 ASSERT_TRUE(fuzzerutil::TypesAreCompatible( 1713 context.get(), spv::Op::OpAtomicISub, 1, int_type, uint_type)); 1714 ASSERT_TRUE(fuzzerutil::TypesAreCompatible( 1715 context.get(), spv::Op::OpAtomicISub, 2, int_type, uint_type)); 1716 ASSERT_FALSE(fuzzerutil::TypesAreCompatible( 1717 context.get(), spv::Op::OpAtomicISub, 3, int_type, uint_type)); 1718 1719// OpAtomicSMin 1720#ifndef NDEBUG 1721 ASSERT_DEATH( 1722 fuzzerutil::TypesAreCompatible(context.get(), spv::Op::OpAtomicSMin, 0, 1723 int_type, uint_type), 1724 "Signedness check should not occur on a pointer operand."); 1725#endif 1726 ASSERT_TRUE(fuzzerutil::TypesAreCompatible( 1727 context.get(), spv::Op::OpAtomicSMin, 1, int_type, uint_type)); 1728 ASSERT_TRUE(fuzzerutil::TypesAreCompatible( 1729 context.get(), spv::Op::OpAtomicSMin, 2, int_type, uint_type)); 1730 ASSERT_FALSE(fuzzerutil::TypesAreCompatible( 1731 context.get(), spv::Op::OpAtomicSMin, 3, int_type, uint_type)); 1732 1733// OpAtomicUMin 1734#ifndef NDEBUG 1735 ASSERT_DEATH( 1736 fuzzerutil::TypesAreCompatible(context.get(), spv::Op::OpAtomicUMin, 0, 1737 int_type, uint_type), 1738 "Signedness check should not occur on a pointer operand."); 1739#endif 1740 ASSERT_TRUE(fuzzerutil::TypesAreCompatible( 1741 context.get(), spv::Op::OpAtomicUMin, 1, int_type, uint_type)); 1742 ASSERT_TRUE(fuzzerutil::TypesAreCompatible( 1743 context.get(), spv::Op::OpAtomicUMin, 2, int_type, uint_type)); 1744 ASSERT_FALSE(fuzzerutil::TypesAreCompatible( 1745 context.get(), spv::Op::OpAtomicUMin, 3, int_type, uint_type)); 1746 1747// OpAtomicSMax 1748#ifndef NDEBUG 1749 ASSERT_DEATH( 1750 fuzzerutil::TypesAreCompatible(context.get(), spv::Op::OpAtomicSMax, 0, 1751 int_type, uint_type), 1752 "Signedness check should not occur on a pointer operand."); 1753#endif 1754 ASSERT_TRUE(fuzzerutil::TypesAreCompatible( 1755 context.get(), spv::Op::OpAtomicSMax, 1, int_type, uint_type)); 1756 ASSERT_TRUE(fuzzerutil::TypesAreCompatible( 1757 context.get(), spv::Op::OpAtomicSMax, 2, int_type, uint_type)); 1758 ASSERT_FALSE(fuzzerutil::TypesAreCompatible( 1759 context.get(), spv::Op::OpAtomicSMax, 3, int_type, uint_type)); 1760 1761// OpAtomicUMax 1762#ifndef NDEBUG 1763 ASSERT_DEATH( 1764 fuzzerutil::TypesAreCompatible(context.get(), spv::Op::OpAtomicUMax, 0, 1765 int_type, uint_type), 1766 "Signedness check should not occur on a pointer operand."); 1767#endif 1768 ASSERT_TRUE(fuzzerutil::TypesAreCompatible( 1769 context.get(), spv::Op::OpAtomicUMax, 1, int_type, uint_type)); 1770 ASSERT_TRUE(fuzzerutil::TypesAreCompatible( 1771 context.get(), spv::Op::OpAtomicUMax, 2, int_type, uint_type)); 1772 ASSERT_FALSE(fuzzerutil::TypesAreCompatible( 1773 context.get(), spv::Op::OpAtomicUMax, 3, int_type, uint_type)); 1774 1775// OpAtomicAnd 1776#ifndef NDEBUG 1777 ASSERT_DEATH(fuzzerutil::TypesAreCompatible( 1778 context.get(), spv::Op::OpAtomicAnd, 0, int_type, uint_type), 1779 "Signedness check should not occur on a pointer operand."); 1780#endif 1781 ASSERT_TRUE(fuzzerutil::TypesAreCompatible( 1782 context.get(), spv::Op::OpAtomicAnd, 1, int_type, uint_type)); 1783 ASSERT_TRUE(fuzzerutil::TypesAreCompatible( 1784 context.get(), spv::Op::OpAtomicAnd, 2, int_type, uint_type)); 1785 ASSERT_FALSE(fuzzerutil::TypesAreCompatible( 1786 context.get(), spv::Op::OpAtomicAnd, 3, int_type, uint_type)); 1787 1788// OpAtomicOr 1789#ifndef NDEBUG 1790 ASSERT_DEATH(fuzzerutil::TypesAreCompatible( 1791 context.get(), spv::Op::OpAtomicOr, 0, int_type, uint_type), 1792 "Signedness check should not occur on a pointer operand."); 1793#endif 1794 ASSERT_TRUE(fuzzerutil::TypesAreCompatible(context.get(), spv::Op::OpAtomicOr, 1795 1, int_type, uint_type)); 1796 ASSERT_TRUE(fuzzerutil::TypesAreCompatible(context.get(), spv::Op::OpAtomicOr, 1797 2, int_type, uint_type)); 1798 ASSERT_FALSE(fuzzerutil::TypesAreCompatible( 1799 context.get(), spv::Op::OpAtomicOr, 3, int_type, uint_type)); 1800 1801// OpAtomicXor 1802#ifndef NDEBUG 1803 ASSERT_DEATH(fuzzerutil::TypesAreCompatible( 1804 context.get(), spv::Op::OpAtomicXor, 0, int_type, uint_type), 1805 "Signedness check should not occur on a pointer operand."); 1806#endif 1807 ASSERT_TRUE(fuzzerutil::TypesAreCompatible( 1808 context.get(), spv::Op::OpAtomicXor, 1, int_type, uint_type)); 1809 ASSERT_TRUE(fuzzerutil::TypesAreCompatible( 1810 context.get(), spv::Op::OpAtomicXor, 2, int_type, uint_type)); 1811 ASSERT_FALSE(fuzzerutil::TypesAreCompatible( 1812 context.get(), spv::Op::OpAtomicXor, 3, int_type, uint_type)); 1813} 1814 1815} // namespace 1816} // namespace fuzz 1817} // namespace spvtools 1818