#include "AArch64Subtarget.h" #include "llvm/MC/TargetRegistry.h" #include "llvm/Support/TargetSelect.h" #include "gtest/gtest.h" using namespace llvm; namespace { std::unique_ptr createTargetMachine() { auto TT(Triple::normalize("aarch64--")); std::string CPU("generic"); std::string FS("+sme"); LLVMInitializeAArch64TargetInfo(); LLVMInitializeAArch64Target(); LLVMInitializeAArch64TargetMC(); std::string Error; const Target *TheTarget = TargetRegistry::lookupTarget(TT, Error); return std::unique_ptr( TheTarget->createTargetMachine(TT, CPU, FS, TargetOptions(), std::nullopt, std::nullopt, CodeGenOptLevel::Default)); } std::unique_ptr createInstrInfo(TargetMachine *TM) { AArch64Subtarget ST(TM->getTargetTriple(), std::string(TM->getTargetCPU()), std::string(TM->getTargetCPU()), std::string(TM->getTargetFeatureString()), *TM, /* isLittle */ false); return std::make_unique(ST); } TEST(MatrixRegisterAliasing, Aliasing) { std::unique_ptr TM = createTargetMachine(); ASSERT_TRUE(TM); std::unique_ptr II = createInstrInfo(TM.get()); const AArch64RegisterInfo &TRI = II->getRegisterInfo(); // za overlaps with za.b ASSERT_TRUE(TRI.regsOverlap(AArch64::ZA, AArch64::ZAB0)); // za0.b overlaps with all tiles ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAB0, AArch64::ZAQ0)); ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAB0, AArch64::ZAQ15)); ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAB0, AArch64::ZAD0)); ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAB0, AArch64::ZAD7)); ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAB0, AArch64::ZAS0)); ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAB0, AArch64::ZAS3)); ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAB0, AArch64::ZAH0)); ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAB0, AArch64::ZAH1)); // za0.h aliases with za0.q, za2.q, .. ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAH0, AArch64::ZAQ0)); ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAH0, AArch64::ZAQ2)); ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAH0, AArch64::ZAQ4)); ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAH0, AArch64::ZAQ6)); ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAH0, AArch64::ZAQ8)); ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAH0, AArch64::ZAQ10)); ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAH0, AArch64::ZAQ12)); ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAH0, AArch64::ZAQ14)); // za1.h aliases with za1.q, za3.q, ... ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAH1, AArch64::ZAQ1)); ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAH1, AArch64::ZAQ3)); ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAH1, AArch64::ZAQ5)); ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAH1, AArch64::ZAQ7)); ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAH1, AArch64::ZAQ9)); ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAH1, AArch64::ZAQ11)); ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAH1, AArch64::ZAQ13)); ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAH1, AArch64::ZAQ15)); // za1.h doesn't alias with za0.q, za2.q, .. ASSERT_FALSE(TRI.regsOverlap(AArch64::ZAH1, AArch64::ZAQ0)); ASSERT_FALSE(TRI.regsOverlap(AArch64::ZAH1, AArch64::ZAQ2)); ASSERT_FALSE(TRI.regsOverlap(AArch64::ZAH1, AArch64::ZAQ4)); ASSERT_FALSE(TRI.regsOverlap(AArch64::ZAH1, AArch64::ZAQ6)); ASSERT_FALSE(TRI.regsOverlap(AArch64::ZAH1, AArch64::ZAQ8)); ASSERT_FALSE(TRI.regsOverlap(AArch64::ZAH1, AArch64::ZAQ10)); ASSERT_FALSE(TRI.regsOverlap(AArch64::ZAH1, AArch64::ZAQ12)); ASSERT_FALSE(TRI.regsOverlap(AArch64::ZAH1, AArch64::ZAQ14)); // za0.h doesn't alias with za1.q, za3.q, .. ASSERT_FALSE(TRI.regsOverlap(AArch64::ZAH0, AArch64::ZAQ1)); ASSERT_FALSE(TRI.regsOverlap(AArch64::ZAH0, AArch64::ZAQ3)); ASSERT_FALSE(TRI.regsOverlap(AArch64::ZAH0, AArch64::ZAQ5)); ASSERT_FALSE(TRI.regsOverlap(AArch64::ZAH0, AArch64::ZAQ7)); ASSERT_FALSE(TRI.regsOverlap(AArch64::ZAH0, AArch64::ZAQ9)); ASSERT_FALSE(TRI.regsOverlap(AArch64::ZAH0, AArch64::ZAQ11)); ASSERT_FALSE(TRI.regsOverlap(AArch64::ZAH0, AArch64::ZAQ13)); ASSERT_FALSE(TRI.regsOverlap(AArch64::ZAH0, AArch64::ZAQ15)); // za0.s aliases with za0.q, za4.q, za8.q, za12.q ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAS0, AArch64::ZAQ0)); ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAS0, AArch64::ZAQ4)); ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAS0, AArch64::ZAQ8)); ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAS0, AArch64::ZAQ12)); // za1.s aliases with za1.q, za5.q, za9.q, za13.q ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAS1, AArch64::ZAQ1)); ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAS1, AArch64::ZAQ5)); ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAS1, AArch64::ZAQ9)); ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAS1, AArch64::ZAQ13)); // za0.s doesn't alias with za1.q, za5.q, za9.q, za13.q ASSERT_FALSE(TRI.regsOverlap(AArch64::ZAS0, AArch64::ZAQ1)); ASSERT_FALSE(TRI.regsOverlap(AArch64::ZAS0, AArch64::ZAQ5)); ASSERT_FALSE(TRI.regsOverlap(AArch64::ZAS0, AArch64::ZAQ9)); ASSERT_FALSE(TRI.regsOverlap(AArch64::ZAS0, AArch64::ZAQ13)); // za1.s doesn't alias with za0.q, za4.q, za8.q, za12.q ASSERT_FALSE(TRI.regsOverlap(AArch64::ZAS1, AArch64::ZAQ0)); ASSERT_FALSE(TRI.regsOverlap(AArch64::ZAS1, AArch64::ZAQ4)); ASSERT_FALSE(TRI.regsOverlap(AArch64::ZAS1, AArch64::ZAQ8)); ASSERT_FALSE(TRI.regsOverlap(AArch64::ZAS1, AArch64::ZAQ12)); // za0.d aliases za0.q and za8.q ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAD0, AArch64::ZAQ0)); ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAD0, AArch64::ZAQ8)); // za1.d aliases za1.q and za9.q ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAD1, AArch64::ZAQ1)); ASSERT_TRUE(TRI.regsOverlap(AArch64::ZAD1, AArch64::ZAQ9)); // za0.d doesn't alias with za1.q and za9.q ASSERT_FALSE(TRI.regsOverlap(AArch64::ZAD0, AArch64::ZAQ1)); ASSERT_FALSE(TRI.regsOverlap(AArch64::ZAD0, AArch64::ZAQ9)); // za1.d doesn't alias with za0.q and za8.q ASSERT_FALSE(TRI.regsOverlap(AArch64::ZAD1, AArch64::ZAQ0)); ASSERT_FALSE(TRI.regsOverlap(AArch64::ZAD1, AArch64::ZAQ8)); } } // end anonymous namespace