// 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/fuzzer_pass_add_equation_instructions.h"

#include <vector>

#include "source/fuzz/fuzzer_util.h"
#include "source/fuzz/transformation_equation_instruction.h"

namespace spvtools {
namespace fuzz {
namespace {

bool IsBitWidthSupported(opt::IRContext* ir_context, uint32_t bit_width) {
  switch (bit_width) {
    case 32:
      return true;
    case 64:
      return ir_context->get_feature_mgr()->HasCapability(
                 SpvCapabilityFloat64) &&
             ir_context->get_feature_mgr()->HasCapability(SpvCapabilityInt64);
    case 16:
      return ir_context->get_feature_mgr()->HasCapability(
                 SpvCapabilityFloat16) &&
             ir_context->get_feature_mgr()->HasCapability(SpvCapabilityInt16);
    default:
      return false;
  }
}

}  // namespace

FuzzerPassAddEquationInstructions::FuzzerPassAddEquationInstructions(
    opt::IRContext* ir_context, TransformationContext* transformation_context,
    FuzzerContext* fuzzer_context,
    protobufs::TransformationSequence* transformations)
    : FuzzerPass(ir_context, transformation_context, fuzzer_context,
                 transformations) {}

FuzzerPassAddEquationInstructions::~FuzzerPassAddEquationInstructions() =
    default;

void FuzzerPassAddEquationInstructions::Apply() {
  ForEachInstructionWithInstructionDescriptor(
      [this](opt::Function* function, opt::BasicBlock* block,
             opt::BasicBlock::iterator inst_it,
             const protobufs::InstructionDescriptor& instruction_descriptor) {
        if (!GetFuzzerContext()->ChoosePercentage(
                GetFuzzerContext()->GetChanceOfAddingEquationInstruction())) {
          return;
        }

        // Check that it is OK to add an equation instruction before the given
        // instruction in principle - e.g. check that this does not lead to
        // inserting before an OpVariable or OpPhi instruction.  We use OpIAdd
        // as an example opcode for this check, to be representative of *some*
        // opcode that defines an equation, even though we may choose a
        // different opcode below.
        if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(SpvOpIAdd, inst_it)) {
          return;
        }

        // Get all available instructions with result ids and types that are not
        // OpUndef.
        std::vector<opt::Instruction*> available_instructions =
            FindAvailableInstructions(
                function, block, inst_it,
                [this](opt::IRContext* /*unused*/,
                       opt::Instruction* instruction) -> bool {
                  return instruction->result_id() && instruction->type_id() &&
                         instruction->opcode() != SpvOpUndef &&
                         !GetTransformationContext()
                              ->GetFactManager()
                              ->IdIsIrrelevant(instruction->result_id());
                });

        // Try the opcodes for which we know how to make ids at random until
        // something works.
        std::vector<SpvOp> candidate_opcodes = {
            SpvOpIAdd,        SpvOpISub,        SpvOpLogicalNot, SpvOpSNegate,
            SpvOpConvertUToF, SpvOpConvertSToF, SpvOpBitcast};
        do {
          auto opcode =
              GetFuzzerContext()->RemoveAtRandomIndex(&candidate_opcodes);
          switch (opcode) {
            case SpvOpConvertSToF:
            case SpvOpConvertUToF: {
              std::vector<const opt::Instruction*> candidate_instructions;
              for (const auto* inst :
                   GetIntegerInstructions(available_instructions)) {
                const auto* type =
                    GetIRContext()->get_type_mgr()->GetType(inst->type_id());
                assert(type && "|inst| has invalid type");

                if (const auto* vector_type = type->AsVector()) {
                  type = vector_type->element_type();
                }

                if (IsBitWidthSupported(GetIRContext(),
                                        type->AsInteger()->width())) {
                  candidate_instructions.push_back(inst);
                }
              }

              if (candidate_instructions.empty()) {
                break;
              }

              const auto* operand =
                  candidate_instructions[GetFuzzerContext()->RandomIndex(
                      candidate_instructions)];

              const auto* type =
                  GetIRContext()->get_type_mgr()->GetType(operand->type_id());
              assert(type && "Operand has invalid type");

              // Make sure a result type exists in the module.
              if (const auto* vector = type->AsVector()) {
                // We store element count in a separate variable since the
                // call FindOrCreate* functions below might invalidate
                // |vector| pointer.
                const auto element_count = vector->element_count();

                FindOrCreateVectorType(
                    FindOrCreateFloatType(
                        vector->element_type()->AsInteger()->width()),
                    element_count);
              } else {
                FindOrCreateFloatType(type->AsInteger()->width());
              }

              ApplyTransformation(TransformationEquationInstruction(
                  GetFuzzerContext()->GetFreshId(), opcode,
                  {operand->result_id()}, instruction_descriptor));
              return;
            }
            case SpvOpBitcast: {
              const auto candidate_instructions =
                  GetNumericalInstructions(available_instructions);

              if (!candidate_instructions.empty()) {
                const auto* operand_inst =
                    candidate_instructions[GetFuzzerContext()->RandomIndex(
                        candidate_instructions)];
                const auto* operand_type =
                    GetIRContext()->get_type_mgr()->GetType(
                        operand_inst->type_id());
                assert(operand_type && "Operand instruction has invalid type");

                // Make sure a result type exists in the module.
                //
                // TODO(https://github.com/KhronosGroup/SPIRV-Tools/issues/3539):
                //  The only constraint on the types of OpBitcast's parameters
                //  is that they must have the same number of bits. Consider
                //  improving the code below to support this in full.
                if (const auto* vector = operand_type->AsVector()) {
                  // We store element count in a separate variable since the
                  // call FindOrCreate* functions below might invalidate
                  // |vector| pointer.
                  const auto element_count = vector->element_count();

                  uint32_t element_type_id;
                  if (const auto* int_type =
                          vector->element_type()->AsInteger()) {
                    element_type_id = FindOrCreateFloatType(int_type->width());
                  } else {
                    assert(vector->element_type()->AsFloat() &&
                           "Vector must have numerical elements");
                    element_type_id = FindOrCreateIntegerType(
                        vector->element_type()->AsFloat()->width(),
                        GetFuzzerContext()->ChooseEven());
                  }

                  FindOrCreateVectorType(element_type_id, element_count);
                } else if (const auto* int_type = operand_type->AsInteger()) {
                  FindOrCreateFloatType(int_type->width());
                } else {
                  assert(operand_type->AsFloat() &&
                         "Operand is not a scalar of numerical type");
                  FindOrCreateIntegerType(operand_type->AsFloat()->width(),
                                          GetFuzzerContext()->ChooseEven());
                }

                ApplyTransformation(TransformationEquationInstruction(
                    GetFuzzerContext()->GetFreshId(), opcode,
                    {operand_inst->result_id()}, instruction_descriptor));
                return;
              }
            } break;
            case SpvOpIAdd:
            case SpvOpISub: {
              // Instructions of integer (scalar or vector) result type are
              // suitable for these opcodes.
              auto integer_instructions =
                  GetIntegerInstructions(available_instructions);
              if (!integer_instructions.empty()) {
                // There is at least one such instruction, so pick one at random
                // for the LHS of an equation.
                auto lhs = integer_instructions.at(
                    GetFuzzerContext()->RandomIndex(integer_instructions));

                // For the RHS, we can use any instruction with an integer
                // scalar/vector result type of the same number of components
                // and the same bit-width for the underlying integer type.

                // Work out the element count and bit-width.
                auto lhs_type =
                    GetIRContext()->get_type_mgr()->GetType(lhs->type_id());
                uint32_t lhs_element_count;
                uint32_t lhs_bit_width;
                if (lhs_type->AsVector()) {
                  lhs_element_count = lhs_type->AsVector()->element_count();
                  lhs_bit_width = lhs_type->AsVector()
                                      ->element_type()
                                      ->AsInteger()
                                      ->width();
                } else {
                  lhs_element_count = 1;
                  lhs_bit_width = lhs_type->AsInteger()->width();
                }

                // Get all the instructions that match on element count and
                // bit-width.
                auto candidate_rhs_instructions = RestrictToElementBitWidth(
                    RestrictToVectorWidth(integer_instructions,
                                          lhs_element_count),
                    lhs_bit_width);

                // Choose a RHS instruction at random; there is guaranteed to
                // be at least one choice as the LHS will be available.
                auto rhs = candidate_rhs_instructions.at(
                    GetFuzzerContext()->RandomIndex(
                        candidate_rhs_instructions));

                // Add the equation instruction.
                ApplyTransformation(TransformationEquationInstruction(
                    GetFuzzerContext()->GetFreshId(), opcode,
                    {lhs->result_id(), rhs->result_id()},
                    instruction_descriptor));
                return;
              }
              break;
            }
            case SpvOpLogicalNot: {
              // Choose any available instruction of boolean scalar/vector
              // result type and equate its negation with a fresh id.
              auto boolean_instructions =
                  GetBooleanInstructions(available_instructions);
              if (!boolean_instructions.empty()) {
                ApplyTransformation(TransformationEquationInstruction(
                    GetFuzzerContext()->GetFreshId(), opcode,
                    {boolean_instructions
                         .at(GetFuzzerContext()->RandomIndex(
                             boolean_instructions))
                         ->result_id()},
                    instruction_descriptor));
                return;
              }
              break;
            }
            case SpvOpSNegate: {
              // Similar to OpLogicalNot, but for signed integer negation.
              auto integer_instructions =
                  GetIntegerInstructions(available_instructions);
              if (!integer_instructions.empty()) {
                ApplyTransformation(TransformationEquationInstruction(
                    GetFuzzerContext()->GetFreshId(), opcode,
                    {integer_instructions
                         .at(GetFuzzerContext()->RandomIndex(
                             integer_instructions))
                         ->result_id()},
                    instruction_descriptor));
                return;
              }
              break;
            }
            default:
              assert(false && "Unexpected opcode.");
              break;
          }
        } while (!candidate_opcodes.empty());
        // Reaching here means that we did not manage to apply any
        // transformation at this point of the module.
      });
}

std::vector<opt::Instruction*>
FuzzerPassAddEquationInstructions::GetIntegerInstructions(
    const std::vector<opt::Instruction*>& instructions) const {
  std::vector<opt::Instruction*> result;
  for (auto& inst : instructions) {
    auto type = GetIRContext()->get_type_mgr()->GetType(inst->type_id());
    if (type->AsInteger() ||
        (type->AsVector() && type->AsVector()->element_type()->AsInteger())) {
      result.push_back(inst);
    }
  }
  return result;
}

std::vector<opt::Instruction*>
FuzzerPassAddEquationInstructions::GetFloatInstructions(
    const std::vector<opt::Instruction*>& instructions) const {
  std::vector<opt::Instruction*> result;
  for (auto& inst : instructions) {
    auto type = GetIRContext()->get_type_mgr()->GetType(inst->type_id());
    if (type->AsFloat() ||
        (type->AsVector() && type->AsVector()->element_type()->AsFloat())) {
      result.push_back(inst);
    }
  }
  return result;
}

std::vector<opt::Instruction*>
FuzzerPassAddEquationInstructions::GetBooleanInstructions(
    const std::vector<opt::Instruction*>& instructions) const {
  std::vector<opt::Instruction*> result;
  for (auto& inst : instructions) {
    auto type = GetIRContext()->get_type_mgr()->GetType(inst->type_id());
    if (type->AsBool() ||
        (type->AsVector() && type->AsVector()->element_type()->AsBool())) {
      result.push_back(inst);
    }
  }
  return result;
}

std::vector<opt::Instruction*>
FuzzerPassAddEquationInstructions::RestrictToVectorWidth(
    const std::vector<opt::Instruction*>& instructions,
    uint32_t vector_width) const {
  std::vector<opt::Instruction*> result;
  for (auto& inst : instructions) {
    auto type = GetIRContext()->get_type_mgr()->GetType(inst->type_id());
    // Get the vector width of |inst|, which is 1 if |inst| is a scalar and is
    // otherwise derived from its vector type.
    uint32_t other_vector_width =
        type->AsVector() ? type->AsVector()->element_count() : 1;
    // Keep |inst| if the vector widths match.
    if (vector_width == other_vector_width) {
      result.push_back(inst);
    }
  }
  return result;
}

std::vector<opt::Instruction*>
FuzzerPassAddEquationInstructions::RestrictToElementBitWidth(
    const std::vector<opt::Instruction*>& instructions,
    uint32_t bit_width) const {
  std::vector<opt::Instruction*> result;
  for (auto& inst : instructions) {
    const opt::analysis::Type* type =
        GetIRContext()->get_type_mgr()->GetType(inst->type_id());
    if (type->AsVector()) {
      type = type->AsVector()->element_type();
    }
    assert((type->AsInteger() || type->AsFloat()) &&
           "Precondition: all input instructions must "
           "have integer or float scalar or vector type.");
    if ((type->AsInteger() && type->AsInteger()->width() == bit_width) ||
        (type->AsFloat() && type->AsFloat()->width() == bit_width)) {
      result.push_back(inst);
    }
  }
  return result;
}

std::vector<opt::Instruction*>
FuzzerPassAddEquationInstructions::GetNumericalInstructions(
    const std::vector<opt::Instruction*>& instructions) const {
  std::vector<opt::Instruction*> result;

  for (auto* inst : instructions) {
    const auto* type = GetIRContext()->get_type_mgr()->GetType(inst->type_id());
    assert(type && "Instruction has invalid type");

    if (const auto* vector_type = type->AsVector()) {
      type = vector_type->element_type();
    }

    if (!type->AsInteger() && !type->AsFloat()) {
      // Only numerical scalars or vectors of numerical components are
      // supported.
      continue;
    }

    if (!IsBitWidthSupported(GetIRContext(), type->AsInteger()
                                                 ? type->AsInteger()->width()
                                                 : type->AsFloat()->width())) {
      continue;
    }

    result.push_back(inst);
  }

  return result;
}

}  // namespace fuzz
}  // namespace spvtools
