diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -677,6 +677,7 @@ ----------------------- - ``sifive-7-rv32`` and ``sifive-7-rv64`` are no longer supported for ``-mcpu``. Use ``sifive-e76``, ``sifive-s76``, or ``sifive-u74`` instead. +- Native detections via ``-mcpu=native`` and ``-mtune=native`` are supported. X86 Support in Clang -------------------- diff --git a/clang/lib/Driver/ToolChains/Arch/RISCV.h b/clang/lib/Driver/ToolChains/Arch/RISCV.h --- a/clang/lib/Driver/ToolChains/Arch/RISCV.h +++ b/clang/lib/Driver/ToolChains/Arch/RISCV.h @@ -26,6 +26,8 @@ const llvm::Triple &Triple); StringRef getRISCVArch(const llvm::opt::ArgList &Args, const llvm::Triple &Triple); +std::string getRISCVTargetCPU(const llvm::opt::ArgList &Args, + const llvm::Triple &Triple); } // end namespace riscv } // namespace tools } // end namespace driver diff --git a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp --- a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp +++ b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp @@ -16,6 +16,7 @@ #include "llvm/ADT/Optional.h" #include "llvm/Option/ArgList.h" #include "llvm/Support/Error.h" +#include "llvm/Support/Host.h" #include "llvm/Support/RISCVISAInfo.h" #include "llvm/Support/TargetParser.h" #include "llvm/Support/raw_ostream.h" @@ -48,16 +49,12 @@ } // Get features except standard extension feature -static void getRISCFeaturesFromMcpu(const Driver &D, const llvm::Triple &Triple, - const llvm::opt::ArgList &Args, - const llvm::opt::Arg *A, StringRef Mcpu, +static bool getRISCFeaturesFromMcpu(const llvm::Triple &Triple, StringRef Mcpu, std::vector &Features) { bool Is64Bit = Triple.isRISCV64(); llvm::RISCV::CPUKind CPUKind = llvm::RISCV::parseCPUKind(Mcpu); - if (!llvm::RISCV::checkCPUKind(CPUKind, Is64Bit) || - !llvm::RISCV::getCPUFeaturesExceptStdExt(CPUKind, Features)) { - D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args); - } + return llvm::RISCV::checkCPUKind(CPUKind, Is64Bit) && + llvm::RISCV::getCPUFeaturesExceptStdExt(CPUKind, Features); } void riscv::getRISCVTargetFeatures(const Driver &D, const llvm::Triple &Triple, @@ -70,8 +67,14 @@ // If users give march and mcpu, get std extension feature from MArch // and other features (ex. mirco architecture feature) from mcpu - if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) - getRISCFeaturesFromMcpu(D, Triple, Args, A, A->getValue(), Features); + if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) { + StringRef CPU = A->getValue(); + if (CPU == "native") + CPU = llvm::sys::getHostCPUName(); + if (!getRISCFeaturesFromMcpu(Triple, CPU, Features)) + D.Diag(clang::diag::err_drv_unsupported_option_argument) + << A->getOption().getName() << CPU; + } // Handle features corresponding to "-ffixed-X" options if (Args.hasArg(options::OPT_ffixed_x1)) @@ -260,7 +263,10 @@ // 2. Get march (isa string) based on `-mcpu=` if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) { - StringRef MArch = llvm::RISCV::getMArchFromMcpu(A->getValue()); + StringRef CPU = A->getValue(); + if (CPU == "native") + CPU = llvm::sys::getHostCPUName(); + StringRef MArch = llvm::RISCV::getMArchFromMcpu(CPU); // Bypass if target cpu's default march is empty. if (MArch != "") return MArch; @@ -299,3 +305,20 @@ return "rv64imafdc"; } } + +std::string riscv::getRISCVTargetCPU(const llvm::opt::ArgList &Args, + const llvm::Triple &Triple) { + std::string CPU; + // If we have -mcpu, use that. + if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) + CPU = A->getValue(); + + // Handle CPU name is 'native'. + if (CPU == "native") + CPU = llvm::sys::getHostCPUName(); + + if (!CPU.empty()) + return CPU; + + return Triple.isRISCV64() ? "generic-rv64" : "generic-rv32"; +} diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -2187,7 +2187,10 @@ if (const Arg *A = Args.getLastArg(options::OPT_mtune_EQ)) { CmdArgs.push_back("-tune-cpu"); - CmdArgs.push_back(A->getValue()); + if (strcmp(A->getValue(), "native") == 0) + CmdArgs.push_back(Args.MakeArgString(llvm::sys::getHostCPUName())); + else + CmdArgs.push_back(A->getValue()); } } 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 @@ -12,6 +12,7 @@ #include "Arch/M68k.h" #include "Arch/Mips.h" #include "Arch/PPC.h" +#include "Arch/RISCV.h" #include "Arch/Sparc.h" #include "Arch/SystemZ.h" #include "Arch/VE.h" @@ -432,9 +433,7 @@ return "ck810"; case llvm::Triple::riscv32: case llvm::Triple::riscv64: - if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) - return A->getValue(); - return ""; + return riscv::getRISCVTargetCPU(Args, T); case llvm::Triple::bpfel: case llvm::Triple::bpfeb: diff --git a/clang/test/Driver/riscv-cpus.c b/clang/test/Driver/riscv-cpus.c --- a/clang/test/Driver/riscv-cpus.c +++ b/clang/test/Driver/riscv-cpus.c @@ -7,6 +7,10 @@ // MCPU-ROCKET64: "-nostdsysteminc" "-target-cpu" "rocket-rv64" // MCPU-ROCKET64: "-target-feature" "+64bit" +// We cannot check much for -mcpu=native, but it should be replaced by a valid CPU string. +// RUN: %clang --target=riscv64 -### -c %s 2>&1 -mcpu=native | FileCheck -check-prefix=MCPU-NATIVE %s +// MCPU-NATIVE-NOT: "-target-cpu" "native" + // RUN: %clang --target=riscv32 -### -c %s 2>&1 -mtune=rocket-rv32 | FileCheck -check-prefix=MTUNE-ROCKET32 %s // MTUNE-ROCKET32: "-tune-cpu" "rocket-rv32" @@ -26,6 +30,10 @@ // RUN: %clang --target=riscv64 -### -c %s 2>&1 -mtune=rocket | FileCheck -check-prefix=MTUNE-ROCKET-64 %s // MTUNE-ROCKET-64: "-tune-cpu" "rocket" +// We cannot check much for -mtune=native, but it should be replaced by a valid CPU string. +// RUN: %clang --target=riscv64 -### -c %s 2>&1 -mtune=native | FileCheck -check-prefix=MTUNE-NATIVE %s +// MTUNE-NATIVE-NOT: "-tune-cpu" "native" + // 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" @@ -130,10 +138,10 @@ // Check failed cases // RUN: %clang --target=riscv32 -### -c %s 2>&1 -mcpu=generic-rv321 | FileCheck -check-prefix=FAIL-MCPU-NAME %s -// FAIL-MCPU-NAME: error: the clang compiler does not support '-mcpu=generic-rv321' +// FAIL-MCPU-NAME: error: unsupported argument 'generic-rv321' to option '-mcpu=' // RUN: %clang --target=riscv32 -### -c %s 2>&1 -mcpu=generic-rv32 -march=rv64i | FileCheck -check-prefix=MISMATCH-ARCH %s -// MISMATCH-ARCH: error: the clang compiler does not support '-mcpu=generic-rv32' +// MISMATCH-ARCH: error: unsupported argument 'generic-rv32' to option '-mcpu=' // RUN: %clang --target=riscv32 -### -c %s 2>&1 -mcpu=generic-rv64 | FileCheck -check-prefix=MISMATCH-MCPU %s -// MISMATCH-MCPU: error: the clang compiler does not support '-mcpu=generic-rv64' +// MISMATCH-MCPU: error: unsupported argument 'generic-rv64' to option '-mcpu='