blob: 79d0b708274ca56bd8bbfdd060cc7c12306204cb [file] [log] [blame]
Miloš Stojanović0add79a2019-12-16 16:49:09 +01001//===-- SnippetGeneratorTest.cpp --------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "../Common/AssemblerUtils.h"
10#include "Latency.h"
11#include "LlvmState.h"
12#include "MCInstrDescView.h"
13#include "RegisterAliasing.h"
14#include "MipsInstrInfo.h"
15
16#include <unordered_set>
17
18namespace llvm {
19namespace exegesis {
20
21void InitializeMipsExegesisTarget();
22
23namespace {
24
25using testing::AnyOf;
26using testing::ElementsAre;
27using testing::SizeIs;
28
29MATCHER(IsInvalid, "") { return !arg.isValid(); }
30MATCHER(IsReg, "") { return arg.isReg(); }
31
32class MipsSnippetGeneratorTest : public ::testing::Test {
33protected:
34 MipsSnippetGeneratorTest() : State("mips-unknown-linux", "mips32"),
35 InstrInfo(State.getInstrInfo()) {}
36
37 static void SetUpTestCase() {
38 LLVMInitializeMipsTargetInfo();
39 LLVMInitializeMipsTarget();
40 LLVMInitializeMipsTargetMC();
41 InitializeMipsExegesisTarget();
42 }
43
44 LLVMState State;
45 const MCInstrInfo &InstrInfo;
46};
47
48template <typename SnippetGeneratorT>
49class SnippetGeneratorTest : public MipsSnippetGeneratorTest {
50protected:
51 SnippetGeneratorTest() : Generator(State, SnippetGenerator::Options()) {}
52
53 std::vector<CodeTemplate> checkAndGetCodeTemplates(unsigned Opcode) {
54 randomGenerator().seed(0); // Initialize seed.
55 const Instruction &Instr = State.getIC().getInstr(Opcode);
56 auto CodeTemplateOrError = Generator.generateCodeTemplates(
57 Instr, State.getRATC().emptyRegisters());
58 EXPECT_FALSE(CodeTemplateOrError.takeError()); // Valid configuration.
59 return std::move(CodeTemplateOrError.get());
60 }
61
62 SnippetGeneratorT Generator;
63};
64
65using LatencySnippetGeneratorTest =
66 SnippetGeneratorTest<LatencySnippetGenerator>;
67
68TEST_F(LatencySnippetGeneratorTest, ImplicitSelfDependencyThroughExplicitRegs) {
69 // - ADD
70 // - Op0 Explicit Def RegClass(GPR32)
71 // - Op1 Explicit Use RegClass(GPR32)
72 // - Op2 Explicit Use RegClass(GPR32)
73 // - Var0 [Op0]
74 // - Var1 [Op1]
75 // - Var2 [Op2]
76 const unsigned Opcode = Mips::ADD;
77 const auto CodeTemplates = checkAndGetCodeTemplates(Opcode);
78 ASSERT_THAT(CodeTemplates, SizeIs(1));
79 const auto &CT = CodeTemplates[0];
80 EXPECT_THAT(CT.Execution, ExecutionMode::SERIAL_VIA_EXPLICIT_REGS);
81 ASSERT_THAT(CT.Instructions, SizeIs(1));
82 const InstructionTemplate &IT = CT.Instructions[0];
83 EXPECT_THAT(IT.getOpcode(), Opcode);
84 ASSERT_THAT(IT.VariableValues, SizeIs(3));
85 EXPECT_THAT(IT.VariableValues,
86 AnyOf(ElementsAre(IsReg(), IsInvalid(), IsReg()),
87 ElementsAre(IsReg(), IsReg(), IsInvalid())))
88 << "Op0 is either set to Op1 or to Op2";
89}
90
91TEST_F(LatencySnippetGeneratorTest,
92 ImplicitSelfDependencyThroughExplicitRegsForbidAll) {
93 // - XOR
94 // - Op0 Explicit Def RegClass(GPR32)
95 // - Op1 Explicit Use RegClass(GPR32)
96 // - Op2 Explicit Use RegClass(GPR32)
97 // - Var0 [Op0]
98 // - Var1 [Op1]
99 // - Var2 [Op2]
100 randomGenerator().seed(0); // Initialize seed.
101 const Instruction &Instr = State.getIC().getInstr(Mips::XOR);
102 auto AllRegisters = State.getRATC().emptyRegisters();
103 AllRegisters.flip();
104 auto Error = Generator.generateCodeTemplates(Instr, AllRegisters).takeError();
105 EXPECT_TRUE((bool)Error);
106 consumeError(std::move(Error));
107}
108
109} // namespace
110} // namespace exegesis
111} // namespace llvm