// 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) {}

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
