//===- IRSimilarityIdentifierTest.cpp - IRSimilarityIdentifier unit tests -===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Tests for components for finding similarity such as the instruction mapper,
// suffix tree usage, and structural analysis.
//
//===----------------------------------------------------------------------===//

#include "llvm/Analysis/IRSimilarityIdentifier.h"
#include "llvm/ADT/ScopeExit.h"
#include "llvm/AsmParser/Parser.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/SourceMgr.h"
#include "gtest/gtest.h"

using namespace llvm;
using namespace IRSimilarity;

extern llvm::cl::opt<bool> UseNewDbgInfoFormat;
extern cl::opt<cl::boolOrDefault> PreserveInputDbgFormat;
extern bool WriteNewDbgInfoFormatToBitcode;
extern cl::opt<bool> WriteNewDbgInfoFormat;

static std::unique_ptr<Module> makeLLVMModule(LLVMContext &Context,
                                              StringRef ModuleStr) {
  SMDiagnostic Err;
  std::unique_ptr<Module> M = parseAssemblyString(ModuleStr, Err, Context);
  assert(M && "Bad LLVM IR?");
  return M;
}

void getVectors(Module &M, IRInstructionMapper &Mapper,
                std::vector<IRInstructionData *> &InstrList,
                std::vector<unsigned> &UnsignedVec) {
  for (Function &F : M)
    for (BasicBlock &BB : F)
      Mapper.convertToUnsignedVec(BB, InstrList, UnsignedVec);
}

void getSimilarities(
    Module &M,
    std::vector<std::vector<IRSimilarityCandidate>> &SimilarityCandidates) {
  // In order to keep the size of the tests from becoming too large, we do not
  // recognize similarity for branches unless explicitly needed.
  IRSimilarityIdentifier Identifier(/*EnableBranchMatching = */false);
  SimilarityCandidates = Identifier.findSimilarity(M);
}

// Checks that different opcodes are mapped to different values
TEST(IRInstructionMapper, OpcodeDifferentiation) {
  StringRef ModuleString = R"(
                          define i32 @f(i32 %a, i32 %b) {
                          bb0:
                             %0 = add i32 %a, %b
                             %1 = mul i32 %a, %b
                             ret i32 0
                          })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  // Check that the size of the unsigned vector and the instruction list are the
  // same as a safety check.
  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());

  // Make sure that the unsigned vector is the expected size.
  ASSERT_TRUE(UnsignedVec.size() == 3);

  // Check whether the instructions are not mapped to the same value.
  ASSERT_TRUE(UnsignedVec[0] != UnsignedVec[1]);
}

// Checks that the same opcodes and types are mapped to the same values.
TEST(IRInstructionMapper, OpcodeTypeSimilarity) {
  StringRef ModuleString = R"(
                          define i32 @f(i32 %a, i32 %b) {
                          bb0:
                             %0 = add i32 %a, %b
                             %1 = add i32 %b, %a
                             ret i32 0
                          })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());
  ASSERT_TRUE(UnsignedVec.size() == 3);

  // Check whether the instructions are mapped to the same value.
  ASSERT_TRUE(UnsignedVec[0] == UnsignedVec[1]);
}

// Checks that the same opcode and different types are mapped to different
// values.
TEST(IRInstructionMapper, TypeDifferentiation) {
  StringRef ModuleString = R"(
                          define i32 @f(i32 %a, i32 %b, i64 %c, i64 %d) {
                          bb0:
                             %0 = add i32 %a, %b
                             %1 = add i64 %c, %d
                             ret i32 0
                          })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());
  ASSERT_TRUE(UnsignedVec.size() == 3);
  ASSERT_TRUE(UnsignedVec[0] != UnsignedVec[1]);
}

// Checks that different predicates map to different values.
TEST(IRInstructionMapper, PredicateDifferentiation) {
  StringRef ModuleString = R"(
                          define i32 @f(i32 %a, i32 %b) {
                          bb0:
                             %0 = icmp sge i32 %b, %a
                             %1 = icmp slt i32 %a, %b
                             ret i32 0
                          })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());
  ASSERT_TRUE(UnsignedVec.size() == 3);
  ASSERT_TRUE(UnsignedVec[0] != UnsignedVec[1]);
}

// Checks that predicates where that can be considered the same when the
// operands are swapped, i.e. greater than to less than are mapped to the same
// unsigned integer.
TEST(IRInstructionMapper, PredicateIsomorphism) {
  StringRef ModuleString = R"(
                          define i32 @f(i32 %a, i32 %b) {
                          bb0:
                             %0 = icmp sgt i32 %a, %b
                             %1 = icmp slt i32 %b, %a
                             ret i32 0
                          })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());
  ASSERT_TRUE(UnsignedVec.size() == 3);
  ASSERT_TRUE(UnsignedVec[0] == UnsignedVec[1]);
}

// Checks that the same predicate maps to the same value.
TEST(IRInstructionMapper, PredicateSimilarity) {
  StringRef ModuleString = R"(
                          define i32 @f(i32 %a, i32 %b) {
                          bb0:
                             %0 = icmp slt i32 %a, %b
                             %1 = icmp slt i32 %b, %a
                             ret i32 0
                          })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());
  ASSERT_TRUE(UnsignedVec.size() == 3);
  ASSERT_TRUE(UnsignedVec[0] == UnsignedVec[1]);
}

// Checks that the same predicate maps to the same value for floating point
// CmpInsts.
TEST(IRInstructionMapper, FPPredicateSimilarity) {
  StringRef ModuleString = R"(
                          define i32 @f(double %a, double %b) {
                          bb0:
                             %0 = fcmp olt double %a, %b
                             %1 = fcmp olt double %b, %a
                             ret i32 0
                          })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());
  ASSERT_TRUE(UnsignedVec.size() == 3);
  ASSERT_TRUE(UnsignedVec[0] == UnsignedVec[1]);
}

// Checks that the different predicate maps to a different value for floating
// point CmpInsts.
TEST(IRInstructionMapper, FPPredicatDifference) {
  StringRef ModuleString = R"(
                          define i32 @f(double %a, double %b) {
                          bb0:
                             %0 = fcmp olt double %a, %b
                             %1 = fcmp oge double %b, %a
                             ret i32 0
                          })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());
  ASSERT_TRUE(UnsignedVec.size() == 3);
  ASSERT_TRUE(UnsignedVec[0] != UnsignedVec[1]);
}

// Checks that the zexts that have the same type parameters map to the same
// unsigned integer.
TEST(IRInstructionMapper, ZextTypeSimilarity) {
  StringRef ModuleString = R"(
                          define i32 @f(i32 %a) {
                          bb0:
                             %0 = zext i32  %a to i64
                             %1 = zext i32  %a to i64
                             ret i32 0
                          })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());
  ASSERT_TRUE(UnsignedVec.size() == 3);
  ASSERT_TRUE(UnsignedVec[0] == UnsignedVec[1]);
}

// Checks that the sexts that have the same type parameters map to the same
// unsigned integer.
TEST(IRInstructionMapper, SextTypeSimilarity) {
  StringRef ModuleString = R"(
                          define i32 @f(i32 %a) {
                          bb0:
                             %0 = sext i32  %a to i64
                             %1 = sext i32  %a to i64
                             ret i32 0
                          })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());
  ASSERT_TRUE(UnsignedVec.size() == 3);
  ASSERT_TRUE(UnsignedVec[0] == UnsignedVec[1]);
}

// Checks that the zexts that have the different type parameters map to the
// different unsigned integers.
TEST(IRInstructionMapper, ZextTypeDifference) {
  StringRef ModuleString = R"(
                          define i32 @f(i32 %a, i8 %b) {
                          bb0:
                             %0 = zext i32 %a to i64
                             %1 = zext i8 %b to i32
                             ret i32 0
                          })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());
  ASSERT_TRUE(UnsignedVec.size() == 3);
  ASSERT_TRUE(UnsignedVec[0] != UnsignedVec[1]);
}

// Checks that the sexts that have the different type parameters map to the
// different unsigned integers.
TEST(IRInstructionMapper, SextTypeDifference) {
  StringRef ModuleString = R"(
                          define i32 @f(i32 %a, i8 %b) {
                          bb0:
                             %0 = sext i32 %a to i64
                             %1 = sext i8 %b to i32
                             ret i32 0
                          })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());
  ASSERT_TRUE(UnsignedVec.size() == 3);
  ASSERT_TRUE(UnsignedVec[0] != UnsignedVec[1]);
}

// Checks that loads that have the same type are mapped to the same unsigned
// integer.
TEST(IRInstructionMapper, LoadSimilarType) {
  StringRef ModuleString = R"(
                          define i32 @f(i32* %a, i32* %b) {
                          bb0:
                             %0 = load i32, i32* %a
                             %1 = load i32, i32* %b
                             ret i32 0
                          })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());
  ASSERT_TRUE(UnsignedVec.size() == 3);
  ASSERT_TRUE(UnsignedVec[0] == UnsignedVec[1]);
}

// Checks that loads that have the different types are mapped to
// different unsigned integers.
TEST(IRInstructionMapper, LoadDifferentType) {
  StringRef ModuleString = R"(
                          define i32 @f(i32* %a, i64* %b) {
                          bb0:
                             %0 = load i32, i32* %a
                             %1 = load i64, i64* %b
                             ret i32 0
                          })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());
  ASSERT_TRUE(UnsignedVec.size() == 3);
  ASSERT_TRUE(UnsignedVec[0] != UnsignedVec[1]);
}

// Checks that loads that have the different aligns are mapped to different
// unsigned integers.
TEST(IRInstructionMapper, LoadDifferentAlign) {
  StringRef ModuleString = R"(
                          define i32 @f(i32* %a, i32* %b) {
                          bb0:
                             %0 = load i32, i32* %a, align 4
                             %1 = load i32, i32* %b, align 8
                             ret i32 0
                          })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());
  ASSERT_TRUE(UnsignedVec.size() == 3);
  ASSERT_TRUE(UnsignedVec[0] != UnsignedVec[1]);
}

// Checks that loads that have the different volatile settings are mapped to
// different unsigned integers.
TEST(IRInstructionMapper, LoadDifferentVolatile) {
  StringRef ModuleString = R"(
                          define i32 @f(i32* %a, i32* %b) {
                          bb0:
                             %0 = load volatile i32, i32* %a
                             %1 = load i32, i32* %b
                             ret i32 0
                          })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());
  ASSERT_TRUE(UnsignedVec.size() == 3);
  ASSERT_TRUE(UnsignedVec[0] != UnsignedVec[1]);
}

// Checks that loads that have the same volatile settings are mapped to
// different unsigned integers.
TEST(IRInstructionMapper, LoadSameVolatile) {
  StringRef ModuleString = R"(
                          define i32 @f(i32* %a, i32* %b) {
                          bb0:
                             %0 = load volatile i32, i32* %a
                             %1 = load volatile i32, i32* %b
                             ret i32 0
                          })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());
  ASSERT_TRUE(UnsignedVec.size() == 3);
  ASSERT_TRUE(UnsignedVec[0] == UnsignedVec[1]);
}

// Checks that loads that have the different atomicity settings are mapped to
// different unsigned integers.
TEST(IRInstructionMapper, LoadDifferentAtomic) {
  StringRef ModuleString = R"(
                          define i32 @f(i32* %a, i32* %b) {
                          bb0:
                             %0 = load atomic i32, i32* %a unordered, align 4
                             %1 = load atomic i32, i32* %b monotonic, align 4
                             ret i32 0
                          })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());
  ASSERT_TRUE(UnsignedVec.size() == 3);
  ASSERT_TRUE(UnsignedVec[0] != UnsignedVec[1]);
}

// Checks that loads that have the same atomicity settings are mapped to
// different unsigned integers.
TEST(IRInstructionMapper, LoadSameAtomic) {
  StringRef ModuleString = R"(
                          define i32 @f(i32* %a, i32* %b) {
                          bb0:
                             %0 = load atomic i32, i32* %a unordered, align 4
                             %1 = load atomic i32, i32* %b unordered, align 4
                             ret i32 0
                          })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());
  ASSERT_TRUE(UnsignedVec.size() == 3);
  ASSERT_TRUE(UnsignedVec[0] == UnsignedVec[1]);
}

// Checks that stores that have the same type are mapped to the same unsigned
// integer.
TEST(IRInstructionMapper, StoreSimilarType) {
  StringRef ModuleString = R"(
                          define i32 @f(i32* %a, i32* %b) {
                          bb0:
                             store i32 1, i32* %a
                             store i32 2, i32* %a
                             ret i32 0
                          })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());
  ASSERT_TRUE(UnsignedVec.size() == 3);
  ASSERT_TRUE(UnsignedVec[0] == UnsignedVec[1]);
}

// Checks that stores that have the different types are mapped to
// different unsigned integers.
TEST(IRInstructionMapper, StoreDifferentType) {
  StringRef ModuleString = R"(
                          define i32 @f(i32* %a, i64* %b) {
                          bb0:
                             store i32 1, i32* %a
                             store i64 1, i64* %b
                             ret i32 0
                          })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());
  ASSERT_TRUE(UnsignedVec.size() == 3);
  ASSERT_TRUE(UnsignedVec[0] != UnsignedVec[1]);
}

// Checks that stores that have the different aligns are mapped to different
// unsigned integers.
TEST(IRInstructionMapper, StoreDifferentAlign) {
  StringRef ModuleString = R"(
                          define i32 @f(i32* %a, i32* %b) {
                          bb0:
                             store i32 1, i32* %a, align 4
                             store i32 1, i32* %b, align 8
                             ret i32 0
                          })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());
  ASSERT_TRUE(UnsignedVec.size() == 3);
  ASSERT_TRUE(UnsignedVec[0] != UnsignedVec[1]);
}

// Checks that stores that have the different volatile settings are mapped to
// different unsigned integers.
TEST(IRInstructionMapper, StoreDifferentVolatile) {
  StringRef ModuleString = R"(
                          define i32 @f(i32* %a, i32* %b) {
                          bb0:
                             store volatile i32 1, i32* %a
                             store i32 1, i32* %b
                             ret i32 0
                          })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());
  ASSERT_TRUE(UnsignedVec.size() == 3);
  ASSERT_TRUE(UnsignedVec[0] != UnsignedVec[1]);
}

// Checks that stores that have the same volatile settings are mapped to
// different unsigned integers.
TEST(IRInstructionMapper, StoreSameVolatile) {
  StringRef ModuleString = R"(
                          define i32 @f(i32* %a, i32* %b) {
                          bb0:
                             store volatile i32 1, i32* %a
                             store volatile i32 1, i32* %b
                             ret i32 0
                          })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());
  ASSERT_TRUE(UnsignedVec.size() == 3);
  ASSERT_TRUE(UnsignedVec[0] == UnsignedVec[1]);
}

// Checks that loads that have the same atomicity settings are mapped to
// different unsigned integers.
TEST(IRInstructionMapper, StoreSameAtomic) {
  StringRef ModuleString = R"(
                          define i32 @f(i32* %a, i32* %b) {
                          bb0:
                             store atomic i32 1, i32* %a unordered, align 4
                             store atomic i32 1, i32* %b unordered, align 4
                             ret i32 0
                          })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());
  ASSERT_TRUE(UnsignedVec.size() == 3);
  ASSERT_TRUE(UnsignedVec[0] == UnsignedVec[1]);
}

// Checks that loads that have the different atomicity settings are mapped to
// different unsigned integers.
TEST(IRInstructionMapper, StoreDifferentAtomic) {
  StringRef ModuleString = R"(
                          define i32 @f(i32* %a, i32* %b) {
                          bb0:
                             store atomic i32 1, i32* %a unordered, align 4
                             store atomic i32 1, i32* %b monotonic, align 4
                             ret i32 0
                          })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());
  ASSERT_TRUE(UnsignedVec.size() == 3);
  ASSERT_TRUE(UnsignedVec[0] != UnsignedVec[1]);
}

// Checks that the branch is mapped to legal when the option is set.
TEST(IRInstructionMapper, BranchLegal) {
  StringRef ModuleString = R"(
                          define i32 @f(i32 %a, i32 %b) {
                          bb0:
                             %0 = icmp slt i32 %a, %b
                             br i1 %0, label %bb0, label %bb1
                          bb1:
                             ret i32 0
                          })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  Mapper.InstClassifier.EnableBranches = true;
  Mapper.initializeForBBs(*M);
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  ASSERT_EQ(InstrList.size(), UnsignedVec.size());
  ASSERT_EQ(UnsignedVec.size(), static_cast<unsigned>(3));
  ASSERT_TRUE(UnsignedVec[1] > UnsignedVec[0]);
  ASSERT_TRUE(UnsignedVec[1] < UnsignedVec[2]);
}

// Checks that a PHINode is mapped to be legal.
TEST(IRInstructionMapper, PhiLegal) {
  StringRef ModuleString = R"(
                          define i32 @f(i32 %a, i32 %b) {
                          bb0:
                             %0 = phi i1 [ 0, %bb0 ], [ %0, %bb1 ]
                             %1 = add i32 %a, %b
                             ret i32 0
                          bb1:
                             ret i32 1
                          })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  Mapper.InstClassifier.EnableBranches = true;
  Mapper.initializeForBBs(*M);
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  ASSERT_EQ(InstrList.size(), UnsignedVec.size());
  ASSERT_EQ(UnsignedVec.size(), static_cast<unsigned>(3));
}

// Checks that a PHINode is mapped to be legal.
TEST(IRInstructionMapper, PhiIllegal) {
  StringRef ModuleString = R"(
                          define i32 @f(i32 %a, i32 %b) {
                          bb0:
                             %0 = phi i1 [ 0, %bb0 ], [ %0, %bb1 ]
                             %1 = add i32 %a, %b
                             ret i32 0
                          bb1:
                             ret i32 1
                          })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  Mapper.initializeForBBs(*M);
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  ASSERT_EQ(InstrList.size(), UnsignedVec.size());
  ASSERT_EQ(UnsignedVec.size(), static_cast<unsigned>(3));
  ASSERT_GT(UnsignedVec[0], Mapper.IllegalInstrNumber);
}

// In most cases, the illegal instructions we are collecting don't require any
// sort of setup.  In these cases, we can just only have illegal instructions,
// and the mapper will create 0 length vectors, and we can check that.

// In cases where we have legal instructions needed to set up the illegal
// instruction, to check illegal instructions are assigned unsigned integers
// from the maximum value decreasing to 0, it will be greater than a legal
// instruction that comes after.  So to check that we have an illegal
// instruction, we place a legal instruction after an illegal instruction, and
// check that the illegal unsigned integer is greater than the unsigned integer
// of the legal instruction.

// Checks that an alloca instruction is mapped to be illegal.
TEST(IRInstructionMapper, AllocaIllegal) {
  StringRef ModuleString = R"(
                          define i32 @f(i32 %a, i32 %b) {
                          bb0:
                             %0 = alloca i32
                             ret i32 0
                          })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  ASSERT_EQ(InstrList.size(), UnsignedVec.size());
  ASSERT_EQ(UnsignedVec.size(), static_cast<unsigned>(1));
  ASSERT_GT(UnsignedVec[0], Mapper.IllegalInstrNumber);
}

// Checks that an getelementptr instruction is mapped to be legal.  And that
// the operands in getelementpointer instructions are the exact same after the
// first element operand, which only requires the same type.
TEST(IRInstructionMapper, GetElementPtrSameEndOperands) {
  StringRef ModuleString = R"(
    %struct.RT = type { i8, [10 x [20 x i32]], i8 }
    %struct.ST = type { i32, double, %struct.RT }
    define i32 @f(%struct.ST* %s, i64 %a, i64 %b) {
    bb0:
       %0 = getelementptr inbounds %struct.ST, %struct.ST* %s, i64 %a, i32 0
       %1 = getelementptr inbounds %struct.ST, %struct.ST* %s, i64 %b, i32 0
       ret i32 0
    })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  ASSERT_EQ(InstrList.size(), UnsignedVec.size());
  ASSERT_EQ(UnsignedVec.size(), static_cast<unsigned>(3));
  ASSERT_EQ(UnsignedVec[0], UnsignedVec[1]);
}

// Check that when the operands in getelementpointer instructions are not the
// exact same after the first element operand, the instructions are mapped to
// different values.
TEST(IRInstructionMapper, GetElementPtrDifferentEndOperands) {
  StringRef ModuleString = R"(
    %struct.RT = type { i8, [10 x [20 x i32]], i8 }
    %struct.ST = type { i32, double, %struct.RT }
    define i32 @f(%struct.ST* %s, i64 %a, i64 %b) {
    bb0:
       %0 = getelementptr inbounds %struct.ST, %struct.ST* %s, i64 %a, i32 0
       %1 = getelementptr inbounds %struct.ST, %struct.ST* %s, i64 %b, i32 2
       ret i32 0
    })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  ASSERT_EQ(InstrList.size(), UnsignedVec.size());
  ASSERT_EQ(UnsignedVec.size(), static_cast<unsigned>(3));
  ASSERT_NE(UnsignedVec[0], UnsignedVec[1]);
}

// Check that when the operands in getelementpointer instructions are not the
// same initial base type, each instruction is mapped to a different value.
TEST(IRInstructionMapper, GetElementPtrDifferentBaseType) {
  StringRef ModuleString = R"(
    %struct.RT = type { i8, [10 x [20 x i32]], i8 }
    %struct.ST = type { i32, double, %struct.RT }
    define i32 @f(%struct.ST* %s, %struct.RT* %r, i64 %a, i64 %b) {
    bb0:
       %0 = getelementptr inbounds %struct.ST, %struct.ST* %s, i64 %a
       %1 = getelementptr inbounds %struct.RT, %struct.RT* %r, i64 %b
       ret i32 0
    })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  ASSERT_EQ(InstrList.size(), UnsignedVec.size());
  ASSERT_EQ(UnsignedVec.size(), static_cast<unsigned>(3));
  ASSERT_NE(UnsignedVec[0], UnsignedVec[1]);
}

// Check that when the operands in getelementpointer instructions do not have
// the same inbounds modifier, they are not counted as the same.
TEST(IRInstructionMapper, GetElementPtrDifferentInBounds) {
  StringRef ModuleString = R"(
    %struct.RT = type { i8, [10 x [20 x i32]], i8 }
    %struct.ST = type { i32, double, %struct.RT }
    define i32 @f(%struct.ST* %s, %struct.RT* %r, i64 %a, i64 %b) {
    bb0:
       %0 = getelementptr inbounds %struct.ST, %struct.ST* %s, i64 %a, i32 0
       %1 = getelementptr %struct.ST, %struct.ST* %s, i64 %b, i32 0
       ret i32 0
    })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  ASSERT_EQ(InstrList.size(), UnsignedVec.size());
  ASSERT_EQ(UnsignedVec.size(), static_cast<unsigned>(3));
  ASSERT_NE(UnsignedVec[0], UnsignedVec[1]);
}

// Checks that indirect call instructions are mapped to be illegal when it is
// specified to disallow them.
TEST(IRInstructionMapper, CallsIllegalIndirect) {
  StringRef ModuleString = R"(
                          define i32 @f(void()* %func) {
                          bb0:
                             call void %func()
                             ret i32 0
                          })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  Mapper.InstClassifier.EnableIndirectCalls = false;
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  ASSERT_EQ(InstrList.size(), UnsignedVec.size());
  ASSERT_EQ(UnsignedVec.size(), static_cast<unsigned>(1));
  ASSERT_GT(UnsignedVec[0], Mapper.IllegalInstrNumber);
}

// Checks that indirect call instructions are mapped to be legal when it is not
// specified to disallow them.
TEST(IRInstructionMapper, CallsLegalIndirect) {
  StringRef ModuleString = R"(
                          define i32 @f(void()* %func) {
                          bb0:
                             call void %func()
                             call void %func()
                             ret i32 0
                          })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  Mapper.InstClassifier.EnableIndirectCalls = true;
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  ASSERT_EQ(InstrList.size(), UnsignedVec.size());
  ASSERT_EQ(UnsignedVec.size(), static_cast<unsigned>(3));
}

// Checks that a call instruction is mapped to be legal.  Here we check that
// a call with the same name, and same types are mapped to the same
// value.
TEST(IRInstructionMapper, CallsSameTypeSameName) {
  StringRef ModuleString = R"(
                          declare i32 @f1(i32, i32)
                          define i32 @f(i32 %a, i32 %b) {
                          bb0:
                             %0 = call i32 @f1(i32 %a, i32 %b)
                             %1 = call i32 @f1(i32 %a, i32 %b)
                             ret i32 0
                          })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  ASSERT_EQ(InstrList.size(), UnsignedVec.size());
  ASSERT_EQ(UnsignedVec.size(), static_cast<unsigned>(3));
  ASSERT_EQ(UnsignedVec[0], UnsignedVec[1]);
}

// Here we check that a calls with different names, but the same arguments types
// are mapped to different value when specified that the name must match.
TEST(IRInstructionMapper, CallsSameArgTypeDifferentNameDisallowed) {
  StringRef ModuleString = R"(
                          declare i32 @f1(i32, i32)
                          declare i32 @f2(i32, i32)
                          define i32 @f(i32 %a, i32 %b) {
                          bb0:
                             %0 = call i32 @f1(i32 %a, i32 %b)
                             %1 = call i32 @f2(i32 %a, i32 %b)
                             ret i32 0
                          })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  Mapper.EnableMatchCallsByName = true;
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  ASSERT_EQ(InstrList.size(), UnsignedVec.size());
  ASSERT_EQ(UnsignedVec.size(), static_cast<unsigned>(3));
  ASSERT_NE(UnsignedVec[0], UnsignedVec[1]);
}

// Here we check that a calls with different names, but the same arguments types
// are mapped to the same value when it is not specifed that they must match.
TEST(IRInstructionMapper, CallsSameArgTypeDifferentName) {
  StringRef ModuleString = R"(
                          declare i32 @f1(i32, i32)
                          declare i32 @f2(i32, i32)
                          define i32 @f(i32 %a, i32 %b) {
                          bb0:
                             %0 = call i32 @f1(i32 %a, i32 %b)
                             %1 = call i32 @f2(i32 %a, i32 %b)
                             ret i32 0
                          })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  Mapper.EnableMatchCallsByName = false;
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  ASSERT_EQ(InstrList.size(), UnsignedVec.size());
  ASSERT_EQ(UnsignedVec.size(), static_cast<unsigned>(3));
  ASSERT_EQ(UnsignedVec[0], UnsignedVec[1]);
}

// Here we check that a calls with different names, and different arguments
// types are mapped to different value.
TEST(IRInstructionMapper, CallsDifferentArgTypeDifferentName) {
  StringRef ModuleString = R"(
                          declare i32 @f1(i32, i32)
                          declare i32 @f2(i32)
                          define i32 @f(i32 %a, i32 %b) {
                          bb0:
                             %0 = call i32 @f1(i32 %a, i32 %b)
                             %1 = call i32 @f2(i32 %a)
                             ret i32 0
                          })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  ASSERT_EQ(InstrList.size(), UnsignedVec.size());
  ASSERT_EQ(UnsignedVec.size(), static_cast<unsigned>(3));
  ASSERT_NE(UnsignedVec[0], UnsignedVec[1]);
}

// Here we check that calls with different names, and different return
// types are mapped to different value.
TEST(IRInstructionMapper, CallsDifferentReturnTypeDifferentName) {
  StringRef ModuleString = R"(
                          declare i64 @f1(i32, i32)
                          declare i32 @f2(i32, i32)
                          define i32 @f(i32 %a, i32 %b) {
                          bb0:
                             %0 = call i64 @f1(i32 %a, i32 %b)
                             %1 = call i32 @f2(i32 %a, i32 %b)
                             ret i32 0
                          })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  ASSERT_EQ(InstrList.size(), UnsignedVec.size());
  ASSERT_EQ(UnsignedVec.size(), static_cast<unsigned>(3));
  ASSERT_NE(UnsignedVec[0], UnsignedVec[1]);
}

// Here we check that calls with the same name, types, and parameters map to the
// same unsigned integer.
TEST(IRInstructionMapper, CallsSameParameters) {
  StringRef ModuleString = R"(
                          declare i32 @f1(i32, i32)
                          define i32 @f(i32 %a, i32 %b) {
                          bb0:
                             %0 = tail call fastcc i32 @f1(i32 %a, i32 %b)
                             %1 = tail call fastcc i32 @f1(i32 %a, i32 %b)
                             ret i32 0
                          })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  ASSERT_EQ(InstrList.size(), UnsignedVec.size());
  ASSERT_EQ(UnsignedVec.size(), static_cast<unsigned>(3));
  ASSERT_EQ(UnsignedVec[0], UnsignedVec[1]);
}

// Here we check that calls with different tail call settings are mapped to
// different values.
TEST(IRInstructionMapper, CallsDifferentTails) {
  StringRef ModuleString = R"(
                          declare i32 @f1(i32, i32)
                          define i32 @f(i32 %a, i32 %b) {
                          bb0:
                             %0 = tail call i32 @f1(i32 %a, i32 %b)
                             %1 = call i32 @f1(i32 %a, i32 %b)
                             ret i32 0
                          })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  ASSERT_EQ(InstrList.size(), UnsignedVec.size());
  ASSERT_EQ(UnsignedVec.size(), static_cast<unsigned>(3));
  ASSERT_NE(UnsignedVec[0], UnsignedVec[1]);
}

// Here we check that calls with different calling convention settings are
// mapped to different values.
TEST(IRInstructionMapper, CallsDifferentCallingConventions) {
  StringRef ModuleString = R"(
                          declare i32 @f1(i32, i32)
                          define i32 @f(i32 %a, i32 %b) {
                          bb0:
                             %0 = call fastcc i32 @f1(i32 %a, i32 %b)
                             %1 = call i32 @f1(i32 %a, i32 %b)
                             ret i32 0
                          })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  ASSERT_EQ(InstrList.size(), UnsignedVec.size());
  ASSERT_EQ(UnsignedVec.size(), static_cast<unsigned>(3));
  ASSERT_NE(UnsignedVec[0], UnsignedVec[1]);
}

// Checks that an invoke instruction is mapped to be illegal. Invoke
// instructions are considered to be illegal because of the change in the
// control flow that is currently not recognized.
TEST(IRInstructionMapper, InvokeIllegal) {
  StringRef ModuleString = R"(
                          define i32 @f(i8 *%gep1, i32 %b) {
                          then:                       
                            invoke i32 undef(i8* undef)
                               to label %invoke unwind label %lpad

                          invoke:
                            unreachable

                          lpad:
                            landingpad { i8*, i32 }
                               catch i8* null
                            unreachable
                          })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  ASSERT_EQ(InstrList.size(), UnsignedVec.size());
  ASSERT_EQ(UnsignedVec.size(), static_cast<unsigned>(1));
  ASSERT_GT(UnsignedVec[0], Mapper.IllegalInstrNumber);
}

// Checks that an callbr instructions are considered to be illegal.  Callbr
// instructions are considered to be illegal because of the change in the
// control flow that is currently not recognized.
TEST(IRInstructionMapper, CallBrInstIllegal) {
  StringRef ModuleString = R"(
  define void @test() {
    fail:
      ret void
  }

  define i32 @f(i32 %a, i32 %b) {
      bb0:
        callbr void asm "xorl $0, $0; jmp ${1:l}", "r,X,~{dirflag},~{fpsr},~{flags}"(i32 %a, i8* blockaddress(@test, %fail)) to label %normal [label %fail]
      fail:
        ret i32 0
      normal:
        ret i32 0
  })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  ASSERT_EQ(InstrList.size(), UnsignedVec.size());
  ASSERT_EQ(UnsignedVec.size(), static_cast<unsigned>(1));
  ASSERT_GT(UnsignedVec[0], Mapper.IllegalInstrNumber);
}

// Checks that an debuginfo records are mapped to be invisible. Since they
// do not semantically change the program, they can be recognized as similar.
TEST(IRInstructionMapper, DebugInfoInvisible) {
  StringRef ModuleString = R"(
                          define i32 @f(i32 %a, i32 %b) {
                          then:
                            %0 = add i32 %a, %b
                              #dbg_value(i32 0, !0, !0, !0)
                            %1 = add i32 %a, %b
                            ret i32 0
                          }

                          !0 = distinct !{!"test\00", i32 10})";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  ASSERT_EQ(InstrList.size(), UnsignedVec.size());
  ASSERT_EQ(UnsignedVec.size(), static_cast<unsigned>(3));
}

// The following are all exception handling intrinsics.  We do not currently
// handle these instruction because they are very context dependent.

// Checks that an eh.typeid.for intrinsic is mapped to be illegal.
TEST(IRInstructionMapper, ExceptionHandlingTypeIdIllegal) {
  StringRef ModuleString = R"(
    @_ZTIi = external constant i8*
    define i32 @f() {
    then:
      %0 = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*))
      ret i32 0
    }

    declare i32 @llvm.eh.typeid.for(i8*))";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  ASSERT_EQ(InstrList.size(), UnsignedVec.size());
  ASSERT_EQ(UnsignedVec.size(), static_cast<unsigned>(1));
  ASSERT_GT(UnsignedVec[0], Mapper.IllegalInstrNumber);
}

// Checks that an eh.exceptioncode intrinsic is mapped to be illegal.
TEST(IRInstructionMapper, ExceptionHandlingExceptionCodeIllegal) {
  StringRef ModuleString = R"(
    define i32 @f(i32 %a, i32 %b) {
    entry:
      %0 = catchswitch within none [label %__except] unwind to caller

    __except:
      %1 = catchpad within %0 [i8* null]
      catchret from %1 to label %__except

    then:
      %2 = call i32 @llvm.eh.exceptioncode(token %1)
      ret i32 0
    }

    declare i32 @llvm.eh.exceptioncode(token))";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  ASSERT_EQ(InstrList.size(), UnsignedVec.size());
  ASSERT_EQ(UnsignedVec.size(), static_cast<unsigned>(1));
  ASSERT_GT(UnsignedVec[0], Mapper.IllegalInstrNumber);
}

// Checks that an eh.unwind intrinsic is mapped to be illegal.
TEST(IRInstructionMapper, ExceptionHandlingUnwindIllegal) {
  StringRef ModuleString = R"(
                          define i32 @f(i32 %a, i32 %b) {
                          entry:
                            call void @llvm.eh.unwind.init()
                            ret i32 0
                          }

                          declare void @llvm.eh.unwind.init())";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  ASSERT_EQ(InstrList.size(), UnsignedVec.size());
  ASSERT_EQ(UnsignedVec.size(), static_cast<unsigned>(1));
  ASSERT_GT(UnsignedVec[0], Mapper.IllegalInstrNumber);
}

// Checks that an eh.exceptionpointer intrinsic is mapped to be illegal.
TEST(IRInstructionMapper, ExceptionHandlingExceptionPointerIllegal) {
  StringRef ModuleString = R"(
                          define i32 @f(i32 %a, i32 %b) {
                          entry:
                            %0 = call i8* @llvm.eh.exceptionpointer.p0i8(i32 0)
                            ret i32 0
                          }

                          declare i8* @llvm.eh.exceptionpointer.p0i8(i32))";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  ASSERT_EQ(InstrList.size(), UnsignedVec.size());
  ASSERT_EQ(UnsignedVec.size(), static_cast<unsigned>(1));
  ASSERT_GT(UnsignedVec[0], Mapper.IllegalInstrNumber);
}

// Checks that a catchpad instruction is mapped to an illegal value.
TEST(IRInstructionMapper, CatchpadIllegal) {
  StringRef ModuleString = R"(
    declare void @llvm.donothing() nounwind readnone

    define void @function() personality i8 3 {
      entry:
        invoke void @llvm.donothing() to label %normal unwind label %exception
      exception:
        %cs1 = catchswitch within none [label %catchpad1] unwind to caller
      catchpad1:
        catchpad within %cs1 []
        br label %normal
      normal:
        ret void
  })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  ASSERT_EQ(InstrList.size(), UnsignedVec.size());
  ASSERT_EQ(UnsignedVec.size(), static_cast<unsigned>(1));
  ASSERT_GT(UnsignedVec[0], Mapper.IllegalInstrNumber);
}

// Checks that a cleanuppad instruction is mapped to an illegal value.
TEST(IRInstructionMapper, CleanuppadIllegal) {
  StringRef ModuleString = R"(
    declare void @llvm.donothing() nounwind readnone

    define void @function() personality i8 3 {
      entry:
        invoke void @llvm.donothing() to label %normal unwind label %exception
      exception:
        %cs1 = catchswitch within none [label %catchpad1] unwind to caller
      catchpad1:
        %clean = cleanuppad within none []
        br label %normal
      normal:
        ret void
  })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  ASSERT_EQ(InstrList.size(), UnsignedVec.size());
  ASSERT_EQ(UnsignedVec.size(), static_cast<unsigned>(1));
  ASSERT_GT(UnsignedVec[0], Mapper.IllegalInstrNumber);
}

// The following three instructions are memory transfer and setting based, which
// are considered illegal since is extra checking needed to handle the address
// space checking.

// Checks that a memset instruction is mapped to an illegal value when
// specified.
TEST(IRInstructionMapper, MemSetIllegal) {
  StringRef ModuleString = R"(
  declare void @llvm.memset.p0i8.i64(i8* nocapture writeonly, i8, i64, i32, i1)

  define i64 @function(i64 %x, i64 %z, i64 %n) {
  entry:
    %pool = alloca [59 x i64], align 4
    %tmp = bitcast [59 x i64]* %pool to i8*
    call void @llvm.memset.p0i8.i64(i8* nonnull %tmp, i8 0, i64 236, i32 4, i1 false)
    %cmp3 = icmp eq i64 %n, 0
    %a = add i64 %x, %z
    %c = add i64 %x, %z
    ret i64 0
  })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  Mapper.InstClassifier.EnableIntrinsics = false;
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  ASSERT_EQ(InstrList.size(), UnsignedVec.size());
  ASSERT_EQ(UnsignedVec.size(), static_cast<unsigned>(7));
  ASSERT_TRUE(UnsignedVec[2] < UnsignedVec[0]);
}

// Checks that a memcpy instruction is mapped to an illegal value  when
// specified.
TEST(IRInstructionMapper, MemCpyIllegal) {
  StringRef ModuleString = R"(
  declare void @llvm.memcpy.p0i8.i64(i8* nocapture writeonly, i8, i64, i32, i1)

  define i64 @function(i64 %x, i64 %z, i64 %n) {
  entry:
    %pool = alloca [59 x i64], align 4
    %tmp = bitcast [59 x i64]* %pool to i8*
    call void @llvm.memcpy.p0i8.i64(i8* nonnull %tmp, i8 0, i64 236, i32 4, i1 false)
    %cmp3 = icmp eq i64 %n, 0
    %a = add i64 %x, %z
    %c = add i64 %x, %z
    ret i64 0
  })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  Mapper.InstClassifier.EnableIntrinsics = false;
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  ASSERT_EQ(InstrList.size(), UnsignedVec.size());
  ASSERT_EQ(UnsignedVec.size(), static_cast<unsigned>(7));
  ASSERT_GT(UnsignedVec[2], UnsignedVec[3]);
  ASSERT_LT(UnsignedVec[2], UnsignedVec[0]);
}

// Checks that a memmove instruction is mapped to an illegal value  when
// specified.
TEST(IRInstructionMapper, MemMoveIllegal) {
  StringRef ModuleString = R"(
  declare void @llvm.memmove.p0i8.i64(i8* nocapture writeonly, i8, i64, i32, i1)

  define i64 @function(i64 %x, i64 %z, i64 %n) {
  entry:
    %pool = alloca [59 x i64], align 4
    %tmp = bitcast [59 x i64]* %pool to i8*
    call void @llvm.memmove.p0i8.i64(i8* nonnull %tmp, i8 0, i64 236, i32 4, i1 false)
    %cmp3 = icmp eq i64 %n, 0
    %a = add i64 %x, %z
    %c = add i64 %x, %z
    ret i64 0
  })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  Mapper.InstClassifier.EnableIntrinsics = false;
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  ASSERT_EQ(InstrList.size(), UnsignedVec.size());
  ASSERT_EQ(UnsignedVec.size(), static_cast<unsigned>(7));
  ASSERT_LT(UnsignedVec[2], UnsignedVec[0]);
}

// Checks that mem* instructions are mapped to an legal value when not
// specified, and that all the intrinsics are marked differently.
TEST(IRInstructionMapper, MemOpsLegal) {
  StringRef ModuleString = R"(
  declare void @llvm.memmove.p0i8.i64(i8* nocapture writeonly, i8, i64, i32, i1)
  declare void @llvm.memcpy.p0i8.i64(i8* nocapture writeonly, i8, i64, i32, i1)
  declare void @llvm.memset.p0i8.i64(i8* nocapture writeonly, i8, i64, i32, i1)

  define i64 @function(i64 %x, i64 %z, i64 %n) {
  entry:
    %pool = alloca [59 x i64], align 4
    %tmp = bitcast [59 x i64]* %pool to i8*
    call void @llvm.memmove.p0i8.i64(i8* nonnull %tmp, i8 0, i64 236, i32 4, i1 false)
    call void @llvm.memcpy.p0i8.i64(i8* nonnull %tmp, i8 0, i64 236, i32 4, i1 false)
    call void @llvm.memset.p0i8.i64(i8* nonnull %tmp, i8 0, i64 236, i32 4, i1 false)
    %cmp3 = icmp eq i64 %n, 0
    %a = add i64 %x, %z
    %c = add i64 %x, %z
    ret i64 0
  })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  Mapper.InstClassifier.EnableIntrinsics = true;
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  ASSERT_EQ(InstrList.size(), UnsignedVec.size());
  ASSERT_EQ(UnsignedVec.size(), static_cast<unsigned>(9));
  ASSERT_LT(UnsignedVec[2], UnsignedVec[3]);
  ASSERT_LT(UnsignedVec[3], UnsignedVec[4]);
  ASSERT_LT(UnsignedVec[4], UnsignedVec[5]);
}

// Checks that a variable argument instructions are mapped to an illegal value.
// We exclude variable argument instructions since variable arguments
// requires extra checking of the argument list.
TEST(IRInstructionMapper, VarArgsIllegal) {
  StringRef ModuleString = R"(
  declare void @llvm.va_start(i8*)
  declare void @llvm.va_copy(i8*, i8*)
  declare void @llvm.va_end(i8*)

  define i32 @func1(i32 %a, double %b, i8* %v, ...) nounwind {
  entry:
    %a.addr = alloca i32, align 4
    %b.addr = alloca double, align 8
    %ap = alloca i8*, align 4
    %c = alloca i32, align 4
    store i32 %a, i32* %a.addr, align 4
    store double %b, double* %b.addr, align 8
    %ap1 = bitcast i8** %ap to i8*
    call void @llvm.va_start(i8* %ap1)
    store double %b, double* %b.addr, align 8
    store double %b, double* %b.addr, align 8
    %0 = va_arg i8** %ap, i32
    store double %b, double* %b.addr, align 8
    store double %b, double* %b.addr, align 8
    call void @llvm.va_copy(i8* %v, i8* %ap1)
    store double %b, double* %b.addr, align 8
    store double %b, double* %b.addr, align 8
    call void @llvm.va_end(i8* %ap1)
    store i32 %0, i32* %c, align 4
    %tmp = load i32, i32* %c, align 4
    ret i32 %tmp
  })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  Mapper.InstClassifier.EnableIntrinsics = false;
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  ASSERT_EQ(InstrList.size(), UnsignedVec.size());
  ASSERT_EQ(UnsignedVec.size(), static_cast<unsigned>(17));
  ASSERT_TRUE(UnsignedVec[7] < UnsignedVec[0]);
  ASSERT_TRUE(UnsignedVec[13] < UnsignedVec[10]);
  ASSERT_TRUE(UnsignedVec[16] < UnsignedVec[13]);
}

// Check the length of adding two illegal instructions one after th other.  We
// should find that only one element is added for each illegal range.
TEST(IRInstructionMapper, RepeatedIllegalLength) {
  StringRef ModuleString = R"(
                          define i32 @f(i32 %a, i32 %b) {
                          bb0:
                             %0 = add i32 %a, %b
                             %1 = mul i32 %a, %b
                             %2 = alloca i32
                             %3 = alloca i32
                             %4 = add i32 %a, %b
                             %5 = mul i32 %a, %b
                             ret i32 0
                          })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  // Check that the size of the unsigned vector and the instruction list are the
  // same as a safety check.
  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());

  // Make sure that the unsigned vector is the expected size.
  ASSERT_TRUE(UnsignedVec.size() == 6);
}

// A helper function that accepts an instruction list from a module made up of
// two blocks of two legal instructions and terminator, and checks them for
// instruction similarity.
static bool longSimCandCompare(std::vector<IRInstructionData *> &InstrList,
                               bool Structure = false, unsigned Length = 2,
                               unsigned StartIdxOne = 0,
                               unsigned StartIdxTwo = 3) {
  std::vector<IRInstructionData *>::iterator Start, End;

  Start = InstrList.begin();
  End = InstrList.begin();

  std::advance(End, StartIdxOne + Length - 1);
  IRSimilarityCandidate Cand1(StartIdxOne, Length, *Start, *End);

  Start = InstrList.begin();
  End = InstrList.begin();

  std::advance(Start, StartIdxTwo);
  std::advance(End, StartIdxTwo + Length - 1);
  IRSimilarityCandidate Cand2(StartIdxTwo, Length, *Start, *End);
  if (Structure)
    return IRSimilarityCandidate::compareStructure(Cand1, Cand2);
  return IRSimilarityCandidate::isSimilar(Cand1, Cand2);
}

// Checks that two adds with commuted operands are considered to be the same
// instructions.
TEST(IRSimilarityCandidate, CheckIdenticalInstructions) {
  StringRef ModuleString = R"(
                          define i32 @f(i32 %a, i32 %b) {
                          bb0:
                             %0 = add i32 %a, %b
                             %1 = add i32 %b, %a
                             ret i32 0
                          })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  // Check to make sure that we have a long enough region.
  ASSERT_EQ(InstrList.size(), static_cast<unsigned>(3));
  // Check that the instructions were added correctly to both vectors.
  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());

  std::vector<IRInstructionData *>::iterator Start, End;
  Start = InstrList.begin();
  End = InstrList.begin();
  std::advance(End, 1);
  IRSimilarityCandidate Cand1(0, 2, *Start, *End);
  IRSimilarityCandidate Cand2(0, 2, *Start, *End);

  ASSERT_TRUE(IRSimilarityCandidate::isSimilar(Cand1, Cand2));
}

// Checks that comparison instructions are found to be similar instructions
// when the operands are flipped and the predicate is also swapped.
TEST(IRSimilarityCandidate, PredicateIsomorphism) {
  StringRef ModuleString = R"(
                          define i32 @f(i32 %a, i32 %b) {
                          bb0:
                             %0 = icmp sgt i32 %a, %b
                             %1 = add i32 %b, %a
                             br label %bb1
                          bb1:
                             %2 = icmp slt i32 %a, %b
                             %3 = add i32 %a, %b
                             ret i32 0
                          })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  ASSERT_TRUE(InstrList.size() > 5);
  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());

  std::vector<IRInstructionData *>::iterator Start, End;
  Start = InstrList.begin();
  End = InstrList.begin();
  
  std::advance(End, 1);
  IRSimilarityCandidate Cand1(0, 2, *Start, *End);

  Start = InstrList.begin();
  End = InstrList.begin();
  
  std::advance(Start, 3);
  std::advance(End, 4);
  IRSimilarityCandidate Cand2(3, 2, *Start, *End);

  ASSERT_TRUE(IRSimilarityCandidate::isSimilar(Cand1, Cand2));
}

// Checks that IRSimilarityCandidates wrapping these two regions of instructions
// are able to differentiate between instructions that have different opcodes.
TEST(IRSimilarityCandidate, CheckRegionsDifferentInstruction) {
  StringRef ModuleString = R"(
                          define i32 @f(i32 %a, i32 %b) {
                          bb0:
                             %0 = add i32 %a, %b
                             %1 = add i32 %b, %a
                             ret i32 0
                          bb1:
                             %2 = sub i32 %a, %b
                             %3 = add i32 %b, %a
                             ret i32 0
                          })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  // Check to make sure that we have a long enough region.
  ASSERT_EQ(InstrList.size(), static_cast<unsigned>(6));
  // Check that the instructions were added correctly to both vectors.
  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());

  ASSERT_FALSE(longSimCandCompare(InstrList));
}

// Checks that IRSimilarityCandidates wrapping these two regions of instructions
// are able to differentiate between instructions that have different types.
TEST(IRSimilarityCandidate, CheckRegionsDifferentTypes) {
  StringRef ModuleString = R"(
                          define i32 @f(i32 %a, i32 %b, i64 %c, i64 %d) {
                          bb0:
                             %0 = add i32 %a, %b
                             %1 = add i32 %b, %a
                             ret i32 0
                          bb1:
                             %2 = add i64 %c, %d
                             %3 = add i64 %d, %c
                             ret i32 0
                          })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  // Check to make sure that we have a long enough region.
  ASSERT_EQ(InstrList.size(), static_cast<unsigned>(6));
  // Check that the instructions were added correctly to both vectors.
  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());

  ASSERT_FALSE(longSimCandCompare(InstrList));
}

// Check that debug records do not impact similarity. They are marked as
// invisible.
TEST(IRSimilarityCandidate, IdenticalWithDebug) {
  StringRef ModuleString = R"(
                          define i32 @f(i32 %a, i32 %b) {
                          bb0:
                             %0 = add i32 %a, %b
                               #dbg_value(i32 0, !0, !0, !0)
                             %1 = add i32 %b, %a
                             ret i32 0
                          bb1:
                             %2 = add i32 %a, %b
                               #dbg_value(i32 1, !1, !1, !1)
                             %3 = add i32 %b, %a
                             ret i32 0
                          bb2:
                             %4 = add i32 %a, %b
                             %5 = add i32 %b, %a
                             ret i32 0       
                          }

                          !0 = distinct !{!"test\00", i32 10}
                          !1 = distinct !{!"test\00", i32 11})";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  // Check to make sure that we have a long enough region.
  ASSERT_EQ(InstrList.size(), static_cast<unsigned>(9));
  // Check that the instructions were added correctly to both vectors.
  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());

  ASSERT_TRUE(longSimCandCompare(InstrList));
}

// Checks that IRSimilarityCandidates that include illegal instructions, are not
// considered to be the same set of instructions.  In these sets of instructions
// the allocas are illegal.
TEST(IRSimilarityCandidate, IllegalInCandidate) {
  StringRef ModuleString = R"(
                          define i32 @f(i32 %a, i32 %b) {
                          bb0:
                             %0 = add i32 %a, %b
                             %1 = add i32 %a, %b
                             %2 = alloca i32
                             ret i32 0
                          bb1:
                             %3 = add i32 %a, %b
                             %4 = add i32 %a, %b
                             %5 = alloca i32
                             ret i32 0
                          })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  // Check to make sure that we have a long enough region.
  ASSERT_EQ(InstrList.size(), static_cast<unsigned>(6));
  // Check that the instructions were added correctly to both vectors.
  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());

  std::vector<IRInstructionData *>::iterator Start, End;

  Start = InstrList.begin();
  End = InstrList.begin();

  std::advance(End, 2);
  IRSimilarityCandidate Cand1(0, 3, *Start, *End);

  Start = InstrList.begin();
  End = InstrList.begin();

  std::advance(Start, 3);
  std::advance(End, 5);
  IRSimilarityCandidate Cand2(3, 3, *Start, *End);
  ASSERT_FALSE(IRSimilarityCandidate::isSimilar(Cand1, Cand2));
}

// Checks that different structure, in this case, where we introduce a new
// needed input in one region, is recognized as different.
TEST(IRSimilarityCandidate, DifferentStructure) {
  StringRef ModuleString = R"(
                          define i32 @f(i32 %a, i32 %b) {
                          bb0:
                             %0 = add i32 %a, %b
                             %1 = add i32 %b, %a
                             ret i32 0
                          bb1:
                             %2 = add i32 %a, %b
                             %3 = add i32 %b, %0
                             ret i32 0
                          })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  // Check to make sure that we have a long enough region.
  ASSERT_EQ(InstrList.size(), static_cast<unsigned>(6));
  // Check that the instructions were added correctly to both vectors.
  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());

  ASSERT_FALSE(longSimCandCompare(InstrList, true));
}

// Checks that comparison instructions are found to have the same structure
// when the operands are flipped and the predicate is also swapped.
TEST(IRSimilarityCandidate, PredicateIsomorphismStructure) {
  StringRef ModuleString = R"(
                          define i32 @f(i32 %a, i32 %b) {
                          bb0:
                             %0 = icmp sgt i32 %a, %b
                             %1 = add i32 %a, %b
                             br label %bb1
                          bb1:
                             %2 = icmp slt i32 %b, %a
                             %3 = add i32 %a, %b
                             ret i32 0
                          })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  ASSERT_TRUE(InstrList.size() > 5);
  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());

  ASSERT_TRUE(longSimCandCompare(InstrList, true));
}

// Checks that different predicates are counted as diferent.
TEST(IRSimilarityCandidate, PredicateDifference) {
  StringRef ModuleString = R"(
                          define i32 @f(i32 %a, i32 %b) {
                          bb0:
                             %0 = icmp sge i32 %a, %b
                             %1 = add i32 %b, %a
                             br label %bb1
                          bb1:
                             %2 = icmp slt i32 %b, %a
                             %3 = add i32 %a, %b
                             ret i32 0
                          })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  ASSERT_TRUE(InstrList.size() > 5);
  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());

  ASSERT_FALSE(longSimCandCompare(InstrList));
}

// Checks that the same structure is recognized between two candidates. The
// items %a and %b are used in the same way in both sets of instructions.
TEST(IRSimilarityCandidate, SameStructure) {
  StringRef ModuleString = R"(
                          define i32 @f(i32 %a, i32 %b) {
                          bb0:
                             %0 = add i32 %a, %b
                             %1 = sub i32 %b, %a
                             ret i32 0
                          bb1:
                             %2 = add i32 %a, %b
                             %3 = sub i32 %b, %a
                             ret i32 0
                          })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  // Check to make sure that we have a long enough region.
  ASSERT_EQ(InstrList.size(), static_cast<unsigned>(6));
  // Check that the instructions were added correctly to both vectors.
  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());

  ASSERT_TRUE(longSimCandCompare(InstrList, true));
}

// Checks that the canonical numbering between two candidates matches the found
// mapping between two candidates.
TEST(IRSimilarityCandidate, CanonicalNumbering) {
  StringRef ModuleString = R"(
                          define i32 @f(i32 %a, i32 %b) {
                          bb0:
                             %0 = add i32 %a, %b
                             %1 = sub i32 %b, %a
                             ret i32 0
                          bb1:
                             %2 = add i32 %a, %b
                             %3 = sub i32 %b, %a
                             ret i32 0
                          })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  // Check to make sure that we have a long enough region.
  ASSERT_EQ(InstrList.size(), static_cast<unsigned>(6));
  // Check that the instructions were added correctly to both vectors.
  ASSERT_EQ(InstrList.size(), UnsignedVec.size());

  std::vector<IRInstructionData *>::iterator Start, End;

  Start = InstrList.begin();
  End = InstrList.begin();

  std::advance(End, 1);
  IRSimilarityCandidate Cand1(0, 2, *Start, *End);

  Start = InstrList.begin();
  End = InstrList.begin();

  std::advance(Start, 3);
  std::advance(End, 4);
  IRSimilarityCandidate Cand2(3, 2, *Start, *End);
  DenseMap<unsigned, DenseSet<unsigned>> Mapping1;
  DenseMap<unsigned, DenseSet<unsigned>> Mapping2;
  ASSERT_TRUE(IRSimilarityCandidate::compareStructure(Cand1, Cand2, Mapping1,
                                                      Mapping2));
  IRSimilarityCandidate::createCanonicalMappingFor(Cand1);
  Cand2.createCanonicalRelationFrom(Cand1, Mapping1, Mapping2);

  for (std::pair<unsigned, DenseSet<unsigned>> &P : Mapping2) {
    unsigned Source = P.first;

    ASSERT_TRUE(Cand2.getCanonicalNum(Source).has_value());
    unsigned Canon = *Cand2.getCanonicalNum(Source);
    ASSERT_TRUE(Cand1.fromCanonicalNum(Canon).has_value());
    unsigned Dest = *Cand1.fromCanonicalNum(Canon);

    DenseSet<unsigned>::iterator It = P.second.find(Dest);
    ASSERT_NE(It, P.second.end());
  }
}

// Checks that the same structure is recognized between two candidates. While
// the input names are reversed, they still perform the same overall operation.
TEST(IRSimilarityCandidate, DifferentNameSameStructure) {
  StringRef ModuleString = R"(
                          define i32 @f(i32 %a, i32 %b) {
                          bb0:
                             %0 = add i32 %a, %b
                             %1 = add i32 %b, %a
                             ret i32 0
                          bb1:
                             %2 = add i32 %b, %a
                             %3 = add i32 %a, %b
                             ret i32 0
                          })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  // Check to make sure that we have a long enough region.
  ASSERT_EQ(InstrList.size(), static_cast<unsigned>(6));
  // Check that the instructions were added correctly to both vectors.
  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());

  ASSERT_TRUE(longSimCandCompare(InstrList, true));
}

// Checks that the same structure is recognized between two candidates when
// the branches target other blocks inside the same region, the relative
// distance between the blocks must be the same.
TEST(IRSimilarityCandidate, SameBranchStructureInternal) {
  StringRef ModuleString = R"(
                          define i32 @f(i32 %a, i32 %b) {
                          bb0:
                             %0 = add i32 %a, %b
                             %1 = add i32 %b, %a
                             br label %bb1
                          bb1:
                             %2 = add i32 %b, %a
                             %3 = add i32 %a, %b
                             ret i32 0
                          }
                          
                          define i32 @f2(i32 %a, i32 %b) {
                          bb0:
                             %0 = add i32 %a, %b
                             %1 = add i32 %b, %a
                             br label %bb1
                          bb1:
                             %2 = add i32 %b, %a
                             %3 = add i32 %a, %b
                             ret i32 0
                          })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  Mapper.InstClassifier.EnableBranches = true;
  Mapper.initializeForBBs(*M);
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  // Check to make sure that we have a long enough region.
  ASSERT_EQ(InstrList.size(), static_cast<unsigned>(12));
  // Check that the instructions were added correctly to both vectors.
  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());

  ASSERT_TRUE(longSimCandCompare(InstrList, true, 5, 0, 6));
}

// Checks that the different structure is recognized between two candidates,
// when the branches target other blocks inside the same region, the relative
// distance between the blocks must be the same.
TEST(IRSimilarityCandidate, DifferentBranchStructureInternal) {
  StringRef ModuleString = R"(
                          define i32 @f(i32 %a, i32 %b) {
                          bb0:
                             %0 = add i32 %a, %b
                             %1 = add i32 %b, %a
                             br label %bb2
                          bb1:
                             %2 = add i32 %b, %a
                             %3 = add i32 %a, %b
                             br label %bb2
                          bb2:
                             %4 = add i32 %b, %a
                             %5 = add i32 %a, %b
                             ret i32 0
                          }
                          
                          define i32 @f2(i32 %a, i32 %b) {
                          bb0:
                             %0 = add i32 %a, %b
                             %1 = add i32 %b, %a
                             br label %bb1
                          bb1:
                             %2 = add i32 %b, %a
                             %3 = add i32 %a, %b
                             br label %bb2
                          bb2:
                             %4 = add i32 %b, %a
                             %5 = add i32 %a, %b
                             ret i32 0
                          })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  Mapper.InstClassifier.EnableBranches = true;
  Mapper.initializeForBBs(*M);
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  // Check to make sure that we have a long enough region.
  ASSERT_EQ(InstrList.size(), static_cast<unsigned>(18));
  // Check that the instructions were added correctly to both vectors.
  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());

  ASSERT_FALSE(longSimCandCompare(InstrList, true, 6, 0, 9));
}

// Checks that the same structure is recognized between two candidates, when
// the branches target other blocks outside region, the relative distance
// does not need to be the same.
TEST(IRSimilarityCandidate, SameBranchStructureOutside) {
  StringRef ModuleString = R"(
                          define i32 @f(i32 %a, i32 %b) {
                          bb0:
                             %0 = add i32 %a, %b
                             %1 = add i32 %b, %a
                             br label %bb1
                          bb1:
                             %2 = add i32 %b, %a
                             %3 = add i32 %a, %b
                             ret i32 0
                          }
                          
                          define i32 @f2(i32 %a, i32 %b) {
                          bb0:
                             %0 = add i32 %a, %b
                             %1 = add i32 %b, %a
                             br label %bb1
                          bb1:
                             %2 = add i32 %b, %a
                             %3 = add i32 %a, %b
                             ret i32 0
                          })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  Mapper.InstClassifier.EnableBranches = true;
  Mapper.initializeForBBs(*M);
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  // Check to make sure that we have a long enough region.
  ASSERT_EQ(InstrList.size(), static_cast<unsigned>(12));
  // Check that the instructions were added correctly to both vectors.
  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());

  ASSERT_TRUE(longSimCandCompare(InstrList, true, 3, 0, 6));
}

// Checks that the same structure is recognized between two candidates, when
// the branches target other blocks outside region, the relative distance
// does not need to be the same.
TEST(IRSimilarityCandidate, DifferentBranchStructureOutside) {
  StringRef ModuleString = R"(
                          define i32 @f(i32 %a, i32 %b) {
                          bb0:
                             %0 = add i32 %a, %b
                             %1 = add i32 %b, %a
                             br label %bb1
                          bb1:
                             %2 = add i32 %b, %a
                             %3 = add i32 %a, %b
                             ret i32 0
                          }
                          
                          define i32 @f2(i32 %a, i32 %b) {
                          bb0:
                             %0 = add i32 %a, %b
                             %1 = add i32 %b, %a
                             br label %bb2
                          bb1:
                             %2 = add i32 %b, %a
                             %3 = add i32 %a, %b
                             br label %bb2
                          bb2:
                             %4 = add i32 %b, %a
                             %5 = add i32 %a, %b
                             ret i32 0
                          })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  Mapper.InstClassifier.EnableBranches = true;
  Mapper.initializeForBBs(*M);
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  // Check to make sure that we have a long enough region.
  ASSERT_EQ(InstrList.size(), static_cast<unsigned>(15));
  // Check that the instructions were added correctly to both vectors.
  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());

  ASSERT_TRUE(longSimCandCompare(InstrList, true, 3, 0, 6));
}

// Checks that the same structure is recognized between two candidates,
// when the phi predecessor are other blocks inside the same region,
// the relative distance between the blocks must be the same.
TEST(IRSimilarityCandidate, SamePHIStructureInternal) {
  StringRef ModuleString = R"(
                          define i32 @f(i32 %a, i32 %b) {
                          bb0:
                             br label %bb2
                          bb1:
                             br label %bb2
                          bb2:
                             %0 = phi i32 [ %a, %bb0 ], [ %b, %bb1 ] 
                             %1 = add i32 %b, %a
                             %2 = add i32 %a, %b
                             ret i32 0
                          }
                          
                          define i32 @f2(i32 %a, i32 %b) {
                          bb0:
                             br label %bb2
                          bb1:
                             br label %bb2
                          bb2:
                             %0 = phi i32 [ %a, %bb0 ], [ %b, %bb1 ]
                             %1 = add i32 %b, %a
                             %2 = add i32 %a, %b
                             ret i32 0
                          })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  Mapper.InstClassifier.EnableBranches = true;
  Mapper.initializeForBBs(*M);
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  // Check to make sure that we have a long enough region.
  ASSERT_EQ(InstrList.size(), static_cast<unsigned>(12));
  // Check that the instructions were added correctly to both vectors.
  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());

  ASSERT_TRUE(longSimCandCompare(InstrList, true, 4, 0, 6));
}

// Checks that the different structure is recognized between two candidates,
// when the phi predecessor are other blocks inside the same region,
// the relative distance between the blocks must be the same.
TEST(IRSimilarityCandidate, DifferentPHIStructureInternal) {
  StringRef ModuleString = R"(
                          define i32 @f(i32 %a, i32 %b) {
                          bb0:
                             br label %bb2
                          bb1:
                             br label %bb2
                          bb3:
                             br label %bb2
                          bb2:
                             %0 = phi i32 [ %a, %bb0 ], [ %b, %bb1 ] 
                             %1 = add i32 %b, %a
                             %2 = add i32 %a, %b
                             ret i32 0
                          }
                          
                          define i32 @f2(i32 %a, i32 %b) {
                          bb0:
                             br label %bb2
                          bb1:
                             br label %bb2
                          bb3:
                             br label %bb2
                          bb2:
                             %0 = phi i32 [ %a, %bb0 ], [ %b, %bb3 ] 
                             %1 = add i32 %b, %a
                             %2 = add i32 %a, %b
                             ret i32 0
                          })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<IRInstructionData *> InstrList;
  std::vector<unsigned> UnsignedVec;

  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
  Mapper.InstClassifier.EnableBranches = true;
  Mapper.initializeForBBs(*M);
  getVectors(*M, Mapper, InstrList, UnsignedVec);

  // Check to make sure that we have a long enough region.
  ASSERT_EQ(InstrList.size(), static_cast<unsigned>(14));
  // Check that the instructions were added correctly to both vectors.
  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());

  ASSERT_FALSE(longSimCandCompare(InstrList, true, 5, 0, 7));
}

// Checks that two sets of identical instructions are found to be the same.
// Both sequences of adds have the same operand ordering, and the same
// instructions, making them strcturally equivalent.
TEST(IRSimilarityIdentifier, IdentitySimilarity) {
  StringRef ModuleString = R"(
                          define i32 @f(i32 %a, i32 %b) {
                          bb0:
                             %0 = add i32 %a, %b
                             %1 = sub i32 %b, %a
                             br label %bb1
                          bb1:
                             %2 = add i32 %a, %b
                             %3 = sub i32 %b, %a
                             ret i32 0
                          })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<std::vector<IRSimilarityCandidate>> SimilarityCandidates;
  getSimilarities(*M, SimilarityCandidates);

  ASSERT_TRUE(SimilarityCandidates.size() == 1);
  for (std::vector<IRSimilarityCandidate> &Cands : SimilarityCandidates) {
    ASSERT_TRUE(Cands.size() == 2);
    unsigned InstIdx = 0;
    for (IRSimilarityCandidate &Cand : Cands) {
      ASSERT_TRUE(Cand.getStartIdx() == InstIdx);
      InstIdx += 3;
    }
  }
}

// Checks that incorrect sequences are not found as similar.  In this case,
// we have different sequences of instructions.
TEST(IRSimilarityIdentifier, InstructionDifference) {
  StringRef ModuleString = R"(
                          define i32 @f(i32 %a, i32 %b, i32 %c, i32 %d) {
                          bb0:
                             %0 = sub i32 %a, %b
                             %1 = add i32 %b, %a
                             br label %bb1
                          bb1:
                             %2 = add i32 %c, %d
                             %3 = sub i32 %d, %c
                             ret i32 0
                          })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<std::vector<IRSimilarityCandidate>> SimilarityCandidates;
  getSimilarities(*M, SimilarityCandidates);

  ASSERT_TRUE(SimilarityCandidates.empty());
}

// This test checks to see whether we can detect similarity for commutative
// instructions where the operands have been reversed.
TEST(IRSimilarityIdentifier, CommutativeSimilarity) {
  StringRef ModuleString = R"(
                          define i32 @f(i32 %a, i32 %b) {
                          bb0:
                             %0 = add i32 %a, %b
                             %1 = add i32 %b, %a
                             br label %bb1
                          bb1:
                             %2 = add i32 %a, %b
                             %3 = add i32 %a, %b
                             ret i32 0
                          })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<std::vector<IRSimilarityCandidate>> SimilarityCandidates;
  getSimilarities(*M, SimilarityCandidates);

  ASSERT_TRUE(SimilarityCandidates.size() == 1);
  for (std::vector<IRSimilarityCandidate> &Cands : SimilarityCandidates) {
    ASSERT_TRUE(Cands.size() == 2);
    unsigned InstIdx = 0;
    for (IRSimilarityCandidate &Cand : Cands) {
      ASSERT_TRUE(Cand.getStartIdx() == InstIdx);
      InstIdx += 3;
    }
  }
}

// This test ensures that when the first instruction in a sequence is
// a commutative instruction with the same value (mcomm_inst_same_val), but the
// corresponding instruction (comm_inst_diff_val) is not, we mark the regions
// and not similar.
TEST(IRSimilarityIdentifier, CommutativeSameValueFirstMisMatch) {
  StringRef ModuleString = R"(
                          define void @v_1_0(i64 %v_33) {
                            entry:
                              %comm_inst_same_val = mul i64 undef, undef
                              %add = add i64 %comm_inst_same_val, %v_33
                              %comm_inst_diff_val = mul i64 0, undef
                              %mul.i = add i64 %comm_inst_diff_val, %comm_inst_diff_val
                              unreachable
                            })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<std::vector<IRSimilarityCandidate>> SimilarityCandidates;
  getSimilarities(*M, SimilarityCandidates);

  ASSERT_TRUE(SimilarityCandidates.size() == 0);
}

// This test makes sure that intrinsic functions that are marked commutative
// are still treated as non-commutative since they are function calls.
TEST(IRSimilarityIdentifier, IntrinsicCommutative) {
  // If treated as commutative, we will fail to find a valid mapping, causing
  // an assertion error.
  StringRef ModuleString = R"(
  define void @foo() {
    entry:
      %0 = call i16 @llvm.smul.fix.i16(i16 16384, i16 16384, i32 15)
      store i16 %0, i16* undef, align 1
      %1 = icmp eq i16 undef, 8192
      call void @bar()
      %2 = call i16 @llvm.smul.fix.i16(i16 -16384, i16 16384, i32 15)
      store i16 %2, i16* undef, align 1
      %3 = icmp eq i16 undef, -8192
      call void @bar()
      %4 = call i16 @llvm.smul.fix.i16(i16 -16384, i16 -16384, i32 15)
      ret void
  }

  declare void @bar()

  ; Function Attrs: nofree nosync nounwind readnone speculatable willreturn
  declare i16 @llvm.smul.fix.i16(i16, i16, i32 immarg))";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<std::vector<IRSimilarityCandidate>> SimilarityCandidates;
  getSimilarities(*M, SimilarityCandidates);

  ASSERT_TRUE(SimilarityCandidates.size() == 0);
}

// This test checks to see whether we can detect different structure in
// commutative instructions.  In this case, the second operand in the second
// add is different.
TEST(IRSimilarityIdentifier, NoCommutativeSimilarity) {
  StringRef ModuleString = R"(
                          define i32 @f(i32 %a, i32 %b) {
                          bb0:
                             %0 = add i32 %a, %b
                             %1 = add i32 %1, %b
                             br label %bb1
                          bb1:
                             %2 = add i32 %a, %b
                             %3 = add i32 %2, %a
                             ret i32 0
                          })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<std::vector<IRSimilarityCandidate>> SimilarityCandidates;
  getSimilarities(*M, SimilarityCandidates);

  ASSERT_TRUE(SimilarityCandidates.size() == 0);
}

// Check that we are not finding similarity in non commutative
// instructions.  That is, while the instruction and operands used are the same
// in the two subtraction sequences, they are in a different order, and cannot
// be counted as the same since a subtraction is not commutative.
TEST(IRSimilarityIdentifier, NonCommutativeDifference) {
  StringRef ModuleString = R"(
                          define i32 @f(i32 %a, i32 %b) {
                          bb0:
                             %0 = sub i32 %a, %b
                             %1 = sub i32 %b, %a
                             br label %bb1
                          bb1:
                             %2 = sub i32 %a, %b
                             %3 = sub i32 %a, %b
                             ret i32 0
                          })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<std::vector<IRSimilarityCandidate>> SimilarityCandidates;
  getSimilarities(*M, SimilarityCandidates);

  ASSERT_TRUE(SimilarityCandidates.empty());
}

// Check that we find similarity despite changing the register names.
TEST(IRSimilarityIdentifier, MappingSimilarity) {
  StringRef ModuleString = R"(
                          define i32 @f(i32 %a, i32 %b, i32 %c, i32 %d) {
                          bb0:
                             %0 = add i32 %a, %b
                             %1 = sub i32 %b, %a
                             br label %bb1
                          bb1:
                             %2 = add i32 %c, %d
                             %3 = sub i32 %d, %c
                             ret i32 0
                          })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<std::vector<IRSimilarityCandidate>> SimilarityCandidates;
  getSimilarities(*M, SimilarityCandidates);

  ASSERT_TRUE(SimilarityCandidates.size() == 1);
  for (std::vector<IRSimilarityCandidate> &Cands : SimilarityCandidates) {
    ASSERT_TRUE(Cands.size() == 2);
    unsigned InstIdx = 0;
    for (IRSimilarityCandidate &Cand : Cands) {
      ASSERT_TRUE(Cand.getStartIdx() == InstIdx);
      InstIdx += 3;
    }
  }
}

// Check that we find instances of swapped predicate isomorphism.  That is,
// for predicates that can be flipped, e.g. greater than to less than,
// we can identify that instances of these different literal predicates, but are
// the same within a single swap can be found.
TEST(IRSimilarityIdentifier, PredicateIsomorphism) {
  StringRef ModuleString = R"(
                          define i32 @f(i32 %a, i32 %b) {
                          bb0:
                             %0 = add i32 %a, %b
                             %1 = icmp sgt i32 %b, %a
                             br label %bb1
                          bb1:
                             %2 = add i32 %a, %b
                             %3 = icmp slt i32 %a, %b
                             ret i32 0
                          })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<std::vector<IRSimilarityCandidate>> SimilarityCandidates;
  getSimilarities(*M, SimilarityCandidates);

  ASSERT_TRUE(SimilarityCandidates.size() == 1);
  for (std::vector<IRSimilarityCandidate> &Cands : SimilarityCandidates) {
    ASSERT_TRUE(Cands.size() == 2);
    unsigned InstIdx = 0;
    for (IRSimilarityCandidate &Cand : Cands) {
      ASSERT_TRUE(Cand.getStartIdx() == InstIdx);
      InstIdx += 3;
    }
  }
}

// Checks that constants are detected as the same operand in each use in the
// sequences of instructions.  Also checks that we can find structural
// equivalence using constants.  In this case the 1 has the same use pattern as
// %a.
TEST(IRSimilarityIdentifier, ConstantMappingSimilarity) {
  StringRef ModuleString = R"(
                          define i32 @f(i32 %a, i32 %b) {
                          bb0:
                             %0 = add i32 1, %b
                             %1 = icmp sgt i32 %b, 1
                             br label %bb1
                          bb1:
                             %2 = add i32 %a, %b
                             %3 = icmp sgt i32 %b, %a
                             ret i32 0
                          })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<std::vector<IRSimilarityCandidate>> SimilarityCandidates;
  getSimilarities(*M, SimilarityCandidates);

  ASSERT_TRUE(SimilarityCandidates.size() == 1);
  for (std::vector<IRSimilarityCandidate> &Cands : SimilarityCandidates) {
    ASSERT_TRUE(Cands.size() == 2);
    unsigned InstIdx = 0;
    for (IRSimilarityCandidate &Cand : Cands) {
      ASSERT_TRUE(Cand.getStartIdx() == InstIdx);
      InstIdx += 3;
    }
  }
}

// Check that constants are uniquely identified. i.e. two different constants
// are not considered the same.  This means that this should not find any
// structural similarity.
TEST(IRSimilarityIdentifier, ConstantMappingDifference) {
  StringRef ModuleString = R"(
                          define i32 @f(i32 %a, i32 %b) {
                          bb0:
                             %0 = add i32 1, %b
                             %1 = icmp sgt i32 %b, 2
                             br label %bb1
                          bb1:
                             %2 = add i32 %a, %b
                             %3 = icmp slt i32 %a, %b
                             ret i32 0
                          })";
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);

  std::vector<std::vector<IRSimilarityCandidate>> SimilarityCandidates;
  getSimilarities(*M, SimilarityCandidates);

  ASSERT_TRUE(SimilarityCandidates.empty());
}
