blob: d4773fc134d67084749357088c65b2d53d02fcde [file] [log] [blame]
Clement Courbet3e138162019-09-30 12:50:25 +00001//===-- SnippetFileTest.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 "SnippetFile.h"
10
11#include "LlvmState.h"
12#include "X86InstrInfo.h"
13#include "llvm/Support/Error.h"
14#include "llvm/Support/FileSystem.h"
15#include "llvm/Support/Path.h"
16#include "llvm/Support/TargetRegistry.h"
17#include "llvm/Support/TargetSelect.h"
18#include "llvm/Support/raw_ostream.h"
19#include "gmock/gmock.h"
20#include "gtest/gtest.h"
21
22namespace llvm {
23namespace exegesis {
24
25void InitializeX86ExegesisTarget();
26
27namespace {
28
29using testing::AllOf;
30using testing::ElementsAre;
31using testing::Eq;
32using testing::Field;
33using testing::Property;
34using testing::SizeIs;
35
36class X86SnippetFileTest : public ::testing::Test {
37protected:
38 X86SnippetFileTest() : State("x86_64-unknown-linux", "haswell") {}
39
40 static void SetUpTestCase() {
41 LLVMInitializeX86TargetInfo();
42 LLVMInitializeX86TargetMC();
43 LLVMInitializeX86Target();
44 LLVMInitializeX86AsmPrinter();
45 LLVMInitializeX86AsmParser();
46 InitializeX86ExegesisTarget();
47 }
48
49 Expected<std::vector<BenchmarkCode>> TestCommon(StringRef Contents) {
50 SmallString<64> Filename;
51 std::error_code EC;
52 EC = sys::fs::createUniqueDirectory("SnippetFileTestDir", Filename);
53 EXPECT_FALSE(EC);
54 sys::path::append(Filename, "snippet.s");
55 errs() << Filename << "-------\n";
56 {
57 raw_fd_ostream FOS(Filename, EC);
58 FOS << Contents;
59 EXPECT_FALSE(EC);
60 }
61 return readSnippets(State, Filename);
62 }
63
64 const LLVMState State;
65};
66
67// FIXME: Refactor these to ../Common/Matchers.h
68static auto HasOpcode = [](unsigned Opcode) {
69 return Property(&MCInst::getOpcode, Eq(Opcode));
70};
71
72MATCHER_P2(RegisterInitialValueIs, Reg, Val, "") {
73 if (arg.Register == Reg &&
74 arg.Value.getLimitedValue() == static_cast<uint64_t>(Val))
75 return true;
76 *result_listener << "expected: {" << Reg << ", " << Val << "} ";
77 *result_listener << "actual: {" << arg.Register << ", "
78 << arg.Value.getLimitedValue() << "}";
79 return false;
80}
81
82TEST_F(X86SnippetFileTest, Works) {
83 auto Snippets = TestCommon(R"(
84 # LLVM-EXEGESIS-DEFREG RAX 0f
85 # LLVM-EXEGESIS-DEFREG SIL 0
86 # LLVM-EXEGESIS-LIVEIN RDI
87 # LLVM-EXEGESIS-LIVEIN DL
88 incq %rax
89 )");
90 EXPECT_FALSE((bool)Snippets.takeError());
91 ASSERT_THAT(*Snippets, SizeIs(1));
92 const auto &Snippet = (*Snippets)[0];
93 ASSERT_THAT(Snippet.Instructions, ElementsAre(HasOpcode(X86::INC64r)));
94 ASSERT_THAT(Snippet.RegisterInitialValues,
95 ElementsAre(RegisterInitialValueIs(X86::RAX, 15),
96 RegisterInitialValueIs(X86::SIL, 0)));
97 ASSERT_THAT(Snippet.LiveIns, ElementsAre(X86::RDI, X86::DL));
98}
99
100TEST_F(X86SnippetFileTest, BadDefregParam) {
101 auto Error = TestCommon(R"(
102 # LLVM-EXEGESIS-DEFREG DOESNOEXIST 0
103 incq %rax
104 )")
105 .takeError();
106 EXPECT_TRUE((bool)Error);
107 consumeError(std::move(Error));
108}
109
110TEST_F(X86SnippetFileTest, NoDefregValue) {
111 auto Error = TestCommon(R"(
112 # LLVM-EXEGESIS-DEFREG RAX
113 incq %rax
114 )")
115 .takeError();
116 EXPECT_TRUE((bool)Error);
117 consumeError(std::move(Error));
118}
119
120TEST_F(X86SnippetFileTest, MissingParam) {
121 auto Error = TestCommon(R"(
122 # LLVM-EXEGESIS-LIVEIN
123 incq %rax
124 )")
125 .takeError();
126 EXPECT_TRUE((bool)Error);
127 consumeError(std::move(Error));
128}
129
130} // namespace
131} // namespace exegesis
132} // namespace llvm