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