xref: /llvm-project/llvm/unittests/tools/llvm-exegesis/X86/RegisterAliasingTest.cpp (revision 32401afd8cb86680afa1bc93e732b5fbc5a83401)
1 #include "RegisterAliasing.h"
2 
3 #include <cassert>
4 #include <memory>
5 
6 #include "X86InstrInfo.h"
7 #include "llvm/Support/TargetRegistry.h"
8 #include "llvm/Support/TargetSelect.h"
9 #include "gmock/gmock.h"
10 #include "gtest/gtest.h"
11 
12 namespace llvm {
13 namespace exegesis {
14 namespace {
15 
16 class RegisterAliasingTest : public ::testing::Test {
17 protected:
18   RegisterAliasingTest() {
19     const std::string TT = "x86_64-unknown-linux";
20     std::string error;
21     const llvm::Target *const TheTarget =
22         llvm::TargetRegistry::lookupTarget(TT, error);
23     if (!TheTarget) {
24       llvm::errs() << error << "\n";
25       return;
26     }
27     MCRegInfo.reset(TheTarget->createMCRegInfo(TT));
28   }
29 
30   static void SetUpTestCase() {
31     LLVMInitializeX86TargetInfo();
32     LLVMInitializeX86Target();
33     LLVMInitializeX86TargetMC();
34   }
35 
36   const llvm::MCRegisterInfo &getMCRegInfo() {
37     assert(MCRegInfo);
38     return *MCRegInfo;
39   }
40 
41 private:
42   std::unique_ptr<const llvm::MCRegisterInfo> MCRegInfo;
43 };
44 
45 TEST_F(RegisterAliasingTest, TrackSimpleRegister) {
46   const auto &RegInfo = getMCRegInfo();
47   const RegisterAliasingTracker tracker(RegInfo, llvm::X86::EAX);
48   std::set<llvm::MCPhysReg> ActualAliasedRegisters;
49   for (unsigned I : tracker.aliasedBits().set_bits())
50     ActualAliasedRegisters.insert(static_cast<llvm::MCPhysReg>(I));
51   const std::set<llvm::MCPhysReg> ExpectedAliasedRegisters = {
52       llvm::X86::AL,  llvm::X86::AH,  llvm::X86::AX,
53       llvm::X86::EAX, llvm::X86::HAX, llvm::X86::RAX};
54   ASSERT_THAT(ActualAliasedRegisters, ExpectedAliasedRegisters);
55   for (llvm::MCPhysReg aliased : ExpectedAliasedRegisters) {
56     ASSERT_THAT(tracker.getOrigin(aliased), llvm::X86::EAX);
57   }
58 }
59 
60 TEST_F(RegisterAliasingTest, TrackRegisterClass) {
61   // The alias bits for GR8_ABCD_LRegClassID are the union of the alias bits for
62   // AL, BL, CL and DL.
63   const auto &RegInfo = getMCRegInfo();
64   const llvm::BitVector NoReservedReg(RegInfo.getNumRegs());
65 
66   const RegisterAliasingTracker RegClassTracker(
67       RegInfo, NoReservedReg,
68       RegInfo.getRegClass(llvm::X86::GR8_ABCD_LRegClassID));
69 
70   llvm::BitVector sum(RegInfo.getNumRegs());
71   sum |= RegisterAliasingTracker(RegInfo, llvm::X86::AL).aliasedBits();
72   sum |= RegisterAliasingTracker(RegInfo, llvm::X86::BL).aliasedBits();
73   sum |= RegisterAliasingTracker(RegInfo, llvm::X86::CL).aliasedBits();
74   sum |= RegisterAliasingTracker(RegInfo, llvm::X86::DL).aliasedBits();
75 
76   ASSERT_THAT(RegClassTracker.aliasedBits(), sum);
77 }
78 
79 TEST_F(RegisterAliasingTest, TrackRegisterClassCache) {
80   // Fetching twice the same tracker yields the same pointers.
81   const auto &RegInfo = getMCRegInfo();
82   const llvm::BitVector NoReservedReg(RegInfo.getNumRegs());
83   RegisterAliasingTrackerCache Cache(RegInfo, NoReservedReg);
84   ASSERT_THAT(&Cache.getRegister(llvm::X86::AX),
85               &Cache.getRegister(llvm::X86::AX));
86 
87   ASSERT_THAT(&Cache.getRegisterClass(llvm::X86::GR8_ABCD_LRegClassID),
88               &Cache.getRegisterClass(llvm::X86::GR8_ABCD_LRegClassID));
89 }
90 
91 } // namespace
92 } // namespace exegesis
93 } // namespace llvm
94