brintos

brintos / llvm-project-archived public Read only

0
0
Text · 9.4 KiB · c9faee8 Raw
278 lines · cpp
1#include "AArch64Subtarget.h"2#include "AArch64TargetMachine.h"3#include "llvm/CodeGen/MIRParser/MIRParser.h"4#include "llvm/CodeGen/MachineModuleInfo.h"5#include "llvm/IR/Module.h"6#include "llvm/MC/TargetRegistry.h"7#include "llvm/Support/MemoryBuffer.h"8#include "llvm/Support/TargetSelect.h"9 10#include "gtest/gtest.h"11 12using namespace llvm;13 14namespace {15std::unique_ptr<TargetMachine> createTargetMachine() {16  Triple TT("aarch64--");17  std::string CPU("generic");18  std::string FS("+pauth,+mops,+mte");19 20  LLVMInitializeAArch64TargetInfo();21  LLVMInitializeAArch64Target();22  LLVMInitializeAArch64TargetMC();23 24  std::string Error;25  const Target *TheTarget = TargetRegistry::lookupTarget(TT, Error);26 27  return std::unique_ptr<TargetMachine>(28      TheTarget->createTargetMachine(TT, CPU, FS, TargetOptions(), std::nullopt,29                                     std::nullopt, CodeGenOptLevel::Default));30}31 32std::unique_ptr<AArch64InstrInfo> createInstrInfo(TargetMachine *TM) {33  AArch64Subtarget ST(TM->getTargetTriple(), std::string(TM->getTargetCPU()),34                      std::string(TM->getTargetCPU()),35                      std::string(TM->getTargetFeatureString()), *TM,36                      /* isLittle */ false);37  return std::make_unique<AArch64InstrInfo>(ST);38}39 40/// The \p InputIRSnippet is only needed for things that can't be expressed in41/// the \p InputMIRSnippet (global variables etc)42/// TODO: Some of this might be useful for other architectures as well - extract43///       the platform-independent parts somewhere they can be reused.44void runChecks(45    TargetMachine *TM, AArch64InstrInfo *II, const StringRef InputIRSnippet,46    const StringRef InputMIRSnippet,47    std::function<void(AArch64InstrInfo &, MachineFunction &)> Checks) {48  LLVMContext Context;49 50  auto MIRString =51    "--- |\n"52    "  declare void @sizes()\n"53    + InputIRSnippet.str() +54    "...\n"55    "---\n"56    "name: sizes\n"57    "jumpTable:\n"58    "  kind:            block-address\n"59    "  entries:\n"60    "    - id:              0\n"61    "      blocks:          [ '%bb.0' ]\n"62    "body: |\n"63    "  bb.0:\n"64    + InputMIRSnippet.str();65 66  std::unique_ptr<MemoryBuffer> MBuffer = MemoryBuffer::getMemBuffer(MIRString);67  std::unique_ptr<MIRParser> MParser =68      createMIRParser(std::move(MBuffer), Context);69  ASSERT_TRUE(MParser);70 71  std::unique_ptr<Module> M = MParser->parseIRModule();72  ASSERT_TRUE(M);73 74  M->setTargetTriple(TM->getTargetTriple());75  M->setDataLayout(TM->createDataLayout());76 77  MachineModuleInfo MMI(TM);78  bool Res = MParser->parseMachineFunctions(*M, MMI);79  ASSERT_FALSE(Res);80 81  auto F = M->getFunction("sizes");82  ASSERT_TRUE(F != nullptr);83  auto &MF = MMI.getOrCreateMachineFunction(*F);84 85  Checks(*II, MF);86}87 88} // anonymous namespace89 90TEST(InstSizes, Authenticated) {91  std::unique_ptr<TargetMachine> TM = createTargetMachine();92  ASSERT_TRUE(TM);93  std::unique_ptr<AArch64InstrInfo> II = createInstrInfo(TM.get());94 95  auto isAuthInst = [](AArch64InstrInfo &II, MachineFunction &MF) {96    auto I = MF.begin()->begin();97    EXPECT_EQ(4u, II.getInstSizeInBytes(*I));98    EXPECT_TRUE(I->getDesc().isAuthenticated());99  };100 101  runChecks(TM.get(), II.get(), "",102            "    \n"103            "    BLRAA $x10, $x9\n",104            isAuthInst);105 106  runChecks(TM.get(), II.get(), "",107            "    \n"108            "    RETAB implicit $lr, implicit $sp, implicit killed $x0\n",109            isAuthInst);110 111  runChecks(TM.get(), II.get(), "",112            "    \n"113            "    frame-destroy AUTIASP implicit-def $lr, implicit killed $lr, implicit $sp\n",114            isAuthInst);115 116  runChecks(TM.get(), II.get(), "",117            "    \n"118            "    frame-destroy AUTIBSP implicit-def $lr, implicit killed $lr, implicit $sp\n",119            isAuthInst);120}121 122TEST(InstSizes, STACKMAP) {123  std::unique_ptr<TargetMachine> TM = createTargetMachine();124  ASSERT_TRUE(TM);125  std::unique_ptr<AArch64InstrInfo> II = createInstrInfo(TM.get());126 127  runChecks(TM.get(), II.get(), "", "    STACKMAP 0, 16\n"128                                    "    STACKMAP 1, 32\n",129            [](AArch64InstrInfo &II, MachineFunction &MF) {130              auto I = MF.begin()->begin();131              EXPECT_EQ(16u, II.getInstSizeInBytes(*I));132              ++I;133              EXPECT_EQ(32u, II.getInstSizeInBytes(*I));134            });135}136 137TEST(InstSizes, PATCHPOINT) {138  std::unique_ptr<TargetMachine> TM = createTargetMachine();139  std::unique_ptr<AArch64InstrInfo> II = createInstrInfo(TM.get());140 141  runChecks(TM.get(), II.get(), "",142            "    PATCHPOINT 0, 16, 0, 0, 0, csr_aarch64_aapcs\n"143            "    PATCHPOINT 1, 32, 0, 0, 0, csr_aarch64_aapcs\n",144            [](AArch64InstrInfo &II, MachineFunction &MF) {145              auto I = MF.begin()->begin();146              EXPECT_EQ(16u, II.getInstSizeInBytes(*I));147              ++I;148              EXPECT_EQ(32u, II.getInstSizeInBytes(*I));149            });150}151 152TEST(InstSizes, STATEPOINT) {153  std::unique_ptr<TargetMachine> TM = createTargetMachine();154  std::unique_ptr<AArch64InstrInfo> II = createInstrInfo(TM.get());155 156  runChecks(TM.get(), II.get(), "",157            "    STATEPOINT 0, 0, 0, @sizes, 2, 0, 2, 0, 2, 0, 2, 1, 1, 8,"158            " $sp, 24, 2, 0, 2, 1, 0, 0\n",159            [](AArch64InstrInfo &II, MachineFunction &MF) {160              auto I = MF.begin()->begin();161              EXPECT_EQ(4u, II.getInstSizeInBytes(*I));162            });163}164 165TEST(InstSizes, SPACE) {166  std::unique_ptr<TargetMachine> TM = createTargetMachine();167  std::unique_ptr<AArch64InstrInfo> II = createInstrInfo(TM.get());168 169  runChecks(TM.get(), II.get(), "",170            "    $xzr = SPACE 1024, undef $xzr\n"171            "    dead $xzr = SPACE 4096, $xzr\n",172            [](AArch64InstrInfo &II, MachineFunction &MF) {173              auto I = MF.begin()->begin();174              EXPECT_EQ(1024u, II.getInstSizeInBytes(*I));175              ++I;176              EXPECT_EQ(4096u, II.getInstSizeInBytes(*I));177            });178}179 180TEST(InstSizes, TLSDESC_CALLSEQ) {181  std::unique_ptr<TargetMachine> TM = createTargetMachine();182  std::unique_ptr<AArch64InstrInfo> II = createInstrInfo(TM.get());183 184  runChecks(185      TM.get(), II.get(),186      "  @ThreadLocalGlobal = external thread_local global i32, align 8\n",187      "    TLSDESC_CALLSEQ target-flags(aarch64-tls) @ThreadLocalGlobal\n",188      [](AArch64InstrInfo &II, MachineFunction &MF) {189        auto I = MF.begin()->begin();190        EXPECT_EQ(16u, II.getInstSizeInBytes(*I));191      });192}193 194TEST(InstSizes, StoreSwiftAsyncContext) {195  std::unique_ptr<TargetMachine> TM = createTargetMachine();196  std::unique_ptr<AArch64InstrInfo> II = createInstrInfo(TM.get());197 198  runChecks(199      TM.get(), II.get(), "",200      "    StoreSwiftAsyncContext $x0, $x1, 12, implicit-def $x16, "201      "implicit-def $x17\n",202      [](AArch64InstrInfo &II, MachineFunction &MF) {203        auto I = MF.begin()->begin();204        EXPECT_EQ(20u, II.getInstSizeInBytes(*I));205      });206}207 208TEST(InstSizes, SpeculationBarrierISBDSBEndBB) {209  std::unique_ptr<TargetMachine> TM = createTargetMachine();210  std::unique_ptr<AArch64InstrInfo> II = createInstrInfo(TM.get());211 212  runChecks(213      TM.get(), II.get(), "",214      "    SpeculationBarrierISBDSBEndBB\n"215      "    BR $x8\n",216      [](AArch64InstrInfo &II, MachineFunction &MF) {217        auto I = MF.begin()->begin();218        EXPECT_EQ(8u, II.getInstSizeInBytes(*I));219      });220}221 222TEST(InstSizes, SpeculationBarrierSBEndBB) {223  std::unique_ptr<TargetMachine> TM = createTargetMachine();224  std::unique_ptr<AArch64InstrInfo> II = createInstrInfo(TM.get());225 226  runChecks(227      TM.get(), II.get(), "",228      "    SpeculationBarrierSBEndBB\n"229      "    BR $x8\n",230      [](AArch64InstrInfo &II, MachineFunction &MF) {231        auto I = MF.begin()->begin();232        EXPECT_EQ(4u, II.getInstSizeInBytes(*I));233      });234}235 236TEST(InstSizes, JumpTable) {237  std::unique_ptr<TargetMachine> TM = createTargetMachine();238  std::unique_ptr<AArch64InstrInfo> II = createInstrInfo(TM.get());239 240  runChecks(TM.get(), II.get(), "",241            "    $x10, $x11 = JumpTableDest32 $x9, $x8, %jump-table.0\n"242            "    $x10, $x11 = JumpTableDest16 $x9, $x8, %jump-table.0\n"243            "    $x10, $x11 = JumpTableDest8 $x9, $x8, %jump-table.0\n",244            [](AArch64InstrInfo &II, MachineFunction &MF) {245              auto I = MF.begin()->begin();246              EXPECT_EQ(12u, II.getInstSizeInBytes(*I));247              ++I;248              EXPECT_EQ(12u, II.getInstSizeInBytes(*I));249              ++I;250              EXPECT_EQ(12u, II.getInstSizeInBytes(*I));251            });252}253 254TEST(InstSizes, MOPSMemoryPseudos) {255  std::unique_ptr<TargetMachine> TM = createTargetMachine();256  std::unique_ptr<AArch64InstrInfo> II = createInstrInfo(TM.get());257 258  runChecks(TM.get(), II.get(), "",259            "  $x0, $x1, $x2 = MOPSMemoryMovePseudo $x0, $x1, $x2, "260            "implicit-def $nzcv\n"261            "  $x0, $x1 = MOPSMemorySetPseudo $x0, $x1, $x2, "262            "implicit-def $nzcv\n"263            "  $x0, $x1, $x8 = MOPSMemoryCopyPseudo $x0, $x1, $x8, "264            "implicit-def $nzcv\n"265            "  $x0, $x1 = MOPSMemorySetTaggingPseudo $x0, $x1, $x2, "266            "implicit-def $nzcv\n",267            [](AArch64InstrInfo &II, MachineFunction &MF) {268              auto I = MF.begin()->begin();269              EXPECT_EQ(12u, II.getInstSizeInBytes(*I));270              ++I;271              EXPECT_EQ(12u, II.getInstSizeInBytes(*I));272              ++I;273              EXPECT_EQ(12u, II.getInstSizeInBytes(*I));274              ++I;275              EXPECT_EQ(12u, II.getInstSizeInBytes(*I));276            });277}278