bolt/deps/llvm-18.1.8/llvm/unittests/Target/AArch64/AArch64SVESchedPseudoTest.cpp

115 lines
4 KiB
C++
Raw Normal View History

2025-02-14 19:21:04 +01:00
#include "AArch64InstrInfo.h"
#include "AArch64Subtarget.h"
#include "AArch64TargetMachine.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
#include "gtest/gtest.h"
#define GET_COMPUTE_FEATURES
#include "AArch64GenInstrInfo.inc"
using namespace llvm;
namespace {
std::unique_ptr<LLVMTargetMachine> createTargetMachine(const std::string &CPU) {
auto TT(Triple::normalize("aarch64--"));
LLVMInitializeAArch64TargetInfo();
LLVMInitializeAArch64Target();
LLVMInitializeAArch64TargetMC();
std::string Error;
const Target *TheTarget = TargetRegistry::lookupTarget(TT, Error);
return std::unique_ptr<LLVMTargetMachine>(static_cast<LLVMTargetMachine *>(
TheTarget->createTargetMachine(TT, CPU, "", TargetOptions(), std::nullopt,
std::nullopt, CodeGenOptLevel::Default)));
}
std::unique_ptr<AArch64InstrInfo> createInstrInfo(TargetMachine *TM) {
AArch64Subtarget ST(TM->getTargetTriple(), std::string(TM->getTargetCPU()),
std::string(TM->getTargetCPU()),
std::string(TM->getTargetFeatureString()), *TM, true);
return std::make_unique<AArch64InstrInfo>(ST);
}
/// Returns true if the instruction is enabled under a feature that the
/// CPU supports.
static bool isInstructionSupportedByCPU(unsigned Opcode,
FeatureBitset Features) {
FeatureBitset AvailableFeatures =
llvm::AArch64_MC::computeAvailableFeatures(Features);
FeatureBitset RequiredFeatures =
llvm::AArch64_MC::computeRequiredFeatures(Opcode);
FeatureBitset MissingFeatures =
(AvailableFeatures & RequiredFeatures) ^ RequiredFeatures;
return MissingFeatures.none();
}
void runSVEPseudoTestForCPU(const std::string &CPU) {
std::unique_ptr<LLVMTargetMachine> TM = createTargetMachine(CPU);
ASSERT_TRUE(TM);
std::unique_ptr<AArch64InstrInfo> II = createInstrInfo(TM.get());
ASSERT_TRUE(II);
const MCSubtargetInfo *STI = TM->getMCSubtargetInfo();
MCSchedModel SchedModel = STI->getSchedModel();
for (unsigned i = 0; i < AArch64::INSTRUCTION_LIST_END; ++i) {
// Check if instruction is in the pseudo table
// i holds the opcode of the pseudo, OrigInstr holds the opcode of the
// original instruction
int OrigInstr = AArch64::getSVEPseudoMap(i);
if (OrigInstr == -1)
continue;
// Ignore any pseudos/instructions which may not be part of the scheduler
// model for the CPU we're testing. This avoids this test from failing when
// new instructions are added that are not yet covered by the scheduler
// model.
if (!isInstructionSupportedByCPU(OrigInstr, STI->getFeatureBits()))
continue;
const MCInstrDesc &Desc = II->get(i);
unsigned SCClass = Desc.getSchedClass();
const MCSchedClassDesc *SCDesc = SchedModel.getSchedClassDesc(SCClass);
const MCInstrDesc &DescOrig = II->get(OrigInstr);
unsigned SCClassOrig = DescOrig.getSchedClass();
const MCSchedClassDesc *SCDescOrig =
SchedModel.getSchedClassDesc(SCClassOrig);
int Latency = 0;
int LatencyOrig = 0;
for (unsigned DefIdx = 0, DefEnd = SCDesc->NumWriteLatencyEntries;
DefIdx != DefEnd; ++DefIdx) {
const MCWriteLatencyEntry *WLEntry =
STI->getWriteLatencyEntry(SCDesc, DefIdx);
const MCWriteLatencyEntry *WLEntryOrig =
STI->getWriteLatencyEntry(SCDescOrig, DefIdx);
Latency = std::max(Latency, static_cast<int>(WLEntry->Cycles));
LatencyOrig = std::max(Latency, static_cast<int>(WLEntryOrig->Cycles));
}
ASSERT_EQ(Latency, LatencyOrig);
ASSERT_TRUE(SCDesc->isValid());
}
}
// TODO : Add more CPUs that support SVE/SVE2
TEST(AArch64SVESchedPseudoTesta510, IsCorrect) {
runSVEPseudoTestForCPU("cortex-a510");
}
TEST(AArch64SVESchedPseudoTestv2, IsCorrect) {
runSVEPseudoTestForCPU("neoverse-v2");
}
} // namespace