[Clang][MIPS] Send correct architecture for MinGW toolchains (#121042)
[llvm-project.git] / llvm / unittests / Target / AArch64 / AArch64SVESchedPseudoTest.cpp
blob5dd03ac07334a5bc3b07c935b17689403c71bf1b
1 #include "AArch64InstrInfo.h"
2 #include "AArch64Subtarget.h"
3 #include "AArch64TargetMachine.h"
4 #include "llvm/MC/MCSubtargetInfo.h"
5 #include "llvm/MC/TargetRegistry.h"
6 #include "llvm/Support/TargetSelect.h"
7 #include "llvm/Support/raw_ostream.h"
8 #include "llvm/Target/TargetMachine.h"
9 #include "llvm/Target/TargetOptions.h"
11 #include "gtest/gtest.h"
13 #define GET_COMPUTE_FEATURES
14 #include "AArch64GenInstrInfo.inc"
16 using namespace llvm;
17 namespace {
18 std::unique_ptr<TargetMachine> createTargetMachine(const std::string &CPU) {
19 auto TT(Triple::normalize("aarch64--"));
21 LLVMInitializeAArch64TargetInfo();
22 LLVMInitializeAArch64Target();
23 LLVMInitializeAArch64TargetMC();
25 std::string Error;
26 const Target *TheTarget = TargetRegistry::lookupTarget(TT, Error);
28 return std::unique_ptr<TargetMachine>(
29 TheTarget->createTargetMachine(TT, CPU, "", TargetOptions(), std::nullopt,
30 std::nullopt, CodeGenOptLevel::Default));
33 std::unique_ptr<AArch64InstrInfo> createInstrInfo(TargetMachine *TM) {
34 AArch64Subtarget ST(TM->getTargetTriple(), std::string(TM->getTargetCPU()),
35 std::string(TM->getTargetCPU()),
36 std::string(TM->getTargetFeatureString()), *TM, true);
37 return std::make_unique<AArch64InstrInfo>(ST);
40 /// Returns true if the instruction is enabled under a feature that the
41 /// CPU supports.
42 static bool isInstructionSupportedByCPU(unsigned Opcode,
43 FeatureBitset Features) {
44 FeatureBitset AvailableFeatures =
45 llvm::AArch64_MC::computeAvailableFeatures(Features);
46 FeatureBitset RequiredFeatures =
47 llvm::AArch64_MC::computeRequiredFeatures(Opcode);
48 FeatureBitset MissingFeatures =
49 (AvailableFeatures & RequiredFeatures) ^ RequiredFeatures;
50 return MissingFeatures.none();
53 void runSVEPseudoTestForCPU(const std::string &CPU) {
55 std::unique_ptr<TargetMachine> TM = createTargetMachine(CPU);
56 ASSERT_TRUE(TM);
57 std::unique_ptr<AArch64InstrInfo> II = createInstrInfo(TM.get());
58 ASSERT_TRUE(II);
60 const MCSubtargetInfo *STI = TM->getMCSubtargetInfo();
61 MCSchedModel SchedModel = STI->getSchedModel();
63 for (unsigned i = 0; i < AArch64::INSTRUCTION_LIST_END; ++i) {
64 // Check if instruction is in the pseudo table
65 // i holds the opcode of the pseudo, OrigInstr holds the opcode of the
66 // original instruction
67 int OrigInstr = AArch64::getSVEPseudoMap(i);
68 if (OrigInstr == -1)
69 continue;
71 // Ignore any pseudos/instructions which may not be part of the scheduler
72 // model for the CPU we're testing. This avoids this test from failing when
73 // new instructions are added that are not yet covered by the scheduler
74 // model.
75 if (!isInstructionSupportedByCPU(OrigInstr, STI->getFeatureBits()))
76 continue;
78 const MCInstrDesc &Desc = II->get(i);
79 unsigned SCClass = Desc.getSchedClass();
80 const MCSchedClassDesc *SCDesc = SchedModel.getSchedClassDesc(SCClass);
82 const MCInstrDesc &DescOrig = II->get(OrigInstr);
83 unsigned SCClassOrig = DescOrig.getSchedClass();
84 const MCSchedClassDesc *SCDescOrig =
85 SchedModel.getSchedClassDesc(SCClassOrig);
87 int Latency = 0;
88 int LatencyOrig = 0;
90 for (unsigned DefIdx = 0, DefEnd = SCDesc->NumWriteLatencyEntries;
91 DefIdx != DefEnd; ++DefIdx) {
92 const MCWriteLatencyEntry *WLEntry =
93 STI->getWriteLatencyEntry(SCDesc, DefIdx);
94 const MCWriteLatencyEntry *WLEntryOrig =
95 STI->getWriteLatencyEntry(SCDescOrig, DefIdx);
96 Latency = std::max(Latency, static_cast<int>(WLEntry->Cycles));
97 LatencyOrig = std::max(Latency, static_cast<int>(WLEntryOrig->Cycles));
100 ASSERT_EQ(Latency, LatencyOrig);
101 ASSERT_TRUE(SCDesc->isValid());
105 // TODO : Add more CPUs that support SVE/SVE2
106 TEST(AArch64SVESchedPseudoTesta510, IsCorrect) {
107 runSVEPseudoTestForCPU("cortex-a510");
110 TEST(AArch64SVESchedPseudoTestn1, IsCorrect) {
111 runSVEPseudoTestForCPU("neoverse-n2");
114 TEST(AArch64SVESchedPseudoTestn3, IsCorrect) {
115 runSVEPseudoTestForCPU("neoverse-n3");
118 TEST(AArch64SVESchedPseudoTestv1, IsCorrect) {
119 runSVEPseudoTestForCPU("neoverse-v1");
122 TEST(AArch64SVESchedPseudoTestv2, IsCorrect) {
123 runSVEPseudoTestForCPU("neoverse-v2");
126 } // namespace