xref: /llvm-project/llvm/unittests/Target/AArch64/AArch64RegisterInfoTest.cpp (revision 318c69de52b61d64d5ea113dc2e9f307f7fd4d51)
1 #include "AArch64RegisterInfo.h"
2 #include "AArch64InstrInfo.h"
3 #include "AArch64Subtarget.h"
4 #include "AArch64TargetMachine.h"
5 #include "llvm/MC/MCSubtargetInfo.h"
6 #include "llvm/MC/TargetRegistry.h"
7 #include "llvm/Support/TargetSelect.h"
8 #include "llvm/Support/raw_ostream.h"
9 #include "llvm/Target/TargetMachine.h"
10 #include "llvm/Target/TargetOptions.h"
11 
12 #include "gtest/gtest.h"
13 
14 #define GET_COMPUTE_FEATURES
15 #include "AArch64GenInstrInfo.inc"
16 
17 using namespace llvm;
18 
19 namespace {
20 
21 std::unique_ptr<TargetMachine> createTargetMachine(const std::string &CPU) {
22   auto TT(Triple::normalize("aarch64--"));
23 
24   LLVMInitializeAArch64TargetInfo();
25   LLVMInitializeAArch64Target();
26   LLVMInitializeAArch64TargetMC();
27 
28   std::string Error;
29   const Target *TheTarget = TargetRegistry::lookupTarget(TT, Error);
30 
31   return std::unique_ptr<TargetMachine>(
32       TheTarget->createTargetMachine(TT, CPU, "", TargetOptions(), std::nullopt,
33                                      std::nullopt, CodeGenOptLevel::Default));
34 }
35 
36 std::unique_ptr<AArch64InstrInfo> createInstrInfo(TargetMachine *TM) {
37   AArch64Subtarget ST(TM->getTargetTriple(), std::string(TM->getTargetCPU()),
38                       std::string(TM->getTargetCPU()),
39                       std::string(TM->getTargetFeatureString()), *TM, true);
40   return std::make_unique<AArch64InstrInfo>(ST);
41 }
42 
43 TEST(AArch64LaneBitmasks, SubRegs) {
44   std::unique_ptr<TargetMachine> TM = createTargetMachine("");
45   ASSERT_TRUE(TM);
46 
47   std::unique_ptr<AArch64InstrInfo> II = createInstrInfo(TM.get());
48   ASSERT_TRUE(II);
49 
50   const AArch64RegisterInfo &TRI = II->getRegisterInfo();
51 
52   // Test that the lane masks for the subregisters 'bsub, hsub, ssub, etc'
53   // are composed correctly.
54   EXPECT_EQ(TRI.getSubRegIndexLaneMask(AArch64::bsub) |
55                 TRI.getSubRegIndexLaneMask(AArch64::bsub_hi),
56             TRI.getSubRegIndexLaneMask(AArch64::hsub));
57 
58   EXPECT_EQ(TRI.getSubRegIndexLaneMask(AArch64::hsub) |
59                 TRI.getSubRegIndexLaneMask(AArch64::hsub_hi),
60             TRI.getSubRegIndexLaneMask(AArch64::ssub));
61 
62   EXPECT_EQ(TRI.getSubRegIndexLaneMask(AArch64::ssub) |
63                 TRI.getSubRegIndexLaneMask(AArch64::ssub_hi),
64             TRI.getSubRegIndexLaneMask(AArch64::dsub));
65 
66   EXPECT_EQ(TRI.getSubRegIndexLaneMask(AArch64::dsub) |
67                 TRI.getSubRegIndexLaneMask(AArch64::dsub_hi),
68             TRI.getSubRegIndexLaneMask(AArch64::zsub));
69 
70   EXPECT_EQ(TRI.getSubRegIndexLaneMask(AArch64::zsub) |
71                 TRI.getSubRegIndexLaneMask(AArch64::zsub_hi),
72             TRI.getSubRegIndexLaneMask(AArch64::zsub0));
73 
74   // Test that the lane masks for tuples are composed correctly.
75   EXPECT_EQ(TRI.getSubRegIndexLaneMask(AArch64::dsub1_then_bsub) |
76                 TRI.getSubRegIndexLaneMask(AArch64::dsub1_then_bsub_hi),
77             TRI.getSubRegIndexLaneMask(AArch64::dsub1_then_hsub));
78 
79   EXPECT_EQ(TRI.getSubRegIndexLaneMask(AArch64::dsub1_then_hsub) |
80                 TRI.getSubRegIndexLaneMask(AArch64::dsub1_then_hsub_hi),
81             TRI.getSubRegIndexLaneMask(AArch64::dsub1_then_ssub));
82 
83   EXPECT_EQ(TRI.getSubRegIndexLaneMask(AArch64::dsub1_then_ssub) |
84                 TRI.getSubRegIndexLaneMask(AArch64::dsub1_then_ssub_hi),
85             TRI.getSubRegIndexLaneMask(AArch64::dsub1));
86 
87   EXPECT_EQ(TRI.getSubRegIndexLaneMask(AArch64::dsub1) |
88                 TRI.getSubRegIndexLaneMask(AArch64::qsub1_then_dsub_hi),
89             TRI.getSubRegIndexLaneMask(AArch64::qsub1));
90 
91   EXPECT_EQ(TRI.getSubRegIndexLaneMask(AArch64::sub_32) |
92                 TRI.getSubRegIndexLaneMask(AArch64::sub_32_hi),
93             TRI.getSubRegIndexLaneMask(AArch64::sube64));
94 
95   EXPECT_EQ(TRI.getSubRegIndexLaneMask(AArch64::subo64_then_sub_32) |
96                 TRI.getSubRegIndexLaneMask(AArch64::subo64_then_sub_32_hi),
97             TRI.getSubRegIndexLaneMask(AArch64::subo64));
98 
99   // Test that there is no overlap between different (sub)registers
100   // in a tuple.
101   EXPECT_EQ(TRI.getSubRegIndexLaneMask(AArch64::dsub0) &
102                 TRI.getSubRegIndexLaneMask(AArch64::dsub1) &
103                 TRI.getSubRegIndexLaneMask(AArch64::dsub2) &
104                 TRI.getSubRegIndexLaneMask(AArch64::dsub3),
105             LaneBitmask::getNone());
106 
107   EXPECT_EQ(TRI.getSubRegIndexLaneMask(AArch64::qsub0) &
108                 TRI.getSubRegIndexLaneMask(AArch64::qsub1) &
109                 TRI.getSubRegIndexLaneMask(AArch64::qsub2) &
110                 TRI.getSubRegIndexLaneMask(AArch64::qsub3),
111             LaneBitmask::getNone());
112 
113   EXPECT_EQ(TRI.getSubRegIndexLaneMask(AArch64::zsub0) &
114                 TRI.getSubRegIndexLaneMask(AArch64::zsub1) &
115                 TRI.getSubRegIndexLaneMask(AArch64::zsub2) &
116                 TRI.getSubRegIndexLaneMask(AArch64::zsub3),
117             LaneBitmask::getNone());
118 
119   EXPECT_EQ(TRI.getSubRegIndexLaneMask(AArch64::sube32) &
120                 TRI.getSubRegIndexLaneMask(AArch64::subo32),
121             LaneBitmask::getNone());
122 
123   EXPECT_EQ(TRI.getSubRegIndexLaneMask(AArch64::sube64) &
124                 TRI.getSubRegIndexLaneMask(AArch64::subo64),
125             LaneBitmask::getNone());
126 
127   // Test that getting a subregister results in the expected subregister.
128   EXPECT_EQ(TRI.getSubReg(AArch64::Z0_Z8, AArch64::bsub), AArch64::B0);
129   EXPECT_EQ(TRI.getSubReg(AArch64::Z0_Z8, AArch64::hsub), AArch64::H0);
130   EXPECT_EQ(TRI.getSubReg(AArch64::Z0_Z8, AArch64::ssub), AArch64::S0);
131   EXPECT_EQ(TRI.getSubReg(AArch64::Z0_Z8, AArch64::dsub), AArch64::D0);
132   EXPECT_EQ(TRI.getSubReg(AArch64::Z0_Z8, AArch64::zsub), AArch64::Q0);
133   EXPECT_EQ(TRI.getSubReg(AArch64::Z0_Z8, AArch64::zsub0), AArch64::Z0);
134 
135   EXPECT_EQ(TRI.getSubReg(AArch64::Z0_Z8, AArch64::dsub1_then_bsub),
136             AArch64::B8);
137   EXPECT_EQ(TRI.getSubReg(AArch64::Z0_Z8, AArch64::dsub1_then_hsub),
138             AArch64::H8);
139   EXPECT_EQ(TRI.getSubReg(AArch64::Z0_Z8, AArch64::dsub1_then_ssub),
140             AArch64::S8);
141   EXPECT_EQ(TRI.getSubReg(AArch64::Z0_Z8, AArch64::dsub1), AArch64::D8);
142   EXPECT_EQ(TRI.getSubReg(AArch64::Z0_Z8, AArch64::qsub1), AArch64::Q8);
143   EXPECT_EQ(TRI.getSubReg(AArch64::Z0_Z8, AArch64::zsub1), AArch64::Z8);
144 
145   EXPECT_EQ(TRI.getSubReg(AArch64::X0_X1, AArch64::sube64), AArch64::X0);
146   EXPECT_EQ(TRI.getSubReg(AArch64::X0_X1, AArch64::subo64), AArch64::X1);
147   EXPECT_EQ(TRI.getSubReg(AArch64::X0_X1, AArch64::sub_32), AArch64::W0);
148   EXPECT_EQ(TRI.getSubReg(AArch64::X0_X1, AArch64::subo64_then_sub_32),
149             AArch64::W1);
150 }
151 
152 } // namespace
153