diff --git a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp index f2e79e71f93d4..f51e3ea6bfe73 100644 --- a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp +++ b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp @@ -367,3 +367,31 @@ std::string riscv::getRISCVTargetCPU(const llvm::opt::ArgList &Args, return Triple.isRISCV64() ? "generic-rv64" : "generic-rv32"; } + +void riscv::addMtuneWithFeatures(const Arg *A, const ArgList &Args, + ArgStringList &CmdArgs) { + // format: -mtune=[:+a,-b,+c...] + StringRef MTune(A->getValue()); + size_t ColonPos = MTune.find(':'); + bool HasColon = ColonPos != StringRef::npos; + + StringRef TuneCPU = MTune.take_front(ColonPos); + if (TuneCPU == "native") + CmdArgs.push_back(Args.MakeArgString(llvm::sys::getHostCPUName())); + else + CmdArgs.push_back(HasColon ? Args.MakeArgString(TuneCPU) : A->getValue()); + + StringRef FeatureStr = HasColon ? MTune.drop_front(ColonPos + 1) : ""; + // TODO: Emit error + assert(!HasColon || !FeatureStr.empty()); + if (FeatureStr.empty()) + return; + StringRef Feature; + do { + std::tie(Feature, FeatureStr) = FeatureStr.split(','); + // TODO: Emit error + assert(Feature.starts_with('-') || Feature.starts_with('+')); + CmdArgs.push_back("-target-feature"); + CmdArgs.push_back(Args.MakeArgString(Feature)); + } while (!FeatureStr.empty()); +} diff --git a/clang/lib/Driver/ToolChains/Arch/RISCV.h b/clang/lib/Driver/ToolChains/Arch/RISCV.h index 388786b9c4c1f..3e43430051cca 100644 --- a/clang/lib/Driver/ToolChains/Arch/RISCV.h +++ b/clang/lib/Driver/ToolChains/Arch/RISCV.h @@ -28,6 +28,9 @@ std::string getRISCVArch(const llvm::opt::ArgList &Args, const llvm::Triple &Triple); std::string getRISCVTargetCPU(const llvm::opt::ArgList &Args, const llvm::Triple &Triple); +void addMtuneWithFeatures(const llvm::opt::Arg *A, + const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs); } // end namespace riscv } // namespace tools } // end namespace driver diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index d326a81feb762..e39a8d4996089 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -2046,10 +2046,7 @@ void Clang::AddRISCVTargetArgs(const ArgList &Args, if (const Arg *A = Args.getLastArg(options::OPT_mtune_EQ)) { CmdArgs.push_back("-tune-cpu"); - if (strcmp(A->getValue(), "native") == 0) - CmdArgs.push_back(Args.MakeArgString(llvm::sys::getHostCPUName())); - else - CmdArgs.push_back(A->getValue()); + riscv::addMtuneWithFeatures(A, Args, CmdArgs); } // Handle -mrvv-vector-bits= diff --git a/clang/test/Driver/riscv-cpus.c b/clang/test/Driver/riscv-cpus.c index 5d5fdd72baedb..806c42bdad374 100644 --- a/clang/test/Driver/riscv-cpus.c +++ b/clang/test/Driver/riscv-cpus.c @@ -305,6 +305,11 @@ // RUN: %clang --target=riscv64 -### -c %s 2>&1 -mtune=native | FileCheck -check-prefix=MTUNE-NATIVE %s // MTUNE-NATIVE-NOT: "-tune-cpu" "native" +// Checking `-mtune=:+x,-y,+z...` +// RUN: %clang --target=riscv64 -### -c %s 2>&1 -mtune=sifive-e20:+xyz,-abc | FileCheck -check-prefix=MTUNE-WITH-FEATURES %s +// MTUNE-WITH-FEATURES: "-tune-cpu" "sifive-e20" +// MTUNE-WITH-FEATURES: "-target-feature" "+xyz" "-target-feature" "-abc" + // -mcpu with default -march // RUN: %clang --target=riscv64 -### -c %s 2>&1 -mcpu=sifive-e20 | FileCheck -check-prefix=MCPU-SIFIVE-E20 %s // MCPU-SIFIVE-E20: "-nostdsysteminc" "-target-cpu" "sifive-e20"