xref: /llvm-project/llvm/unittests/Target/AArch64/AddressingModes.cpp (revision cd768ec9837afed4d226a5abc8035a1559c18bc5)
1 #include "AArch64Subtarget.h"
2 #include "AArch64TargetMachine.h"
3 #include "llvm/IR/DataLayout.h"
4 #include "llvm/MC/TargetRegistry.h"
5 #include "llvm/Support/TargetSelect.h"
6 
7 #include "gtest/gtest.h"
8 #include <initializer_list>
9 #include <memory>
10 
11 using namespace llvm;
12 
13 namespace {
14 
15 struct AddrMode : public TargetLowering::AddrMode {
AddrMode__anonb45c0c090111::AddrMode16   constexpr AddrMode(GlobalValue *GV, int64_t Offs, bool HasBase, int64_t S,
17                      int64_t SOffs = 0) {
18     BaseGV = GV;
19     BaseOffs = Offs;
20     HasBaseReg = HasBase;
21     Scale = S;
22     ScalableOffset = SOffs;
23   }
24 };
25 struct TestCase {
26   AddrMode AM;
27   unsigned TypeBits;
28   bool Result;
29 };
30 
31 const std::initializer_list<TestCase> Tests = {
32     // {BaseGV, BaseOffs, HasBaseReg, Scale}, Bits, Result
33     {{reinterpret_cast<GlobalValue *>(-1), 0, false, 0}, 64, false},
34     {{nullptr, 8, true, 1}, 64, false},
35     {{nullptr, 0, false, 2}, 64, true},
36     {{nullptr, 0, false, 1}, 64, true},
37     {{nullptr, 4, false, 0}, 64, false},
38 
39     {{nullptr, 0, true, 1}, 64, true},
40     {{nullptr, 0, true, 1}, 32, true},
41     {{nullptr, 0, true, 1}, 16, true},
42     {{nullptr, 0, true, 1}, 8, true},
43 
44     {{nullptr, 0, true, 2}, 64, false},
45     {{nullptr, 0, true, 2}, 32, false},
46     {{nullptr, 0, true, 2}, 16, true},
47     {{nullptr, 0, true, 2}, 8, false},
48     {{nullptr, 0, true, 4}, 64, false},
49     {{nullptr, 0, true, 4}, 32, true},
50     {{nullptr, 0, true, 4}, 16, false},
51     {{nullptr, 0, true, 4}, 8, false},
52 
53     {{nullptr, 0, true, 8}, 64, true},
54     {{nullptr, 0, true, 8}, 32, false},
55     {{nullptr, 0, true, 8}, 16, false},
56     {{nullptr, 0, true, 8}, 8, false},
57 
58     {{nullptr, 0, true, 16}, 64, false},
59     {{nullptr, 0, true, 16}, 32, false},
60     {{nullptr, 0, true, 16}, 16, false},
61     {{nullptr, 0, true, 16}, 8, false},
62 
63     {{nullptr, -257, true, 0}, 64, false},
64     {{nullptr, -256, true, 0}, 64, true},
65     {{nullptr, -255, true, 0}, 64, true},
66     {{nullptr, -1, true, 0}, 64, true},
67     {{nullptr, 0, true, 0}, 64, true},
68     {{nullptr, 1, true, 0}, 64, true},
69     {{nullptr, 254, true, 0}, 64, true},
70     {{nullptr, 255, true, 0}, 64, true},
71     {{nullptr, 256, true, 0}, 64, true},
72     {{nullptr, 257, true, 0}, 64, false},
73     {{nullptr, 258, true, 0}, 64, false},
74     {{nullptr, 259, true, 0}, 64, false},
75     {{nullptr, 260, true, 0}, 64, false},
76     {{nullptr, 261, true, 0}, 64, false},
77     {{nullptr, 262, true, 0}, 64, false},
78     {{nullptr, 263, true, 0}, 64, false},
79     {{nullptr, 264, true, 0}, 64, true},
80 
81     {{nullptr, 4096 * 8 - 8, true, 0}, 64, true},
82     {{nullptr, 4096 * 8 - 7, true, 0}, 64, false},
83     {{nullptr, 4096 * 8 - 6, true, 0}, 64, false},
84     {{nullptr, 4096 * 8 - 5, true, 0}, 64, false},
85     {{nullptr, 4096 * 8 - 4, true, 0}, 64, false},
86     {{nullptr, 4096 * 8 - 3, true, 0}, 64, false},
87     {{nullptr, 4096 * 8 - 2, true, 0}, 64, false},
88     {{nullptr, 4096 * 8 - 1, true, 0}, 64, false},
89     {{nullptr, 4096 * 8, true, 0}, 64, false},
90     {{nullptr, 4096 * 8 + 1, true, 0}, 64, false},
91     {{nullptr, 4096 * 8 + 2, true, 0}, 64, false},
92     {{nullptr, 4096 * 8 + 3, true, 0}, 64, false},
93     {{nullptr, 4096 * 8 + 4, true, 0}, 64, false},
94     {{nullptr, 4096 * 8 + 5, true, 0}, 64, false},
95     {{nullptr, 4096 * 8 + 6, true, 0}, 64, false},
96     {{nullptr, 4096 * 8 + 7, true, 0}, 64, false},
97     {{nullptr, 4096 * 8 + 8, true, 0}, 64, false},
98 
99     {{nullptr, -257, true, 0}, 32, false},
100     {{nullptr, -256, true, 0}, 32, true},
101     {{nullptr, -255, true, 0}, 32, true},
102     {{nullptr, -1, true, 0}, 32, true},
103     {{nullptr, 0, true, 0}, 32, true},
104     {{nullptr, 1, true, 0}, 32, true},
105     {{nullptr, 254, true, 0}, 32, true},
106     {{nullptr, 255, true, 0}, 32, true},
107     {{nullptr, 256, true, 0}, 32, true},
108     {{nullptr, 257, true, 0}, 32, false},
109     {{nullptr, 258, true, 0}, 32, false},
110     {{nullptr, 259, true, 0}, 32, false},
111     {{nullptr, 260, true, 0}, 32, true},
112 
113     {{nullptr, 4096 * 4 - 4, true, 0}, 32, true},
114     {{nullptr, 4096 * 4 - 3, true, 0}, 32, false},
115     {{nullptr, 4096 * 4 - 2, true, 0}, 32, false},
116     {{nullptr, 4096 * 4 - 1, true, 0}, 32, false},
117     {{nullptr, 4096 * 4, true, 0}, 32, false},
118     {{nullptr, 4096 * 4 + 1, true, 0}, 32, false},
119     {{nullptr, 4096 * 4 + 2, true, 0}, 32, false},
120     {{nullptr, 4096 * 4 + 3, true, 0}, 32, false},
121     {{nullptr, 4096 * 4 + 4, true, 0}, 32, false},
122 
123     {{nullptr, -257, true, 0}, 16, false},
124     {{nullptr, -256, true, 0}, 16, true},
125     {{nullptr, -255, true, 0}, 16, true},
126     {{nullptr, -1, true, 0}, 16, true},
127     {{nullptr, 0, true, 0}, 16, true},
128     {{nullptr, 1, true, 0}, 16, true},
129     {{nullptr, 254, true, 0}, 16, true},
130     {{nullptr, 255, true, 0}, 16, true},
131     {{nullptr, 256, true, 0}, 16, true},
132     {{nullptr, 257, true, 0}, 16, false},
133     {{nullptr, 258, true, 0}, 16, true},
134 
135     {{nullptr, 4096 * 2 - 2, true, 0}, 16, true},
136     {{nullptr, 4096 * 2 - 1, true, 0}, 16, false},
137     {{nullptr, 4096 * 2, true, 0}, 16, false},
138     {{nullptr, 4096 * 2 + 1, true, 0}, 16, false},
139     {{nullptr, 4096 * 2 + 2, true, 0}, 16, false},
140 
141     {{nullptr, -257, true, 0}, 8, false},
142     {{nullptr, -256, true, 0}, 8, true},
143     {{nullptr, -255, true, 0}, 8, true},
144     {{nullptr, -1, true, 0}, 8, true},
145     {{nullptr, 0, true, 0}, 8, true},
146     {{nullptr, 1, true, 0}, 8, true},
147     {{nullptr, 254, true, 0}, 8, true},
148     {{nullptr, 255, true, 0}, 8, true},
149     {{nullptr, 256, true, 0}, 8, true},
150     {{nullptr, 257, true, 0}, 8, true},
151 
152     {{nullptr, 4096 - 2, true, 0}, 8, true},
153     {{nullptr, 4096 - 1, true, 0}, 8, true},
154     {{nullptr, 4096, true, 0}, 8, false},
155     {{nullptr, 4096 + 1, true, 0}, 8, false},
156 
157 };
158 
159 struct SVETestCase {
160   AddrMode AM;
161   unsigned TypeBits;
162   unsigned NumElts;
163   bool Result;
164 };
165 
166 const std::initializer_list<SVETestCase> SVETests = {
167     // {BaseGV, BaseOffs, HasBaseReg, Scale, SOffs}, EltBits, Count, Result
168     // Test immediate range -- [-8,7] vector's worth.
169     // <vscale x 16 x i8>, increment by one vector
170     {{nullptr, 0, true, 0, 16}, 8, 16, true},
171     // <vscale x 4 x i32>, increment by eight vectors
172     {{nullptr, 0, true, 0, 128}, 32, 4, false},
173     // <vscale x 8 x i16>, increment by seven vectors
174     {{nullptr, 0, true, 0, 112}, 16, 8, true},
175     // <vscale x 2 x i64>, decrement by eight vectors
176     {{nullptr, 0, true, 0, -128}, 64, 2, true},
177     // <vscale x 16 x i8>, decrement by nine vectors
178     {{nullptr, 0, true, 0, -144}, 8, 16, false},
179 
180     // Half the size of a vector register, but allowable with extending
181     // loads and truncating stores
182     // <vscale x 8 x i8>, increment by three vectors
183     {{nullptr, 0, true, 0, 24}, 8, 8, true},
184 
185     // Test invalid types or offsets
186     // <vscale x 5 x i32>, increment by one vector (base size > 16B)
187     {{nullptr, 0, true, 0, 20}, 32, 5, false},
188     // <vscale x 8 x i16>, increment by half a vector
189     {{nullptr, 0, true, 0, 8}, 16, 8, false},
190     // <vscale x 3 x i8>, increment by 3 vectors (non-power-of-two)
191     {{nullptr, 0, true, 0, 9}, 8, 3, false},
192 
193     // Scalable and fixed offsets
194     // <vscale x 16 x i8>, increment by 32 then decrement by vscale x 16
195     {{nullptr, 32, true, 0, -16}, 8, 16, false},
196 };
197 } // namespace
198 
TEST(AddressingModes,AddressingModes)199 TEST(AddressingModes, AddressingModes) {
200   LLVMInitializeAArch64TargetInfo();
201   LLVMInitializeAArch64Target();
202   LLVMInitializeAArch64TargetMC();
203 
204   std::string Error;
205   auto TT = Triple::normalize("aarch64");
206   const Target *T = TargetRegistry::lookupTarget(TT, Error);
207 
208   std::unique_ptr<TargetMachine> TM(
209       T->createTargetMachine(TT, "generic", "", TargetOptions(), std::nullopt,
210                              std::nullopt, CodeGenOptLevel::Default));
211   AArch64Subtarget ST(TM->getTargetTriple(), TM->getTargetCPU(),
212                       TM->getTargetCPU(), TM->getTargetFeatureString(), *TM,
213                       true);
214 
215   auto *TLI = ST.getTargetLowering();
216   DataLayout DL("e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128");
217   LLVMContext Ctx;
218 
219   for (const auto &Test : Tests) {
220     Type *Typ = Type::getIntNTy(Ctx, Test.TypeBits);
221     ASSERT_EQ(TLI->isLegalAddressingMode(DL, Test.AM, Typ, 0), Test.Result);
222   }
223 
224   for (const auto &SVETest : SVETests) {
225     Type *Ty = VectorType::get(Type::getIntNTy(Ctx, SVETest.TypeBits),
226                                ElementCount::getScalable(SVETest.NumElts));
227     ASSERT_EQ(TLI->isLegalAddressingMode(DL, SVETest.AM, Ty, 0),
228               SVETest.Result);
229   }
230 }
231