diff --git a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp index a05f4b7ea64b4..346fb67ff277e 100644 --- a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp +++ b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp @@ -63,6 +63,9 @@ static void getRISCFeaturesFromMcpu(const Driver &D, const Arg *A, D.Diag(clang::diag::err_drv_unsupported_option_argument) << A->getSpelling() << Mcpu; } + + if (llvm::RISCV::hasFastUnalignedAccess(Mcpu)) + Features.push_back("+unaligned-scalar-mem"); } void riscv::getRISCVTargetFeatures(const Driver &D, const llvm::Triple &Triple, diff --git a/llvm/include/llvm/TargetParser/RISCVTargetParser.h b/llvm/include/llvm/TargetParser/RISCVTargetParser.h index a4cb7988eb398..5cc8a4a953045 100644 --- a/llvm/include/llvm/TargetParser/RISCVTargetParser.h +++ b/llvm/include/llvm/TargetParser/RISCVTargetParser.h @@ -31,6 +31,7 @@ bool parseTuneCPU(StringRef CPU, bool IsRV64); StringRef getMArchFromMcpu(StringRef CPU); void fillValidCPUArchList(SmallVectorImpl &Values, bool IsRV64); void fillValidTuneCPUArchList(SmallVectorImpl &Values, bool IsRV64); +bool hasFastUnalignedAccess(StringRef CPU); } // namespace RISCV } // namespace llvm diff --git a/llvm/lib/TargetParser/RISCVTargetParser.cpp b/llvm/lib/TargetParser/RISCVTargetParser.cpp index 30a1023c06732..85cdd1289a953 100644 --- a/llvm/lib/TargetParser/RISCVTargetParser.cpp +++ b/llvm/lib/TargetParser/RISCVTargetParser.cpp @@ -20,7 +20,7 @@ namespace llvm { namespace RISCV { enum CPUKind : unsigned { -#define PROC(ENUM, NAME, DEFAULT_MARCH) CK_##ENUM, +#define PROC(ENUM, NAME, DEFAULT_MARCH, FAST_UNALIGN) CK_##ENUM, #define TUNE_PROC(ENUM, NAME) CK_##ENUM, #include "llvm/TargetParser/RISCVTargetParserDef.inc" }; @@ -28,12 +28,13 @@ enum CPUKind : unsigned { struct CPUInfo { StringLiteral Name; StringLiteral DefaultMarch; + bool FastUnalignedAccess; bool is64Bit() const { return DefaultMarch.starts_with("rv64"); } }; constexpr CPUInfo RISCVCPUInfo[] = { -#define PROC(ENUM, NAME, DEFAULT_MARCH) \ - {NAME, DEFAULT_MARCH}, +#define PROC(ENUM, NAME, DEFAULT_MARCH, FAST_UNALIGN) \ + {NAME, DEFAULT_MARCH, FAST_UNALIGN}, #include "llvm/TargetParser/RISCVTargetParserDef.inc" }; @@ -44,6 +45,11 @@ static const CPUInfo *getCPUInfoByName(StringRef CPU) { return nullptr; } +bool hasFastUnalignedAccess(StringRef CPU) { + const CPUInfo *Info = getCPUInfoByName(CPU); + return Info && Info->FastUnalignedAccess; +} + bool parseCPU(StringRef CPU, bool IsRV64) { const CPUInfo *Info = getCPUInfoByName(CPU); diff --git a/llvm/utils/TableGen/RISCVTargetDefEmitter.cpp b/llvm/utils/TableGen/RISCVTargetDefEmitter.cpp index 12174fd83f566..fddfefda1007d 100644 --- a/llvm/utils/TableGen/RISCVTargetDefEmitter.cpp +++ b/llvm/utils/TableGen/RISCVTargetDefEmitter.cpp @@ -49,7 +49,7 @@ static std::string getMArch(const Record &Rec) { static void EmitRISCVTargetDef(RecordKeeper &RK, raw_ostream &OS) { OS << "#ifndef PROC\n" - << "#define PROC(ENUM, NAME, DEFAULT_MARCH)\n" + << "#define PROC(ENUM, NAME, DEFAULT_MARCH, FAST_UNALIGNED_ACCESS)\n" << "#endif\n\n"; // Iterate on all definition records. @@ -60,9 +60,14 @@ static void EmitRISCVTargetDef(RecordKeeper &RK, raw_ostream &OS) { if (MArch.empty()) MArch = getMArch(*Rec); + const bool FastUnalignedAccess = + any_of(Rec->getValueAsListOfDefs("Features"), [&](auto &Feature) { + return Feature->getValueAsString("Name") == "unaligned-scalar-mem"; + }); + OS << "PROC(" << Rec->getName() << ", " << "{\"" << Rec->getValueAsString("Name") << "\"}, " - << "{\"" << MArch << "\"})\n"; + << "{\"" << MArch << "\"}, " << FastUnalignedAccess << ")\n"; } OS << "\n#undef PROC\n"; OS << "\n";