comparator_deep_blocks_first_test.cpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. // Copyright (c) 2020 Google LLC
  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. #include "source/fuzz/comparator_deep_blocks_first.h"
  15. #include "gtest/gtest.h"
  16. #include "source/fuzz/fact_manager/fact_manager.h"
  17. #include "source/fuzz/fuzzer_util.h"
  18. #include "source/fuzz/pseudo_random_generator.h"
  19. #include "source/fuzz/transformation_context.h"
  20. #include "test/fuzz/fuzz_test_util.h"
  21. namespace spvtools {
  22. namespace fuzz {
  23. namespace {
  24. std::string shader = R"(
  25. OpCapability Shader
  26. %1 = OpExtInstImport "GLSL.std.450"
  27. OpMemoryModel Logical GLSL450
  28. OpEntryPoint Fragment %2 "main"
  29. OpExecutionMode %2 OriginUpperLeft
  30. OpSource ESSL 310
  31. %3 = OpTypeVoid
  32. %4 = OpTypeFunction %3
  33. %5 = OpTypeBool
  34. %6 = OpConstantTrue %5
  35. %7 = OpTypeInt 32 1
  36. %8 = OpTypePointer Function %7
  37. %9 = OpConstant %7 1
  38. %10 = OpConstant %7 10
  39. %11 = OpConstant %7 2
  40. %2 = OpFunction %3 None %4
  41. %12 = OpLabel
  42. OpSelectionMerge %13 None
  43. OpBranchConditional %6 %14 %15
  44. %14 = OpLabel
  45. OpBranch %13
  46. %15 = OpLabel
  47. OpBranch %16
  48. %16 = OpLabel
  49. OpLoopMerge %17 %18 None
  50. OpBranch %19
  51. %19 = OpLabel
  52. OpBranchConditional %6 %20 %17
  53. %20 = OpLabel
  54. OpSelectionMerge %21 None
  55. OpBranchConditional %6 %22 %23
  56. %22 = OpLabel
  57. OpBranch %21
  58. %23 = OpLabel
  59. OpBranch %21
  60. %21 = OpLabel
  61. OpBranch %18
  62. %18 = OpLabel
  63. OpBranch %16
  64. %17 = OpLabel
  65. OpBranch %13
  66. %13 = OpLabel
  67. OpReturn
  68. OpFunctionEnd
  69. )";
  70. TEST(ComparatorDeepBlocksFirstTest, Compare) {
  71. const auto env = SPV_ENV_UNIVERSAL_1_5;
  72. const auto consumer = nullptr;
  73. const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
  74. spvtools::ValidatorOptions validator_options;
  75. ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
  76. kConsoleMessageConsumer));
  77. TransformationContext transformation_context(
  78. MakeUnique<FactManager>(context.get()), validator_options);
  79. auto is_deeper = ComparatorDeepBlocksFirst(context.get());
  80. // The block ids and the corresponding depths are:
  81. // 12, 13 -> depth 0
  82. // 14, 15, 16, 17 -> depth 1
  83. // 18, 19, 20, 21 -> depth 2
  84. // 22, 23 -> depth 3
  85. // Perform some comparisons and check that they return true iff the first
  86. // block is deeper than the second.
  87. ASSERT_FALSE(is_deeper(12, 12));
  88. ASSERT_FALSE(is_deeper(12, 13));
  89. ASSERT_FALSE(is_deeper(12, 14));
  90. ASSERT_FALSE(is_deeper(12, 18));
  91. ASSERT_FALSE(is_deeper(12, 22));
  92. ASSERT_TRUE(is_deeper(14, 12));
  93. ASSERT_FALSE(is_deeper(14, 15));
  94. ASSERT_FALSE(is_deeper(15, 14));
  95. ASSERT_FALSE(is_deeper(14, 18));
  96. ASSERT_TRUE(is_deeper(18, 12));
  97. ASSERT_TRUE(is_deeper(18, 16));
  98. }
  99. TEST(ComparatorDeepBlocksFirstTest, Sort) {
  100. const auto env = SPV_ENV_UNIVERSAL_1_5;
  101. const auto consumer = nullptr;
  102. const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
  103. spvtools::ValidatorOptions validator_options;
  104. ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
  105. kConsoleMessageConsumer));
  106. TransformationContext transformation_context(
  107. MakeUnique<FactManager>(context.get()), validator_options);
  108. // Check that, sorting using the comparator, the blocks are ordered from more
  109. // deeply nested to less deeply nested.
  110. // 17 has depth 1, 20 has depth 2, 13 has depth 0.
  111. std::vector<opt::BasicBlock*> blocks = {context->get_instr_block(17),
  112. context->get_instr_block(20),
  113. context->get_instr_block(13)};
  114. std::sort(blocks.begin(), blocks.end(),
  115. ComparatorDeepBlocksFirst(context.get()));
  116. // Check that the blocks are in the correct order.
  117. ASSERT_EQ(blocks[0]->id(), 20);
  118. ASSERT_EQ(blocks[1]->id(), 17);
  119. ASSERT_EQ(blocks[2]->id(), 13);
  120. }
  121. } // namespace
  122. } // namespace fuzz
  123. } // namespace spvtools