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