// Copyright (c) 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "source/fuzz/shrinker.h"

#include "gtest/gtest.h"
#include "source/fuzz/fact_manager/fact_manager.h"
#include "source/fuzz/fuzzer_context.h"
#include "source/fuzz/fuzzer_pass_donate_modules.h"
#include "source/fuzz/fuzzer_util.h"
#include "source/fuzz/pseudo_random_generator.h"
#include "source/fuzz/transformation_context.h"
#include "source/opt/ir_context.h"
#include "source/util/make_unique.h"
#include "test/fuzz/fuzz_test_util.h"

namespace spvtools {
namespace fuzz {
namespace {

TEST(ShrinkerTest, ReduceAddedFunctions) {
  const std::string kReferenceModule = R"(
               OpCapability Shader
          %1 = OpExtInstImport "GLSL.std.450"
               OpMemoryModel Logical GLSL450
               OpEntryPoint Fragment %4 "main"
               OpExecutionMode %4 OriginUpperLeft
               OpSource ESSL 320
          %2 = OpTypeVoid
          %3 = OpTypeFunction %2
          %6 = OpTypeInt 32 1
          %7 = OpTypePointer Private %6
          %8 = OpVariable %7 Private
          %9 = OpConstant %6 2
         %10 = OpTypePointer Function %6
          %4 = OpFunction %2 None %3
          %5 = OpLabel
         %11 = OpVariable %10 Function
               OpStore %8 %9
         %12 = OpLoad %6 %8
               OpStore %11 %12
               OpReturn
               OpFunctionEnd
  )";

  const std::string kDonorModule = R"(
               OpCapability Shader
          %1 = OpExtInstImport "GLSL.std.450"
               OpMemoryModel Logical GLSL450
               OpEntryPoint Fragment %4 "main"
               OpExecutionMode %4 OriginUpperLeft
               OpSource ESSL 320
          %2 = OpTypeVoid
          %3 = OpTypeFunction %2
          %6 = OpTypeInt 32 1
          %7 = OpTypePointer Function %6
          %8 = OpTypeFunction %6 %7
         %12 = OpTypeFunction %2 %7
         %17 = OpConstant %6 0
         %26 = OpTypeBool
         %32 = OpConstant %6 1
         %46 = OpTypePointer Private %6
         %47 = OpVariable %46 Private
         %48 = OpConstant %6 3
          %4 = OpFunction %2 None %3
          %5 = OpLabel
         %49 = OpVariable %7 Function
         %50 = OpVariable %7 Function
         %51 = OpLoad %6 %49
               OpStore %50 %51
         %52 = OpFunctionCall %2 %14 %50
               OpReturn
               OpFunctionEnd
         %10 = OpFunction %6 None %8
          %9 = OpFunctionParameter %7
         %11 = OpLabel
         %16 = OpVariable %7 Function
         %18 = OpVariable %7 Function
               OpStore %16 %17
               OpStore %18 %17
               OpBranch %19
         %19 = OpLabel
               OpLoopMerge %21 %22 None
               OpBranch %23
         %23 = OpLabel
         %24 = OpLoad %6 %18
         %25 = OpLoad %6 %9
         %27 = OpSLessThan %26 %24 %25
               OpBranchConditional %27 %20 %21
         %20 = OpLabel
         %28 = OpLoad %6 %9
         %29 = OpLoad %6 %16
         %30 = OpIAdd %6 %29 %28
               OpStore %16 %30
               OpBranch %22
         %22 = OpLabel
         %31 = OpLoad %6 %18
         %33 = OpIAdd %6 %31 %32
               OpStore %18 %33
               OpBranch %19
         %21 = OpLabel
         %34 = OpLoad %6 %16
         %35 = OpNot %6 %34
               OpReturnValue %35
               OpFunctionEnd
         %14 = OpFunction %2 None %12
         %13 = OpFunctionParameter %7
         %15 = OpLabel
         %37 = OpVariable %7 Function
         %38 = OpVariable %7 Function
         %39 = OpLoad %6 %13
               OpStore %38 %39
         %40 = OpFunctionCall %6 %10 %38
               OpStore %37 %40
         %41 = OpLoad %6 %37
         %42 = OpLoad %6 %13
         %43 = OpSGreaterThan %26 %41 %42
               OpSelectionMerge %45 None
               OpBranchConditional %43 %44 %45
         %44 = OpLabel
               OpStore %47 %48
               OpBranch %45
         %45 = OpLabel
               OpReturn
               OpFunctionEnd
  )";

  // Note: |env| should ideally be declared const.  However, due to a known
  // issue with older versions of MSVC we would have to mark |env| as being
  // captured due to its used in a lambda below, and other compilers would warn
  // that such capturing is not necessary.  Not declaring |env| as const means
  // that it needs to be captured to be used in the lambda, and thus all
  // compilers are kept happy.  See:
  // https://developercommunity.visualstudio.com/content/problem/367326/problems-with-capturing-constexpr-in-lambda.html
  spv_target_env env = SPV_ENV_UNIVERSAL_1_3;
  const auto consumer = fuzzerutil::kSilentMessageConsumer;

  SpirvTools tools(env);
  std::vector<uint32_t> reference_binary;
  ASSERT_TRUE(
      tools.Assemble(kReferenceModule, &reference_binary, kFuzzAssembleOption));

  spvtools::ValidatorOptions validator_options;

  const auto variant_ir_context =
      BuildModule(env, consumer, kReferenceModule, kFuzzAssembleOption);
  ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(
      variant_ir_context.get(), validator_options, kConsoleMessageConsumer));

  const auto donor_ir_context =
      BuildModule(env, consumer, kDonorModule, kFuzzAssembleOption);
  ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(
      donor_ir_context.get(), validator_options, kConsoleMessageConsumer));

  FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100,
                               false);
  TransformationContext transformation_context(
      MakeUnique<FactManager>(variant_ir_context.get()), validator_options);

  protobufs::TransformationSequence transformations;
  FuzzerPassDonateModules pass(variant_ir_context.get(),
                               &transformation_context, &fuzzer_context,
                               &transformations, false, {});
  pass.DonateSingleModule(donor_ir_context.get(), true);

  protobufs::FactSequence no_facts;

  Shrinker::InterestingnessFunction interestingness_function =
      [consumer, env](const std::vector<uint32_t>& binary,
                      uint32_t /*unused*/) -> bool {
    bool found_op_not = false;
    uint32_t op_call_count = 0;
    auto temp_ir_context =
        BuildModule(env, consumer, binary.data(), binary.size());
    for (auto& function : *temp_ir_context->module()) {
      for (auto& block : function) {
        for (auto& inst : block) {
          if (inst.opcode() == spv::Op::OpNot) {
            found_op_not = true;
          } else if (inst.opcode() == spv::Op::OpFunctionCall) {
            op_call_count++;
          }
        }
      }
    }
    return found_op_not && op_call_count >= 2;
  };

  auto shrinker_result =
      Shrinker(env, consumer, reference_binary, no_facts, transformations,
               interestingness_function, 1000, true, validator_options)
          .Run();
  ASSERT_EQ(Shrinker::ShrinkerResultStatus::kComplete, shrinker_result.status);

  // We now check that the module after shrinking looks right.
  // The entry point should be identical to what it looked like in the
  // reference, while the other functions should be absolutely minimal,
  // containing only what is needed to satisfy the interestingness function.
  auto ir_context_after_shrinking =
      BuildModule(env, consumer, shrinker_result.transformed_binary.data(),
                  shrinker_result.transformed_binary.size());
  bool first_function = true;
  for (auto& function : *ir_context_after_shrinking->module()) {
    if (first_function) {
      first_function = false;
      bool first_block = true;
      for (auto& block : function) {
        ASSERT_TRUE(first_block);
        uint32_t counter = 0;
        for (auto& inst : block) {
          switch (counter) {
            case 0:
              ASSERT_EQ(spv::Op::OpVariable, inst.opcode());
              ASSERT_EQ(11, inst.result_id());
              break;
            case 1:
              ASSERT_EQ(spv::Op::OpStore, inst.opcode());
              break;
            case 2:
              ASSERT_EQ(spv::Op::OpLoad, inst.opcode());
              ASSERT_EQ(12, inst.result_id());
              break;
            case 3:
              ASSERT_EQ(spv::Op::OpStore, inst.opcode());
              break;
            case 4:
              ASSERT_EQ(spv::Op::OpReturn, inst.opcode());
              break;
            default:
              FAIL();
          }
          counter++;
        }
      }
    } else {
      bool first_block = true;
      for (auto& block : function) {
        ASSERT_TRUE(first_block);
        first_block = false;
        for (auto& inst : block) {
          switch (inst.opcode()) {
            case spv::Op::OpVariable:
            case spv::Op::OpNot:
            case spv::Op::OpReturn:
            case spv::Op::OpReturnValue:
            case spv::Op::OpFunctionCall:
              // These are the only instructions we expect to see.
              break;
            default:
              FAIL();
          }
        }
      }
    }
  }
}

TEST(ShrinkerTest, HitStepLimitWhenReducingAddedFunctions) {
  const std::string kReferenceModule = R"(
               OpCapability Shader
          %1 = OpExtInstImport "GLSL.std.450"
               OpMemoryModel Logical GLSL450
               OpEntryPoint Fragment %4 "main"
               OpExecutionMode %4 OriginUpperLeft
               OpSource ESSL 320
          %2 = OpTypeVoid
          %3 = OpTypeFunction %2
          %6 = OpTypeInt 32 1
          %7 = OpTypePointer Private %6
          %8 = OpVariable %7 Private
          %9 = OpConstant %6 2
         %10 = OpTypePointer Function %6
          %4 = OpFunction %2 None %3
          %5 = OpLabel
         %11 = OpVariable %10 Function
               OpStore %8 %9
         %12 = OpLoad %6 %8
               OpStore %11 %12
               OpReturn
               OpFunctionEnd
  )";

  const std::string kDonorModule = R"(
               OpCapability Shader
          %1 = OpExtInstImport "GLSL.std.450"
               OpMemoryModel Logical GLSL450
               OpEntryPoint Fragment %4 "main"
               OpExecutionMode %4 OriginUpperLeft
               OpSource ESSL 320
          %2 = OpTypeVoid
          %3 = OpTypeFunction %2
          %6 = OpTypeInt 32 1
         %48 = OpConstant %6 3
          %4 = OpFunction %2 None %3
          %5 = OpLabel
         %52 = OpCopyObject %6 %48
         %53 = OpCopyObject %6 %52
         %54 = OpCopyObject %6 %53
         %55 = OpCopyObject %6 %54
         %56 = OpCopyObject %6 %55
         %57 = OpCopyObject %6 %56
         %58 = OpCopyObject %6 %48
         %59 = OpCopyObject %6 %58
         %60 = OpCopyObject %6 %59
         %61 = OpCopyObject %6 %60
         %62 = OpCopyObject %6 %61
         %63 = OpCopyObject %6 %62
         %64 = OpCopyObject %6 %48
               OpReturn
               OpFunctionEnd
  )";

  spv_target_env env = SPV_ENV_UNIVERSAL_1_3;
  const auto consumer = fuzzerutil::kSilentMessageConsumer;

  SpirvTools tools(env);
  std::vector<uint32_t> reference_binary;
  ASSERT_TRUE(
      tools.Assemble(kReferenceModule, &reference_binary, kFuzzAssembleOption));

  spvtools::ValidatorOptions validator_options;

  const auto variant_ir_context =
      BuildModule(env, consumer, kReferenceModule, kFuzzAssembleOption);
  ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(
      variant_ir_context.get(), validator_options, kConsoleMessageConsumer));

  const auto donor_ir_context =
      BuildModule(env, consumer, kDonorModule, kFuzzAssembleOption);
  ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(
      donor_ir_context.get(), validator_options, kConsoleMessageConsumer));

  FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0), 100,
                               false);
  TransformationContext transformation_context(
      MakeUnique<FactManager>(variant_ir_context.get()), validator_options);

  protobufs::TransformationSequence transformations;
  FuzzerPassDonateModules pass(variant_ir_context.get(),
                               &transformation_context, &fuzzer_context,
                               &transformations, false, {});
  pass.DonateSingleModule(donor_ir_context.get(), true);

  protobufs::FactSequence no_facts;

  Shrinker::InterestingnessFunction interestingness_function =
      [consumer, env](const std::vector<uint32_t>& binary,
                      uint32_t /*unused*/) -> bool {
    auto temp_ir_context =
        BuildModule(env, consumer, binary.data(), binary.size());
    uint32_t copy_object_count = 0;
    temp_ir_context->module()->ForEachInst(
        [&copy_object_count](opt::Instruction* inst) {
          if (inst->opcode() == spv::Op::OpCopyObject) {
            copy_object_count++;
          }
        });
    return copy_object_count >= 8;
  };

  auto shrinker_result =
      Shrinker(env, consumer, reference_binary, no_facts, transformations,
               interestingness_function, 30, true, validator_options)
          .Run();
  ASSERT_EQ(Shrinker::ShrinkerResultStatus::kStepLimitReached,
            shrinker_result.status);
}

}  // namespace
}  // namespace fuzz
}  // namespace spvtools
