//===-- SnippetGeneratorTest.cpp --------------------------------*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//

#include "../Common/AssemblerUtils.h"
#include "LlvmState.h"
#include "MCInstrDescView.h"
#include "ParallelSnippetGenerator.h"
#include "RegisterAliasing.h"
#include "SerialSnippetGenerator.h"
#include "TestBase.h"
#include "X86InstrInfo.h"
#include "llvm/ADT/SetOperations.h"

#include <unordered_set>

namespace llvm {
namespace exegesis {

void InitializeX86ExegesisTarget();

namespace {

using testing::AnyOf;
using testing::ElementsAre;
using testing::Gt;
using testing::HasSubstr;
using testing::IsEmpty;
using testing::Not;
using testing::SizeIs;

MATCHER(IsInvalid, "") { return !arg.isValid(); }
MATCHER(IsReg, "") { return arg.isReg(); }

template <typename SnippetGeneratorT>
class X86SnippetGeneratorTest : public X86TestBase {
protected:
  X86SnippetGeneratorTest() : Generator(State, SnippetGenerator::Options()),
	                      InstrInfo(State.getInstrInfo()) {}

  std::vector<CodeTemplate> checkAndGetCodeTemplates(unsigned Opcode) {
    randomGenerator().seed(0); // Initialize seed.
    const Instruction &Instr = State.getIC().getInstr(Opcode);
    auto CodeTemplateOrError = Generator.generateCodeTemplates(
        &Instr, State.getRATC().emptyRegisters());
    EXPECT_FALSE(CodeTemplateOrError.takeError()); // Valid configuration.
    return std::move(CodeTemplateOrError.get());
  }

  SnippetGeneratorT Generator;
  const MCInstrInfo &InstrInfo;
};

using X86SerialSnippetGeneratorTest = X86SnippetGeneratorTest<SerialSnippetGenerator>;

using X86ParallelSnippetGeneratorTest =
    X86SnippetGeneratorTest<ParallelSnippetGenerator>;

TEST_F(X86SerialSnippetGeneratorTest, ImplicitSelfDependencyThroughImplicitReg) {
  // - ADC16i16
  // - Op0 Explicit Use Immediate
  // - Op1 Implicit Def Reg(AX)
  // - Op2 Implicit Def Reg(EFLAGS)
  // - Op3 Implicit Use Reg(AX)
  // - Op4 Implicit Use Reg(EFLAGS)
  // - Var0 [Op0]
  // - hasAliasingImplicitRegisters (execution is always serial)
  // - hasAliasingRegisters
  const unsigned Opcode = X86::ADC16i16;
  EXPECT_THAT(InstrInfo.get(Opcode).implicit_defs()[0], X86::AX);
  EXPECT_THAT(InstrInfo.get(Opcode).implicit_defs()[1], X86::EFLAGS);
  EXPECT_THAT(InstrInfo.get(Opcode).implicit_uses()[0], X86::AX);
  EXPECT_THAT(InstrInfo.get(Opcode).implicit_uses()[1], X86::EFLAGS);
  const auto CodeTemplates = checkAndGetCodeTemplates(Opcode);
  ASSERT_THAT(CodeTemplates, SizeIs(1));
  const auto &CT = CodeTemplates[0];
  EXPECT_THAT(CT.Execution, ExecutionMode::ALWAYS_SERIAL_IMPLICIT_REGS_ALIAS);
  ASSERT_THAT(CT.Instructions, SizeIs(1));
  const InstructionTemplate &IT = CT.Instructions[0];
  EXPECT_THAT(IT.getOpcode(), Opcode);
  ASSERT_THAT(IT.getVariableValues(), SizeIs(1)); // Imm.
  EXPECT_THAT(IT.getVariableValues()[0], IsInvalid()) << "Immediate is not set";
}

TEST_F(X86SerialSnippetGeneratorTest, ImplicitSelfDependencyThroughTiedRegs) {
  // - ADD16ri
  // - Op0 Explicit Def RegClass(GR16)
  // - Op1 Explicit Use RegClass(GR16) TiedToOp0
  // - Op2 Explicit Use Immediate
  // - Op3 Implicit Def Reg(EFLAGS)
  // - Var0 [Op0,Op1]
  // - Var1 [Op2]
  // - hasTiedRegisters (execution is always serial)
  // - hasAliasingRegisters
  const unsigned Opcode = X86::ADD16ri;
  EXPECT_THAT(InstrInfo.get(Opcode).implicit_defs()[0], X86::EFLAGS);
  const auto CodeTemplates = checkAndGetCodeTemplates(Opcode);
  ASSERT_THAT(CodeTemplates, SizeIs(1));
  const auto &CT = CodeTemplates[0];
  EXPECT_THAT(CT.Execution, ExecutionMode::ALWAYS_SERIAL_TIED_REGS_ALIAS);
  ASSERT_THAT(CT.Instructions, SizeIs(1));
  const InstructionTemplate &IT = CT.Instructions[0];
  EXPECT_THAT(IT.getOpcode(), Opcode);
  ASSERT_THAT(IT.getVariableValues(), SizeIs(2));
  EXPECT_THAT(IT.getVariableValues()[0], IsInvalid()) << "Operand 1 is not set";
  EXPECT_THAT(IT.getVariableValues()[1], IsInvalid()) << "Operand 2 is not set";
}

TEST_F(X86SerialSnippetGeneratorTest, ImplicitSelfDependencyThroughExplicitRegs) {
  // - VXORPSrr
  // - Op0 Explicit Def RegClass(VR128)
  // - Op1 Explicit Use RegClass(VR128)
  // - Op2 Explicit Use RegClass(VR128)
  // - Var0 [Op0]
  // - Var1 [Op1]
  // - Var2 [Op2]
  // - hasAliasingRegisters
  const unsigned Opcode = X86::VXORPSrr;
  const auto CodeTemplates = checkAndGetCodeTemplates(Opcode);
  ASSERT_THAT(CodeTemplates, SizeIs(1));
  const auto &CT = CodeTemplates[0];
  EXPECT_THAT(CT.Execution, ExecutionMode::SERIAL_VIA_EXPLICIT_REGS);
  ASSERT_THAT(CT.Instructions, SizeIs(1));
  const InstructionTemplate &IT = CT.Instructions[0];
  EXPECT_THAT(IT.getOpcode(), Opcode);
  ASSERT_THAT(IT.getVariableValues(), SizeIs(3));
  EXPECT_THAT(IT.getVariableValues(),
              AnyOf(ElementsAre(IsReg(), IsInvalid(), IsReg()),
                    ElementsAre(IsReg(), IsReg(), IsInvalid())))
      << "Op0 is either set to Op1 or to Op2";
}

TEST_F(X86SerialSnippetGeneratorTest,
       ImplicitSelfDependencyThroughExplicitRegsForbidAll) {
  // - VXORPSrr
  // - Op0 Explicit Def RegClass(VR128)
  // - Op1 Explicit Use RegClass(VR128)
  // - Op2 Explicit Use RegClass(VR128)
  // - Var0 [Op0]
  // - Var1 [Op1]
  // - Var2 [Op2]
  // - hasAliasingRegisters
  const unsigned Opcode = X86::VXORPSrr;
  randomGenerator().seed(0); // Initialize seed.
  const Instruction &Instr = State.getIC().getInstr(Opcode);
  auto AllRegisters = State.getRATC().emptyRegisters();
  AllRegisters.flip();
  auto Error =
      Generator.generateCodeTemplates(&Instr, AllRegisters).takeError();
  EXPECT_TRUE((bool)Error);
  consumeError(std::move(Error));
}

TEST_F(X86SerialSnippetGeneratorTest,
       ImplicitSelfDependencyThroughExplicitRegsForbidAlmostAll) {
  // - VXORPSrr
  // - Op0 Explicit Def RegClass(VR128)
  // - Op1 Explicit Use RegClass(VR128)
  // - Op2 Explicit Use RegClass(VR128)
  // - Var0 [Op0]
  // - Var1 [Op1]
  // - Var2 [Op2]
  // - hasAliasingRegisters
  const unsigned Opcode = X86::VXORPSrr;
  randomGenerator().seed(0); // Initialize seed.
  const Instruction &Instr = State.getIC().getInstr(Opcode);
  auto ForbiddenRegisters = State.getRATC().emptyRegisters();
  ForbiddenRegisters.flip();
  ForbiddenRegisters.reset(X86::XMM0);
  auto Error = Generator.generateCodeTemplates(&Instr, ForbiddenRegisters);
  EXPECT_FALSE((bool)Error.takeError());
  auto CodeTemplates = std::move(Error.get());
  ASSERT_THAT(CodeTemplates, SizeIs(Gt(0U))) << "Templates are available";
  for (const auto &CT : CodeTemplates) {
    EXPECT_THAT(CT.Execution, ExecutionMode::SERIAL_VIA_EXPLICIT_REGS);
    ASSERT_THAT(CT.Instructions, SizeIs(1));
    const InstructionTemplate &IT = CT.Instructions[0];
    EXPECT_THAT(IT.getOpcode(), Opcode);
    ASSERT_THAT(IT.getVariableValues(), SizeIs(3));
    for (const auto &Var : IT.getVariableValues()) {
      if (Var.isReg()) {
        EXPECT_FALSE(ForbiddenRegisters[Var.getReg().id()]);
      }
    }
  }
}

TEST_F(X86SerialSnippetGeneratorTest, DependencyThroughOtherOpcode) {
  // - CMP64rr
  // - Op0 Explicit Use RegClass(GR64)
  // - Op1 Explicit Use RegClass(GR64)
  // - Op2 Implicit Def Reg(EFLAGS)
  // - Var0 [Op0]
  // - Var1 [Op1]
  const unsigned Opcode = X86::CMP64rr;
  const auto CodeTemplates = checkAndGetCodeTemplates(Opcode);
  ASSERT_THAT(CodeTemplates, SizeIs(Gt(1U))) << "Many templates are available";
  for (const auto &CT : CodeTemplates) {
    EXPECT_THAT(CT.Execution, ExecutionMode::SERIAL_VIA_NON_MEMORY_INSTR);
    ASSERT_THAT(CT.Instructions, SizeIs(2));
    const InstructionTemplate &IT = CT.Instructions[0];
    EXPECT_THAT(IT.getOpcode(), Opcode);
    ASSERT_THAT(IT.getVariableValues(), SizeIs(2));
    EXPECT_THAT(IT.getVariableValues(),
                AnyOf(ElementsAre(IsReg(), IsInvalid()),
                      ElementsAre(IsInvalid(), IsReg())));
    EXPECT_THAT(CT.Instructions[1].getOpcode(), Not(Opcode));
    // TODO: check that the two instructions alias each other.
  }
}

TEST_F(X86SerialSnippetGeneratorTest, LAHF) {
  // - LAHF
  // - Op0 Implicit Def Reg(AH)
  // - Op1 Implicit Use Reg(EFLAGS)
  const unsigned Opcode = X86::LAHF;
  const auto CodeTemplates = checkAndGetCodeTemplates(Opcode);
  ASSERT_THAT(CodeTemplates, SizeIs(Gt(1U))) << "Many templates are available";
  for (const auto &CT : CodeTemplates) {
    EXPECT_THAT(CT.Execution, ExecutionMode::SERIAL_VIA_NON_MEMORY_INSTR);
    ASSERT_THAT(CT.Instructions, SizeIs(2));
    const InstructionTemplate &IT = CT.Instructions[0];
    EXPECT_THAT(IT.getOpcode(), Opcode);
    ASSERT_THAT(IT.getVariableValues(), SizeIs(0));
  }
}

TEST_F(X86SerialSnippetGeneratorTest, VCVTUSI642SDZrrb_Int) {
  // - VCVTUSI642SDZrrb_Int
  // - Op0 Explicit Def RegClass(VR128X)
  // - Op1 Explicit Use RegClass(VR128X)
  // - Op2 Explicit Use STATIC_ROUNDING
  // - Op2 Explicit Use RegClass(GR64)
  // - Op4 Implicit Use Reg(MXSCR)
  const unsigned Opcode = X86::VCVTUSI642SDZrrb_Int;
  const Instruction &Instr = State.getIC().getInstr(Opcode);
  std::vector<BenchmarkCode> Configs;
  auto Error = Generator.generateConfigurations(
      &Instr, Configs, State.getRATC().emptyRegisters());
  ASSERT_FALSE(Error);
  ASSERT_THAT(Configs, SizeIs(1));
  const BenchmarkCode &BC = Configs[0];
  ASSERT_THAT(BC.Key.Instructions, SizeIs(1));
  ASSERT_TRUE(BC.Key.Instructions[0].getOperand(3).isImm());
}

TEST_F(X86ParallelSnippetGeneratorTest, SerialInstruction) {
  // - CDQ
  // - Op0 Implicit Def Reg(EAX)
  // - Op1 Implicit Def Reg(EDX)
  // - Op2 Implicit Use Reg(EAX)
  // - hasAliasingImplicitRegisters (execution is always serial)
  // - hasAliasingRegisters
  const unsigned Opcode = X86::CDQ;
  const auto CodeTemplates = checkAndGetCodeTemplates(Opcode);
  ASSERT_THAT(CodeTemplates, SizeIs(1));
  const auto &CT = CodeTemplates[0];
  EXPECT_THAT(CT.Info, HasSubstr("serial"));
  EXPECT_THAT(CT.Execution, ExecutionMode::UNKNOWN);
  ASSERT_THAT(CT.Instructions, SizeIs(1));
  const InstructionTemplate &IT = CT.Instructions[0];
  EXPECT_THAT(IT.getOpcode(), Opcode);
  ASSERT_THAT(IT.getVariableValues(), SizeIs(0));
}

TEST_F(X86ParallelSnippetGeneratorTest, ReadAfterWrite_CMOV32rr) {
  // CMOV32rr has tied variables, we enumerate the possible values to execute
  // as many in parallel as possible.

  // - CMOV32rr
  // - Op0 Explicit Def RegClass(GR32)
  // - Op1 Explicit Use RegClass(GR32) TiedToOp0
  // - Op2 Explicit Use RegClass(GR32)
  // - Op3 Explicit Use Immediate
  // - Op3 Implicit Use Reg(EFLAGS)
  // - Var0 [Op0,Op1]
  // - Var1 [Op2]
  // - hasTiedRegisters (execution is always serial)
  // - hasAliasingRegisters
  const unsigned Opcode = X86::CMOV32rr;
  const auto CodeTemplates = checkAndGetCodeTemplates(Opcode);
  ASSERT_THAT(CodeTemplates, SizeIs(2));
  for (const auto &CT : CodeTemplates) {
    EXPECT_THAT(CT.Info, HasSubstr("avoiding Read-After-Write issue"));
    EXPECT_THAT(CT.Execution, ExecutionMode::UNKNOWN);
    ASSERT_GT(CT.Instructions.size(), 1U);
    std::set<MCRegister> AllDefRegisters;
    std::set<MCRegister> AllUseRegisters;
    for (const auto &IT : CT.Instructions) {
      ASSERT_THAT(IT.getVariableValues(), SizeIs(3));
      AllDefRegisters.insert(IT.getVariableValues()[0].getReg());
      AllUseRegisters.insert(IT.getVariableValues()[1].getReg());
    }
    EXPECT_THAT(AllDefRegisters, SizeIs(CT.Instructions.size()))
        << "Each instruction writes to a different register";
    EXPECT_THAT(AllUseRegisters, Not(IsEmpty()))
        << "In total, some other registers are used";
    auto AllDefAndUseRegs = AllUseRegisters;
    llvm::set_intersect(AllDefAndUseRegs, AllDefRegisters); // A := A ^ B
    EXPECT_THAT(AllDefAndUseRegs, IsEmpty())
        << "No instruction uses any register defined by any of the "
           "instructions";
  }
}

TEST_F(X86ParallelSnippetGeneratorTest, ReadAfterWrite_VFMADD132PDr) {
  // VFMADD132PDr has tied variables, we enumerate the possible values
  // to execute as many in parallel as possible.

  // - VFMADD132PDr
  // - Op0 Explicit Def RegClass(XMM)
  // - Op1 Explicit Use RegClass(XMM) TiedToOp0
  // - Op2 Explicit Use RegClass(XMM)
  // - Op3 Explicit Use RegClass(XMM)
  // - Var0 [Op0,Op1]
  // - Var1 [Op2]
  // - Var2 [Op3]
  // - hasTiedRegisters (execution is always serial)
  // - hasAliasingRegisters
  const unsigned Opcode = X86::VFMADD132PDr;
  const auto CodeTemplates = checkAndGetCodeTemplates(Opcode);
  ASSERT_THAT(CodeTemplates, SizeIs(3));
  for (const auto &CT : CodeTemplates) {
    EXPECT_THAT(CT.Info, HasSubstr("avoiding Read-After-Write issue"));
    EXPECT_THAT(CT.Execution, ExecutionMode::UNKNOWN);
    ASSERT_GT(CT.Instructions.size(), 1U);
    std::set<MCRegister> AllDefRegisters;
    std::set<MCRegister> AllUseRegisters;
    for (const auto &IT : CT.Instructions) {
      ASSERT_THAT(IT.getVariableValues(), SizeIs(3));
      AllDefRegisters.insert(IT.getVariableValues()[0].getReg());
      AllUseRegisters.insert(IT.getVariableValues()[1].getReg());
      AllUseRegisters.insert(IT.getVariableValues()[2].getReg());
    }
    EXPECT_THAT(AllDefRegisters, SizeIs(CT.Instructions.size()))
        << "Each instruction writes to a different register";
    EXPECT_THAT(AllUseRegisters, Not(IsEmpty()))
        << "In total, some other registers are used";
    auto AllDefAndUseRegs = AllUseRegisters;
    llvm::set_intersect(AllDefAndUseRegs, AllDefRegisters); // A := A ^ B
    EXPECT_THAT(AllDefAndUseRegs, IsEmpty())
        << "No instruction uses any register defined by any of the "
           "instructions";
  }
}

TEST_F(X86ParallelSnippetGeneratorTest, NoTiedVariables) {
  // CMOV_GR32 has no tied variables, we make sure def and use are different
  // from each other.

  // - CMOV_GR32
  // - Op0 Explicit Def RegClass(GR32)
  // - Op1 Explicit Use RegClass(GR32)
  // - Op2 Explicit Use RegClass(GR32)
  // - Op3 Explicit Use Immediate
  // - Op4 Implicit Use Reg(EFLAGS)
  // - Var0 [Op0]
  // - Var1 [Op1]
  // - Var2 [Op2]
  // - Var3 [Op3]
  // - hasAliasingRegisters
  const unsigned Opcode = X86::CMOV_GR32;
  const auto CodeTemplates = checkAndGetCodeTemplates(Opcode);
  ASSERT_THAT(CodeTemplates, SizeIs(2));
  for (const auto &CT : CodeTemplates) {
    EXPECT_THAT(CT.Info, HasSubstr("no tied variables"));
    EXPECT_THAT(CT.Execution, ExecutionMode::UNKNOWN);
    ASSERT_THAT(CT.Instructions, SizeIs(1));
    const InstructionTemplate &IT = CT.Instructions[0];
    EXPECT_THAT(IT.getOpcode(), Opcode);
    ASSERT_THAT(IT.getVariableValues(), SizeIs(4));
    EXPECT_THAT(IT.getVariableValues()[0].getReg(),
                Not(IT.getVariableValues()[1].getReg()))
        << "Def is different from first Use";
    EXPECT_THAT(IT.getVariableValues()[0].getReg(),
                Not(IT.getVariableValues()[2].getReg()))
        << "Def is different from second Use";
    EXPECT_THAT(IT.getVariableValues()[3], IsInvalid());
  }
}

TEST_F(X86ParallelSnippetGeneratorTest, MemoryUse) {
  // Mov32rm reads from memory.
  // - MOV32rm
  // - Op0 Explicit Def RegClass(GR32)
  // - Op1 Explicit Use Memory RegClass(GR8)
  // - Op2 Explicit Use Memory
  // - Op3 Explicit Use Memory RegClass(GRH8)
  // - Op4 Explicit Use Memory
  // - Op5 Explicit Use Memory RegClass(SEGMENT_REG)
  // - Var0 [Op0]
  // - Var1 [Op1]
  // - Var2 [Op2]
  // - Var3 [Op3]
  // - Var4 [Op4]
  // - Var5 [Op5]
  // - hasMemoryOperands
  // - hasAliasingRegisters
  const unsigned Opcode = X86::MOV32rm;
  const auto CodeTemplates = checkAndGetCodeTemplates(Opcode);
  ASSERT_THAT(CodeTemplates, SizeIs(1));
  for (const auto &CT : CodeTemplates) {
    EXPECT_THAT(CT.Info, HasSubstr("no tied variables"));
    EXPECT_THAT(CT.Execution, ExecutionMode::UNKNOWN);
    ASSERT_THAT(CT.Instructions,
                SizeIs(ParallelSnippetGenerator::kMinNumDifferentAddresses));
    const InstructionTemplate &IT = CT.Instructions[0];
    EXPECT_THAT(IT.getOpcode(), Opcode);
    ASSERT_THAT(IT.getVariableValues(), SizeIs(6));
    EXPECT_EQ(IT.getVariableValues()[2].getImm(), 1);
    EXPECT_FALSE(IT.getVariableValues()[3].getReg().isValid());
    EXPECT_EQ(IT.getVariableValues()[4].getImm(), 0);
    EXPECT_FALSE(IT.getVariableValues()[5].getReg().isValid());
  }
}

TEST_F(X86ParallelSnippetGeneratorTest, MOV16ms) {
  const unsigned Opcode = X86::MOV16ms;
  const Instruction &Instr = State.getIC().getInstr(Opcode);
  std::vector<BenchmarkCode> Benchmarks;
  auto Err = Generator.generateConfigurations(&Instr, Benchmarks,
                                              State.getRATC().emptyRegisters());
  EXPECT_TRUE((bool)Err);
  EXPECT_THAT(toString(std::move(Err)),
              testing::HasSubstr("no available registers"));
}

TEST_F(X86ParallelSnippetGeneratorTest,
       AvoidSerializingThroughImplicitRegisters) {
  // MULX32rr implicitly uses EDX. We should not select that register to avoid
  // serialization.
  const unsigned Opcode = X86::MULX32rr;
  randomGenerator().seed(0); // Initialize seed.
  const Instruction &Instr = State.getIC().getInstr(Opcode);
  // Forbid all registers but RDX/EDX/DX/DH/DL. The only option would be to
  // choose that register, but that would serialize the instruction, so we
  // should be returning an error.
  auto AllRegisters = State.getRATC().emptyRegisters();
  AllRegisters.flip();
  AllRegisters.reset(X86::RDX);
  AllRegisters.reset(X86::EDX);
  AllRegisters.reset(X86::DX);
  AllRegisters.reset(X86::DH);
  AllRegisters.reset(X86::DL);
  auto Err = Generator.generateCodeTemplates(&Instr, AllRegisters);
  EXPECT_FALSE((bool)Err);
  EXPECT_THAT(toString(Err.takeError()),
              testing::HasSubstr("Failed to produce any snippet"));
}

class X86FakeSnippetGenerator : public SnippetGenerator {
public:
  X86FakeSnippetGenerator(const LLVMState &State, const Options &Opts)
      : SnippetGenerator(State, Opts) {}

  const Instruction &getInstr(unsigned Opcode) {
    return State.getIC().getInstr(Opcode);
  }

  InstructionTemplate getInstructionTemplate(unsigned Opcode) {
    return {&getInstr(Opcode)};
  }

private:
  Expected<std::vector<CodeTemplate>>
  generateCodeTemplates(InstructionTemplate, const BitVector &) const override {
    return make_error<StringError>("not implemented", inconvertibleErrorCode());
  }
};

using X86FakeSnippetGeneratorTest = X86SnippetGeneratorTest<X86FakeSnippetGenerator>;

testing::Matcher<const RegisterValue &> IsRegisterValue(unsigned Reg,
                                                        APInt Value) {
  return testing::AllOf(testing::Field(&RegisterValue::Register, Reg),
                        testing::Field(&RegisterValue::Value, Value));
}

TEST_F(X86FakeSnippetGeneratorTest, MemoryUse_Movsb) {
  // MOVSB writes to scratch memory register.
  // - MOVSB
  // - Op0 Explicit Use Memory RegClass(GR8)
  // - Op1 Explicit Use Memory RegClass(GR8)
  // - Op2 Explicit Use Memory RegClass(SEGMENT_REG)
  // - Op3 Implicit Def Reg(EDI)
  // - Op4 Implicit Def Reg(ESI)
  // - Op5 Implicit Use Reg(EDI)
  // - Op6 Implicit Use Reg(ESI)
  // - Op7 Implicit Use Reg(DF)
  // - Var0 [Op0]
  // - Var1 [Op1]
  // - Var2 [Op2]
  // - hasMemoryOperands
  // - hasAliasingImplicitRegisters (execution is always serial)
  // - hasAliasingRegisters
  const unsigned Opcode = X86::MOVSB;
  const Instruction &Instr = State.getIC().getInstr(Opcode);
  std::vector<BenchmarkCode> Benchmarks;
  auto Error = Generator.generateConfigurations(
      &Instr, Benchmarks, State.getRATC().emptyRegisters());
  EXPECT_TRUE((bool)Error);
  consumeError(std::move(Error));
}

TEST_F(X86FakeSnippetGeneratorTest, ComputeRegisterInitialValuesAdd16ri) {
  // ADD16ri:
  // explicit def 0       : reg RegClass=GR16
  // explicit use 1       : reg RegClass=GR16 | TIED_TO:0
  // explicit use 2       : imm
  // implicit def         : EFLAGS
  InstructionTemplate IT = Generator.getInstructionTemplate(X86::ADD16ri);
  IT.getValueFor(IT.getInstr().Variables[0]) = MCOperand::createReg(X86::AX);
  std::vector<InstructionTemplate> Snippet;
  Snippet.push_back(std::move(IT));
  const auto RIV = Generator.computeRegisterInitialValues(Snippet);
  EXPECT_THAT(RIV, ElementsAre(IsRegisterValue(X86::AX, APInt())));
}

TEST_F(X86FakeSnippetGeneratorTest, ComputeRegisterInitialValuesAdd64rr) {
  // ADD64rr:
  //  mov64ri rax, 42
  //  add64rr rax, rax, rbx
  // -> only rbx needs defining.
  std::vector<InstructionTemplate> Snippet;
  {
    InstructionTemplate Mov = Generator.getInstructionTemplate(X86::MOV64ri);
    Mov.getValueFor(Mov.getInstr().Variables[0]) =
        MCOperand::createReg(X86::RAX);
    Mov.getValueFor(Mov.getInstr().Variables[1]) = MCOperand::createImm(42);
    Snippet.push_back(std::move(Mov));
  }
  {
    InstructionTemplate Add = Generator.getInstructionTemplate(X86::ADD64rr);
    Add.getValueFor(Add.getInstr().Variables[0]) =
        MCOperand::createReg(X86::RAX);
    Add.getValueFor(Add.getInstr().Variables[1]) =
        MCOperand::createReg(X86::RBX);
    Snippet.push_back(std::move(Add));
  }

  const auto RIV = Generator.computeRegisterInitialValues(Snippet);
  EXPECT_THAT(RIV, ElementsAre(IsRegisterValue(X86::RBX, APInt())));
}

} // namespace
} // namespace exegesis
} // namespace llvm
