xref: /llvm-project/llvm/unittests/Target/AArch64/AddressingModes.cpp (revision cd768ec9837afed4d226a5abc8035a1559c18bc5)
16c9066feSMomchil Velikov #include "AArch64Subtarget.h"
26c9066feSMomchil Velikov #include "AArch64TargetMachine.h"
36c9066feSMomchil Velikov #include "llvm/IR/DataLayout.h"
46c9066feSMomchil Velikov #include "llvm/MC/TargetRegistry.h"
56c9066feSMomchil Velikov #include "llvm/Support/TargetSelect.h"
66c9066feSMomchil Velikov 
76c9066feSMomchil Velikov #include "gtest/gtest.h"
86c9066feSMomchil Velikov #include <initializer_list>
96c9066feSMomchil Velikov #include <memory>
106c9066feSMomchil Velikov 
116c9066feSMomchil Velikov using namespace llvm;
126c9066feSMomchil Velikov 
136c9066feSMomchil Velikov namespace {
146c9066feSMomchil Velikov 
156c9066feSMomchil Velikov struct AddrMode : public TargetLowering::AddrMode {
AddrMode__anonb45c0c090111::AddrMode16*cd768ec9SGraham Hunter   constexpr AddrMode(GlobalValue *GV, int64_t Offs, bool HasBase, int64_t S,
17*cd768ec9SGraham Hunter                      int64_t SOffs = 0) {
186c9066feSMomchil Velikov     BaseGV = GV;
196c9066feSMomchil Velikov     BaseOffs = Offs;
206c9066feSMomchil Velikov     HasBaseReg = HasBase;
216c9066feSMomchil Velikov     Scale = S;
22*cd768ec9SGraham Hunter     ScalableOffset = SOffs;
236c9066feSMomchil Velikov   }
246c9066feSMomchil Velikov };
256c9066feSMomchil Velikov struct TestCase {
266c9066feSMomchil Velikov   AddrMode AM;
276c9066feSMomchil Velikov   unsigned TypeBits;
286c9066feSMomchil Velikov   bool Result;
296c9066feSMomchil Velikov };
306c9066feSMomchil Velikov 
316c9066feSMomchil Velikov const std::initializer_list<TestCase> Tests = {
326c9066feSMomchil Velikov     // {BaseGV, BaseOffs, HasBaseReg, Scale}, Bits, Result
336c9066feSMomchil Velikov     {{reinterpret_cast<GlobalValue *>(-1), 0, false, 0}, 64, false},
346c9066feSMomchil Velikov     {{nullptr, 8, true, 1}, 64, false},
356c9066feSMomchil Velikov     {{nullptr, 0, false, 2}, 64, true},
366c9066feSMomchil Velikov     {{nullptr, 0, false, 1}, 64, true},
376c9066feSMomchil Velikov     {{nullptr, 4, false, 0}, 64, false},
386c9066feSMomchil Velikov 
396c9066feSMomchil Velikov     {{nullptr, 0, true, 1}, 64, true},
406c9066feSMomchil Velikov     {{nullptr, 0, true, 1}, 32, true},
416c9066feSMomchil Velikov     {{nullptr, 0, true, 1}, 16, true},
426c9066feSMomchil Velikov     {{nullptr, 0, true, 1}, 8, true},
436c9066feSMomchil Velikov 
446c9066feSMomchil Velikov     {{nullptr, 0, true, 2}, 64, false},
456c9066feSMomchil Velikov     {{nullptr, 0, true, 2}, 32, false},
466c9066feSMomchil Velikov     {{nullptr, 0, true, 2}, 16, true},
476c9066feSMomchil Velikov     {{nullptr, 0, true, 2}, 8, false},
486c9066feSMomchil Velikov     {{nullptr, 0, true, 4}, 64, false},
496c9066feSMomchil Velikov     {{nullptr, 0, true, 4}, 32, true},
506c9066feSMomchil Velikov     {{nullptr, 0, true, 4}, 16, false},
516c9066feSMomchil Velikov     {{nullptr, 0, true, 4}, 8, false},
526c9066feSMomchil Velikov 
536c9066feSMomchil Velikov     {{nullptr, 0, true, 8}, 64, true},
546c9066feSMomchil Velikov     {{nullptr, 0, true, 8}, 32, false},
556c9066feSMomchil Velikov     {{nullptr, 0, true, 8}, 16, false},
566c9066feSMomchil Velikov     {{nullptr, 0, true, 8}, 8, false},
576c9066feSMomchil Velikov 
586c9066feSMomchil Velikov     {{nullptr, 0, true, 16}, 64, false},
596c9066feSMomchil Velikov     {{nullptr, 0, true, 16}, 32, false},
606c9066feSMomchil Velikov     {{nullptr, 0, true, 16}, 16, false},
616c9066feSMomchil Velikov     {{nullptr, 0, true, 16}, 8, false},
626c9066feSMomchil Velikov 
636c9066feSMomchil Velikov     {{nullptr, -257, true, 0}, 64, false},
646c9066feSMomchil Velikov     {{nullptr, -256, true, 0}, 64, true},
656c9066feSMomchil Velikov     {{nullptr, -255, true, 0}, 64, true},
666c9066feSMomchil Velikov     {{nullptr, -1, true, 0}, 64, true},
676c9066feSMomchil Velikov     {{nullptr, 0, true, 0}, 64, true},
686c9066feSMomchil Velikov     {{nullptr, 1, true, 0}, 64, true},
696c9066feSMomchil Velikov     {{nullptr, 254, true, 0}, 64, true},
706c9066feSMomchil Velikov     {{nullptr, 255, true, 0}, 64, true},
716c9066feSMomchil Velikov     {{nullptr, 256, true, 0}, 64, true},
726c9066feSMomchil Velikov     {{nullptr, 257, true, 0}, 64, false},
736c9066feSMomchil Velikov     {{nullptr, 258, true, 0}, 64, false},
746c9066feSMomchil Velikov     {{nullptr, 259, true, 0}, 64, false},
756c9066feSMomchil Velikov     {{nullptr, 260, true, 0}, 64, false},
766c9066feSMomchil Velikov     {{nullptr, 261, true, 0}, 64, false},
776c9066feSMomchil Velikov     {{nullptr, 262, true, 0}, 64, false},
786c9066feSMomchil Velikov     {{nullptr, 263, true, 0}, 64, false},
796c9066feSMomchil Velikov     {{nullptr, 264, true, 0}, 64, true},
806c9066feSMomchil Velikov 
816c9066feSMomchil Velikov     {{nullptr, 4096 * 8 - 8, true, 0}, 64, true},
826c9066feSMomchil Velikov     {{nullptr, 4096 * 8 - 7, true, 0}, 64, false},
836c9066feSMomchil Velikov     {{nullptr, 4096 * 8 - 6, true, 0}, 64, false},
846c9066feSMomchil Velikov     {{nullptr, 4096 * 8 - 5, true, 0}, 64, false},
856c9066feSMomchil Velikov     {{nullptr, 4096 * 8 - 4, true, 0}, 64, false},
866c9066feSMomchil Velikov     {{nullptr, 4096 * 8 - 3, true, 0}, 64, false},
876c9066feSMomchil Velikov     {{nullptr, 4096 * 8 - 2, true, 0}, 64, false},
886c9066feSMomchil Velikov     {{nullptr, 4096 * 8 - 1, true, 0}, 64, false},
896c9066feSMomchil Velikov     {{nullptr, 4096 * 8, true, 0}, 64, false},
906c9066feSMomchil Velikov     {{nullptr, 4096 * 8 + 1, true, 0}, 64, false},
916c9066feSMomchil Velikov     {{nullptr, 4096 * 8 + 2, true, 0}, 64, false},
926c9066feSMomchil Velikov     {{nullptr, 4096 * 8 + 3, true, 0}, 64, false},
936c9066feSMomchil Velikov     {{nullptr, 4096 * 8 + 4, true, 0}, 64, false},
946c9066feSMomchil Velikov     {{nullptr, 4096 * 8 + 5, true, 0}, 64, false},
956c9066feSMomchil Velikov     {{nullptr, 4096 * 8 + 6, true, 0}, 64, false},
966c9066feSMomchil Velikov     {{nullptr, 4096 * 8 + 7, true, 0}, 64, false},
976c9066feSMomchil Velikov     {{nullptr, 4096 * 8 + 8, true, 0}, 64, false},
986c9066feSMomchil Velikov 
996c9066feSMomchil Velikov     {{nullptr, -257, true, 0}, 32, false},
1006c9066feSMomchil Velikov     {{nullptr, -256, true, 0}, 32, true},
1016c9066feSMomchil Velikov     {{nullptr, -255, true, 0}, 32, true},
1026c9066feSMomchil Velikov     {{nullptr, -1, true, 0}, 32, true},
1036c9066feSMomchil Velikov     {{nullptr, 0, true, 0}, 32, true},
1046c9066feSMomchil Velikov     {{nullptr, 1, true, 0}, 32, true},
1056c9066feSMomchil Velikov     {{nullptr, 254, true, 0}, 32, true},
1066c9066feSMomchil Velikov     {{nullptr, 255, true, 0}, 32, true},
1076c9066feSMomchil Velikov     {{nullptr, 256, true, 0}, 32, true},
1086c9066feSMomchil Velikov     {{nullptr, 257, true, 0}, 32, false},
1096c9066feSMomchil Velikov     {{nullptr, 258, true, 0}, 32, false},
1106c9066feSMomchil Velikov     {{nullptr, 259, true, 0}, 32, false},
1116c9066feSMomchil Velikov     {{nullptr, 260, true, 0}, 32, true},
1126c9066feSMomchil Velikov 
1136c9066feSMomchil Velikov     {{nullptr, 4096 * 4 - 4, true, 0}, 32, true},
1146c9066feSMomchil Velikov     {{nullptr, 4096 * 4 - 3, true, 0}, 32, false},
1156c9066feSMomchil Velikov     {{nullptr, 4096 * 4 - 2, true, 0}, 32, false},
1166c9066feSMomchil Velikov     {{nullptr, 4096 * 4 - 1, true, 0}, 32, false},
1176c9066feSMomchil Velikov     {{nullptr, 4096 * 4, true, 0}, 32, false},
1186c9066feSMomchil Velikov     {{nullptr, 4096 * 4 + 1, true, 0}, 32, false},
1196c9066feSMomchil Velikov     {{nullptr, 4096 * 4 + 2, true, 0}, 32, false},
1206c9066feSMomchil Velikov     {{nullptr, 4096 * 4 + 3, true, 0}, 32, false},
1216c9066feSMomchil Velikov     {{nullptr, 4096 * 4 + 4, true, 0}, 32, false},
1226c9066feSMomchil Velikov 
1236c9066feSMomchil Velikov     {{nullptr, -257, true, 0}, 16, false},
1246c9066feSMomchil Velikov     {{nullptr, -256, true, 0}, 16, true},
1256c9066feSMomchil Velikov     {{nullptr, -255, true, 0}, 16, true},
1266c9066feSMomchil Velikov     {{nullptr, -1, true, 0}, 16, true},
1276c9066feSMomchil Velikov     {{nullptr, 0, true, 0}, 16, true},
1286c9066feSMomchil Velikov     {{nullptr, 1, true, 0}, 16, true},
1296c9066feSMomchil Velikov     {{nullptr, 254, true, 0}, 16, true},
1306c9066feSMomchil Velikov     {{nullptr, 255, true, 0}, 16, true},
1316c9066feSMomchil Velikov     {{nullptr, 256, true, 0}, 16, true},
1326c9066feSMomchil Velikov     {{nullptr, 257, true, 0}, 16, false},
1336c9066feSMomchil Velikov     {{nullptr, 258, true, 0}, 16, true},
1346c9066feSMomchil Velikov 
1356c9066feSMomchil Velikov     {{nullptr, 4096 * 2 - 2, true, 0}, 16, true},
1366c9066feSMomchil Velikov     {{nullptr, 4096 * 2 - 1, true, 0}, 16, false},
1376c9066feSMomchil Velikov     {{nullptr, 4096 * 2, true, 0}, 16, false},
1386c9066feSMomchil Velikov     {{nullptr, 4096 * 2 + 1, true, 0}, 16, false},
1396c9066feSMomchil Velikov     {{nullptr, 4096 * 2 + 2, true, 0}, 16, false},
1406c9066feSMomchil Velikov 
1416c9066feSMomchil Velikov     {{nullptr, -257, true, 0}, 8, false},
1426c9066feSMomchil Velikov     {{nullptr, -256, true, 0}, 8, true},
1436c9066feSMomchil Velikov     {{nullptr, -255, true, 0}, 8, true},
1446c9066feSMomchil Velikov     {{nullptr, -1, true, 0}, 8, true},
1456c9066feSMomchil Velikov     {{nullptr, 0, true, 0}, 8, true},
1466c9066feSMomchil Velikov     {{nullptr, 1, true, 0}, 8, true},
1476c9066feSMomchil Velikov     {{nullptr, 254, true, 0}, 8, true},
1486c9066feSMomchil Velikov     {{nullptr, 255, true, 0}, 8, true},
1496c9066feSMomchil Velikov     {{nullptr, 256, true, 0}, 8, true},
1506c9066feSMomchil Velikov     {{nullptr, 257, true, 0}, 8, true},
1516c9066feSMomchil Velikov 
1526c9066feSMomchil Velikov     {{nullptr, 4096 - 2, true, 0}, 8, true},
1536c9066feSMomchil Velikov     {{nullptr, 4096 - 1, true, 0}, 8, true},
1546c9066feSMomchil Velikov     {{nullptr, 4096, true, 0}, 8, false},
1556c9066feSMomchil Velikov     {{nullptr, 4096 + 1, true, 0}, 8, false},
1566c9066feSMomchil Velikov 
1576c9066feSMomchil Velikov };
158*cd768ec9SGraham Hunter 
159*cd768ec9SGraham Hunter struct SVETestCase {
160*cd768ec9SGraham Hunter   AddrMode AM;
161*cd768ec9SGraham Hunter   unsigned TypeBits;
162*cd768ec9SGraham Hunter   unsigned NumElts;
163*cd768ec9SGraham Hunter   bool Result;
164*cd768ec9SGraham Hunter };
165*cd768ec9SGraham Hunter 
166*cd768ec9SGraham Hunter const std::initializer_list<SVETestCase> SVETests = {
167*cd768ec9SGraham Hunter     // {BaseGV, BaseOffs, HasBaseReg, Scale, SOffs}, EltBits, Count, Result
168*cd768ec9SGraham Hunter     // Test immediate range -- [-8,7] vector's worth.
169*cd768ec9SGraham Hunter     // <vscale x 16 x i8>, increment by one vector
170*cd768ec9SGraham Hunter     {{nullptr, 0, true, 0, 16}, 8, 16, true},
171*cd768ec9SGraham Hunter     // <vscale x 4 x i32>, increment by eight vectors
172*cd768ec9SGraham Hunter     {{nullptr, 0, true, 0, 128}, 32, 4, false},
173*cd768ec9SGraham Hunter     // <vscale x 8 x i16>, increment by seven vectors
174*cd768ec9SGraham Hunter     {{nullptr, 0, true, 0, 112}, 16, 8, true},
175*cd768ec9SGraham Hunter     // <vscale x 2 x i64>, decrement by eight vectors
176*cd768ec9SGraham Hunter     {{nullptr, 0, true, 0, -128}, 64, 2, true},
177*cd768ec9SGraham Hunter     // <vscale x 16 x i8>, decrement by nine vectors
178*cd768ec9SGraham Hunter     {{nullptr, 0, true, 0, -144}, 8, 16, false},
179*cd768ec9SGraham Hunter 
180*cd768ec9SGraham Hunter     // Half the size of a vector register, but allowable with extending
181*cd768ec9SGraham Hunter     // loads and truncating stores
182*cd768ec9SGraham Hunter     // <vscale x 8 x i8>, increment by three vectors
183*cd768ec9SGraham Hunter     {{nullptr, 0, true, 0, 24}, 8, 8, true},
184*cd768ec9SGraham Hunter 
185*cd768ec9SGraham Hunter     // Test invalid types or offsets
186*cd768ec9SGraham Hunter     // <vscale x 5 x i32>, increment by one vector (base size > 16B)
187*cd768ec9SGraham Hunter     {{nullptr, 0, true, 0, 20}, 32, 5, false},
188*cd768ec9SGraham Hunter     // <vscale x 8 x i16>, increment by half a vector
189*cd768ec9SGraham Hunter     {{nullptr, 0, true, 0, 8}, 16, 8, false},
190*cd768ec9SGraham Hunter     // <vscale x 3 x i8>, increment by 3 vectors (non-power-of-two)
191*cd768ec9SGraham Hunter     {{nullptr, 0, true, 0, 9}, 8, 3, false},
192*cd768ec9SGraham Hunter 
193*cd768ec9SGraham Hunter     // Scalable and fixed offsets
194*cd768ec9SGraham Hunter     // <vscale x 16 x i8>, increment by 32 then decrement by vscale x 16
195*cd768ec9SGraham Hunter     {{nullptr, 32, true, 0, -16}, 8, 16, false},
196*cd768ec9SGraham Hunter };
1976c9066feSMomchil Velikov } // namespace
1986c9066feSMomchil Velikov 
TEST(AddressingModes,AddressingModes)1996c9066feSMomchil Velikov TEST(AddressingModes, AddressingModes) {
2006c9066feSMomchil Velikov   LLVMInitializeAArch64TargetInfo();
2016c9066feSMomchil Velikov   LLVMInitializeAArch64Target();
2026c9066feSMomchil Velikov   LLVMInitializeAArch64TargetMC();
2036c9066feSMomchil Velikov 
2046c9066feSMomchil Velikov   std::string Error;
2056c9066feSMomchil Velikov   auto TT = Triple::normalize("aarch64");
2066c9066feSMomchil Velikov   const Target *T = TargetRegistry::lookupTarget(TT, Error);
2076c9066feSMomchil Velikov 
2086c9066feSMomchil Velikov   std::unique_ptr<TargetMachine> TM(
2096c9066feSMomchil Velikov       T->createTargetMachine(TT, "generic", "", TargetOptions(), std::nullopt,
2100a1aa6cdSArthur Eubanks                              std::nullopt, CodeGenOptLevel::Default));
2116c9066feSMomchil Velikov   AArch64Subtarget ST(TM->getTargetTriple(), TM->getTargetCPU(),
2126c9066feSMomchil Velikov                       TM->getTargetCPU(), TM->getTargetFeatureString(), *TM,
2136c9066feSMomchil Velikov                       true);
2146c9066feSMomchil Velikov 
2156c9066feSMomchil Velikov   auto *TLI = ST.getTargetLowering();
2166c9066feSMomchil Velikov   DataLayout DL("e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128");
2176c9066feSMomchil Velikov   LLVMContext Ctx;
2186c9066feSMomchil Velikov 
2196c9066feSMomchil Velikov   for (const auto &Test : Tests) {
2206c9066feSMomchil Velikov     Type *Typ = Type::getIntNTy(Ctx, Test.TypeBits);
2216c9066feSMomchil Velikov     ASSERT_EQ(TLI->isLegalAddressingMode(DL, Test.AM, Typ, 0), Test.Result);
2226c9066feSMomchil Velikov   }
223*cd768ec9SGraham Hunter 
224*cd768ec9SGraham Hunter   for (const auto &SVETest : SVETests) {
225*cd768ec9SGraham Hunter     Type *Ty = VectorType::get(Type::getIntNTy(Ctx, SVETest.TypeBits),
226*cd768ec9SGraham Hunter                                ElementCount::getScalable(SVETest.NumElts));
227*cd768ec9SGraham Hunter     ASSERT_EQ(TLI->isLegalAddressingMode(DL, SVETest.AM, Ty, 0),
228*cd768ec9SGraham Hunter               SVETest.Result);
229*cd768ec9SGraham Hunter   }
2306c9066feSMomchil Velikov }
231