Clement Courbet | 3e13816 | 2019-09-30 12:50:25 +0000 | [diff] [blame] | 1 | //===-- 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 | |
| 22 | namespace llvm { |
| 23 | namespace exegesis { |
| 24 | |
| 25 | void InitializeX86ExegesisTarget(); |
| 26 | |
| 27 | namespace { |
| 28 | |
| 29 | using testing::AllOf; |
| 30 | using testing::ElementsAre; |
| 31 | using testing::Eq; |
| 32 | using testing::Field; |
| 33 | using testing::Property; |
| 34 | using testing::SizeIs; |
| 35 | |
| 36 | class X86SnippetFileTest : public ::testing::Test { |
| 37 | protected: |
| 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 |
| 68 | static auto HasOpcode = [](unsigned Opcode) { |
| 69 | return Property(&MCInst::getOpcode, Eq(Opcode)); |
| 70 | }; |
| 71 | |
| 72 | MATCHER_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 | |
| 82 | TEST_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 | |
| 100 | TEST_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 | |
| 110 | TEST_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 | |
| 120 | TEST_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 |