1 #include "AArch64Subtarget.h"
2 #include "llvm/Support/TargetRegistry.h"
3 #include "llvm/Support/TargetSelect.h"
4 
5 #include "gtest/gtest.h"
6 
7 using namespace llvm;
8 
9 namespace {
10 std::unique_ptr<LLVMTargetMachine> createTargetMachine() {
11   auto TT(Triple::normalize("aarch64--"));
12   std::string CPU("generic");
13   std::string FS("+sme");
14 
15   LLVMInitializeAArch64TargetInfo();
16   LLVMInitializeAArch64Target();
17   LLVMInitializeAArch64TargetMC();
18 
19   std::string Error;
20   const Target *TheTarget = TargetRegistry::lookupTarget(TT, Error);
21 
22   return std::unique_ptr<LLVMTargetMachine>(
23       static_cast<LLVMTargetMachine *>(TheTarget->createTargetMachine(
24           TT, CPU, FS, TargetOptions(), None, None, CodeGenOpt::Default)));
25 }
26 
27 std::unique_ptr<AArch64InstrInfo> createInstrInfo(TargetMachine *TM) {
28   AArch64Subtarget ST(TM->getTargetTriple(), std::string(TM->getTargetCPU()),
29                       std::string(TM->getTargetFeatureString()), *TM,
30                       /* isLittle */ false);
31   return std::make_unique<AArch64InstrInfo>(ST);
32 }
33 
34 TEST(MatrixRegisterAliasing, Aliasing) {
35   std::unique_ptr<LLVMTargetMachine> TM = createTargetMachine();
36   ASSERT_TRUE(TM);
37   std::unique_ptr<AArch64InstrInfo> II = createInstrInfo(TM.get());
38 
39   const AArch64RegisterInfo &TRI = II->getRegisterInfo();
40 
41   // za overlaps with za.b
42   ASSERT_TRUE(TRI.regsOverlap(AArch64::ZA, AArch64::ZAB0));
43 
44   // za0.b overlaps with all tiles
45   ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAB0, AArch64::ZAQ0));
46   ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAB0, AArch64::ZAQ15));
47   ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAB0, AArch64::ZAD0));
48   ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAB0, AArch64::ZAD7));
49   ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAB0, AArch64::ZAS0));
50   ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAB0, AArch64::ZAS3));
51   ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAB0, AArch64::ZAH0));
52   ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAB0, AArch64::ZAH1));
53 
54   // za0.h aliases with za0.q, za2.q, ..
55   ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAH0, AArch64::ZAQ0));
56   ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAH0, AArch64::ZAQ2));
57   ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAH0, AArch64::ZAQ4));
58   ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAH0, AArch64::ZAQ6));
59   ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAH0, AArch64::ZAQ8));
60   ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAH0, AArch64::ZAQ10));
61   ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAH0, AArch64::ZAQ12));
62   ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAH0, AArch64::ZAQ14));
63 
64   // za1.h aliases with za1.q, za3.q, ...
65   ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAH1, AArch64::ZAQ1));
66   ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAH1, AArch64::ZAQ3));
67   ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAH1, AArch64::ZAQ5));
68   ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAH1, AArch64::ZAQ7));
69   ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAH1, AArch64::ZAQ9));
70   ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAH1, AArch64::ZAQ11));
71   ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAH1, AArch64::ZAQ13));
72   ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAH1, AArch64::ZAQ15));
73 
74   // za1.h doesn't alias with za0.q, za2.q, ..
75   ASSERT_FALSE(TRI.regsOverlap(AArch64::ZAH1, AArch64::ZAQ0));
76   ASSERT_FALSE(TRI.regsOverlap(AArch64::ZAH1, AArch64::ZAQ2));
77   ASSERT_FALSE(TRI.regsOverlap(AArch64::ZAH1, AArch64::ZAQ4));
78   ASSERT_FALSE(TRI.regsOverlap(AArch64::ZAH1, AArch64::ZAQ6));
79   ASSERT_FALSE(TRI.regsOverlap(AArch64::ZAH1, AArch64::ZAQ8));
80   ASSERT_FALSE(TRI.regsOverlap(AArch64::ZAH1, AArch64::ZAQ10));
81   ASSERT_FALSE(TRI.regsOverlap(AArch64::ZAH1, AArch64::ZAQ12));
82   ASSERT_FALSE(TRI.regsOverlap(AArch64::ZAH1, AArch64::ZAQ14));
83 
84   // za0.h doesn't alias with za1.q, za3.q, ..
85   ASSERT_FALSE(TRI.regsOverlap(AArch64::ZAH0, AArch64::ZAQ1));
86   ASSERT_FALSE(TRI.regsOverlap(AArch64::ZAH0, AArch64::ZAQ3));
87   ASSERT_FALSE(TRI.regsOverlap(AArch64::ZAH0, AArch64::ZAQ5));
88   ASSERT_FALSE(TRI.regsOverlap(AArch64::ZAH0, AArch64::ZAQ7));
89   ASSERT_FALSE(TRI.regsOverlap(AArch64::ZAH0, AArch64::ZAQ9));
90   ASSERT_FALSE(TRI.regsOverlap(AArch64::ZAH0, AArch64::ZAQ11));
91   ASSERT_FALSE(TRI.regsOverlap(AArch64::ZAH0, AArch64::ZAQ13));
92   ASSERT_FALSE(TRI.regsOverlap(AArch64::ZAH0, AArch64::ZAQ15));
93 
94   // za0.s aliases with za0.q, za4.q, za8.q, za12.q
95   ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAS0, AArch64::ZAQ0));
96   ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAS0, AArch64::ZAQ4));
97   ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAS0, AArch64::ZAQ8));
98   ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAS0, AArch64::ZAQ12));
99 
100   // za1.s aliases with za1.q, za5.q, za9.q, za13.q
101   ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAS1, AArch64::ZAQ1));
102   ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAS1, AArch64::ZAQ5));
103   ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAS1, AArch64::ZAQ9));
104   ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAS1, AArch64::ZAQ13));
105 
106   // za0.s doesn't alias with za1.q, za5.q, za9.q, za13.q
107   ASSERT_FALSE(TRI.regsOverlap(AArch64::ZAS0, AArch64::ZAQ1));
108   ASSERT_FALSE(TRI.regsOverlap(AArch64::ZAS0, AArch64::ZAQ5));
109   ASSERT_FALSE(TRI.regsOverlap(AArch64::ZAS0, AArch64::ZAQ9));
110   ASSERT_FALSE(TRI.regsOverlap(AArch64::ZAS0, AArch64::ZAQ13));
111 
112   // za1.s doesn't alias with za0.q, za4.q, za8.q, za12.q
113   ASSERT_FALSE(TRI.regsOverlap(AArch64::ZAS1, AArch64::ZAQ0));
114   ASSERT_FALSE(TRI.regsOverlap(AArch64::ZAS1, AArch64::ZAQ4));
115   ASSERT_FALSE(TRI.regsOverlap(AArch64::ZAS1, AArch64::ZAQ8));
116   ASSERT_FALSE(TRI.regsOverlap(AArch64::ZAS1, AArch64::ZAQ12));
117 
118   // za0.d aliases za0.q and za8.q
119   ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAD0, AArch64::ZAQ0));
120   ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAD0, AArch64::ZAQ8));
121 
122   // za1.d aliases za1.q and za9.q
123   ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAD1, AArch64::ZAQ1));
124   ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAD1, AArch64::ZAQ9));
125 
126   // za0.d doesn't alias with za1.q and za9.q
127   ASSERT_FALSE(TRI.regsOverlap(AArch64::ZAD0, AArch64::ZAQ1));
128   ASSERT_FALSE(TRI.regsOverlap(AArch64::ZAD0, AArch64::ZAQ9));
129 
130   // za1.d doesn't alias with za0.q and za8.q
131   ASSERT_FALSE(TRI.regsOverlap(AArch64::ZAD1, AArch64::ZAQ0));
132   ASSERT_FALSE(TRI.regsOverlap(AArch64::ZAD1, AArch64::ZAQ8));
133 }
134 
135 } // end anonymous namespace
136