diff --git a/clang/lib/Driver/ToolChains/Arch/CSKY.h b/clang/lib/Driver/ToolChains/Arch/CSKY.h --- a/clang/lib/Driver/ToolChains/Arch/CSKY.h +++ b/clang/lib/Driver/ToolChains/Arch/CSKY.h @@ -32,7 +32,6 @@ void getCSKYTargetFeatures(const Driver &D, const llvm::Triple &Triple, const llvm::opt::ArgList &Args, - llvm::opt::ArgStringList &CmdArgs, std::vector &Features); std::optional getCSKYArchName(const Driver &D, diff --git a/clang/lib/Driver/ToolChains/Arch/CSKY.cpp b/clang/lib/Driver/ToolChains/Arch/CSKY.cpp --- a/clang/lib/Driver/ToolChains/Arch/CSKY.cpp +++ b/clang/lib/Driver/ToolChains/Arch/CSKY.cpp @@ -116,7 +116,7 @@ } void csky::getCSKYTargetFeatures(const Driver &D, const llvm::Triple &Triple, - const ArgList &Args, ArgStringList &CmdArgs, + const ArgList &Args, std::vector &Features) { llvm::StringRef archName; llvm::StringRef cpuName; diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -62,6 +62,7 @@ #include "llvm/Support/VirtualFileSystem.h" #include "llvm/Support/YAMLParser.h" #include "llvm/TargetParser/Host.h" +#include "llvm/TargetParser/SubtargetFeature.h" #include "llvm/TargetParser/TargetParser.h" #include @@ -485,10 +486,10 @@ options::OPT_m_wasm_Features_Group); } -void tools::getTargetFeatures(const Driver &D, const llvm::Triple &Triple, - const ArgList &Args, ArgStringList &CmdArgs, - bool ForAS, bool IsAux) { - std::vector Features; +static void collectTargetFeatures(const Driver &D, const llvm::Triple &Triple, + const ArgList &Args, + std::vector &Features, + bool ForAS) { switch (Triple.getArch()) { default: break; @@ -556,13 +557,20 @@ ve::getVETargetFeatures(D, Args, Features); break; case llvm::Triple::csky: - csky::getCSKYTargetFeatures(D, Triple, Args, CmdArgs, Features); + csky::getCSKYTargetFeatures(D, Triple, Args, Features); break; case llvm::Triple::loongarch32: case llvm::Triple::loongarch64: loongarch::getLoongArchTargetFeatures(D, Triple, Args, Features); break; } +} + +void tools::getTargetFeatures(const Driver &D, const llvm::Triple &Triple, + const ArgList &Args, ArgStringList &CmdArgs, + bool ForAS, bool IsAux) { + std::vector Features; + collectTargetFeatures(D, Triple, Args, Features, ForAS); for (auto Feature : unifyTargetFeatures(Features)) { CmdArgs.push_back(IsAux ? "-aux-target-feature" : "-target-feature"); @@ -639,6 +647,17 @@ CmdArgs.push_back( Args.MakeArgString(Twine(PluginOptPrefix) + ExtraDash + "mcpu=" + CPU)); + std::vector Features; + collectTargetFeatures(D, ToolChain.getTriple(), Args, Features, + /*ForAS*/ false); + if (!Features.empty()) { + llvm::SubtargetFeatures FeatureStr; + for (auto Feature : unifyTargetFeatures(Features)) + FeatureStr.AddFeature(Feature); + CmdArgs.push_back(Args.MakeArgString(Twine(PluginOptPrefix) + ExtraDash + + "mattr=" + FeatureStr.getString())); + } + if (Arg *A = Args.getLastArg(options::OPT_O_Group)) { // The optimization level matches // CompilerInvocation.cpp:getOptimizationLevel(). diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -1467,6 +1467,10 @@ parseClangOption(saver().save("-mcpu=" + StringRef(arg->getValue())), arg->getSpelling()); + if (auto *arg = args.getLastArg(OPT_plugin_opt_mattr_eq)) + parseClangOption(saver().save("-mattr=" + StringRef(arg->getValue())), + arg->getSpelling()); + for (opt::Arg *arg : args.filtered(OPT_plugin_opt_eq_minus)) parseClangOption(std::string("-") + arg->getValue(), arg->getSpelling()); diff --git a/lld/ELF/Options.td b/lld/ELF/Options.td --- a/lld/ELF/Options.td +++ b/lld/ELF/Options.td @@ -656,6 +656,7 @@ def: J<"plugin-opt=jobs=">, Alias, HelpText<"Alias for --thinlto-jobs=">; def: J<"plugin-opt=lto-partitions=">, Alias, HelpText<"Alias for --lto-partitions">; def plugin_opt_mcpu_eq: J<"plugin-opt=mcpu=">; +def plugin_opt_mattr_eq: J<"plugin-opt=mattr=">; def: F<"plugin-opt=cs-profile-generate">, Alias, HelpText<"Alias for --lto-cs-profile-generate">; def: J<"plugin-opt=cs-profile-path=">, diff --git a/llvm/tools/gold/gold-plugin.cpp b/llvm/tools/gold/gold-plugin.cpp --- a/llvm/tools/gold/gold-plugin.cpp +++ b/llvm/tools/gold/gold-plugin.cpp @@ -33,6 +33,7 @@ #include "llvm/Support/Threading.h" #include "llvm/Support/raw_ostream.h" #include "llvm/TargetParser/Host.h" +#include "llvm/TargetParser/SubtargetFeature.h" #include #include #include @@ -152,6 +153,7 @@ static std::string extra_library_path; static std::string triple; static std::string mcpu; + static std::string mattr; // When the thinlto plugin option is specified, only read the function // the information from intermediate files and write a combined // global index for the ThinLTO backends. @@ -228,6 +230,8 @@ if (opt.consume_front("mcpu=")) { mcpu = std::string(opt); + } else if (opt.consume_front("mattr=")) { + mattr = std::string(opt); } else if (opt.consume_front("extra-library-path=")) { extra_library_path = std::string(opt); } else if (opt.consume_front("mtriple=")) { @@ -875,7 +879,8 @@ if (!codegen::getExplicitDataSections()) Conf.Options.DataSections = SplitSections; - Conf.MAttrs = codegen::getMAttrs(); + SubtargetFeatures Features(options::mattr); + Conf.MAttrs = Features.getFeatures(); Conf.RelocModel = RelocationModel; Conf.CodeModel = codegen::getExplicitCodeModel(); std::optional CGOptLevelOrNone =