Skip to content

Commit 7c50bcb

Browse files
committed
[RISCV] Support -mcpu/mtune=native
We may need hosted Clang/LLVM to compile and `getHostCpuName` can be used for native detection. Tests are added in riscv-cpus.c just like what AArch64/PPC have done. Reviewed By: kito-cheng Differential Revision: https://reviews.llvm.org/D136930
1 parent 34f687c commit 7c50bcb

File tree

6 files changed

+53
-17
lines changed

6 files changed

+53
-17
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -677,6 +677,7 @@ RISC-V Support in Clang
677677
-----------------------
678678
- ``sifive-7-rv32`` and ``sifive-7-rv64`` are no longer supported for ``-mcpu``.
679679
Use ``sifive-e76``, ``sifive-s76``, or ``sifive-u74`` instead.
680+
- Native detections via ``-mcpu=native`` and ``-mtune=native`` are supported.
680681

681682
X86 Support in Clang
682683
--------------------

clang/lib/Driver/ToolChains/Arch/RISCV.cpp

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "llvm/ADT/Optional.h"
1717
#include "llvm/Option/ArgList.h"
1818
#include "llvm/Support/Error.h"
19+
#include "llvm/Support/Host.h"
1920
#include "llvm/Support/RISCVISAInfo.h"
2021
#include "llvm/Support/TargetParser.h"
2122
#include "llvm/Support/raw_ostream.h"
@@ -48,16 +49,12 @@ static bool getArchFeatures(const Driver &D, StringRef Arch,
4849
}
4950

5051
// Get features except standard extension feature
51-
static void getRISCFeaturesFromMcpu(const Driver &D, const llvm::Triple &Triple,
52-
const llvm::opt::ArgList &Args,
53-
const llvm::opt::Arg *A, StringRef Mcpu,
52+
static bool getRISCFeaturesFromMcpu(const llvm::Triple &Triple, StringRef Mcpu,
5453
std::vector<StringRef> &Features) {
5554
bool Is64Bit = Triple.isRISCV64();
5655
llvm::RISCV::CPUKind CPUKind = llvm::RISCV::parseCPUKind(Mcpu);
57-
if (!llvm::RISCV::checkCPUKind(CPUKind, Is64Bit) ||
58-
!llvm::RISCV::getCPUFeaturesExceptStdExt(CPUKind, Features)) {
59-
D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args);
60-
}
56+
return llvm::RISCV::checkCPUKind(CPUKind, Is64Bit) &&
57+
llvm::RISCV::getCPUFeaturesExceptStdExt(CPUKind, Features);
6158
}
6259

6360
void riscv::getRISCVTargetFeatures(const Driver &D, const llvm::Triple &Triple,
@@ -70,8 +67,14 @@ void riscv::getRISCVTargetFeatures(const Driver &D, const llvm::Triple &Triple,
7067

7168
// If users give march and mcpu, get std extension feature from MArch
7269
// and other features (ex. mirco architecture feature) from mcpu
73-
if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
74-
getRISCFeaturesFromMcpu(D, Triple, Args, A, A->getValue(), Features);
70+
if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
71+
StringRef CPU = A->getValue();
72+
if (CPU == "native")
73+
CPU = llvm::sys::getHostCPUName();
74+
if (!getRISCFeaturesFromMcpu(Triple, CPU, Features))
75+
D.Diag(clang::diag::err_drv_unsupported_option_argument)
76+
<< A->getOption().getName() << CPU;
77+
}
7578

7679
// Handle features corresponding to "-ffixed-X" options
7780
if (Args.hasArg(options::OPT_ffixed_x1))
@@ -260,7 +263,10 @@ StringRef riscv::getRISCVArch(const llvm::opt::ArgList &Args,
260263

261264
// 2. Get march (isa string) based on `-mcpu=`
262265
if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
263-
StringRef MArch = llvm::RISCV::getMArchFromMcpu(A->getValue());
266+
StringRef CPU = A->getValue();
267+
if (CPU == "native")
268+
CPU = llvm::sys::getHostCPUName();
269+
StringRef MArch = llvm::RISCV::getMArchFromMcpu(CPU);
264270
// Bypass if target cpu's default march is empty.
265271
if (MArch != "")
266272
return MArch;
@@ -299,3 +305,20 @@ StringRef riscv::getRISCVArch(const llvm::opt::ArgList &Args,
299305
return "rv64imafdc";
300306
}
301307
}
308+
309+
std::string riscv::getRISCVTargetCPU(const llvm::opt::ArgList &Args,
310+
const llvm::Triple &Triple) {
311+
std::string CPU;
312+
// If we have -mcpu, use that.
313+
if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
314+
CPU = A->getValue();
315+
316+
// Handle CPU name is 'native'.
317+
if (CPU == "native")
318+
CPU = llvm::sys::getHostCPUName();
319+
320+
if (!CPU.empty())
321+
return CPU;
322+
323+
return Triple.isRISCV64() ? "generic-rv64" : "generic-rv32";
324+
}

clang/lib/Driver/ToolChains/Arch/RISCV.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ StringRef getRISCVABI(const llvm::opt::ArgList &Args,
2626
const llvm::Triple &Triple);
2727
StringRef getRISCVArch(const llvm::opt::ArgList &Args,
2828
const llvm::Triple &Triple);
29+
std::string getRISCVTargetCPU(const llvm::opt::ArgList &Args,
30+
const llvm::Triple &Triple);
2931
} // end namespace riscv
3032
} // namespace tools
3133
} // end namespace driver

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2187,7 +2187,10 @@ void Clang::AddRISCVTargetArgs(const ArgList &Args,
21872187

21882188
if (const Arg *A = Args.getLastArg(options::OPT_mtune_EQ)) {
21892189
CmdArgs.push_back("-tune-cpu");
2190-
CmdArgs.push_back(A->getValue());
2190+
if (strcmp(A->getValue(), "native") == 0)
2191+
CmdArgs.push_back(Args.MakeArgString(llvm::sys::getHostCPUName()));
2192+
else
2193+
CmdArgs.push_back(A->getValue());
21912194
}
21922195
}
21932196

clang/lib/Driver/ToolChains/CommonArgs.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "Arch/M68k.h"
1313
#include "Arch/Mips.h"
1414
#include "Arch/PPC.h"
15+
#include "Arch/RISCV.h"
1516
#include "Arch/Sparc.h"
1617
#include "Arch/SystemZ.h"
1718
#include "Arch/VE.h"
@@ -432,9 +433,7 @@ std::string tools::getCPUName(const Driver &D, const ArgList &Args,
432433
return "ck810";
433434
case llvm::Triple::riscv32:
434435
case llvm::Triple::riscv64:
435-
if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
436-
return A->getValue();
437-
return "";
436+
return riscv::getRISCVTargetCPU(Args, T);
438437

439438
case llvm::Triple::bpfel:
440439
case llvm::Triple::bpfeb:

clang/test/Driver/riscv-cpus.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@
77
// MCPU-ROCKET64: "-nostdsysteminc" "-target-cpu" "rocket-rv64"
88
// MCPU-ROCKET64: "-target-feature" "+64bit"
99

10+
// We cannot check much for -mcpu=native, but it should be replaced by a valid CPU string.
11+
// RUN: %clang --target=riscv64 -### -c %s 2>&1 -mcpu=native | FileCheck -check-prefix=MCPU-NATIVE %s
12+
// MCPU-NATIVE-NOT: "-target-cpu" "native"
13+
1014
// RUN: %clang --target=riscv32 -### -c %s 2>&1 -mtune=rocket-rv32 | FileCheck -check-prefix=MTUNE-ROCKET32 %s
1115
// MTUNE-ROCKET32: "-tune-cpu" "rocket-rv32"
1216

@@ -26,6 +30,10 @@
2630
// RUN: %clang --target=riscv64 -### -c %s 2>&1 -mtune=rocket | FileCheck -check-prefix=MTUNE-ROCKET-64 %s
2731
// MTUNE-ROCKET-64: "-tune-cpu" "rocket"
2832

33+
// We cannot check much for -mtune=native, but it should be replaced by a valid CPU string.
34+
// RUN: %clang --target=riscv64 -### -c %s 2>&1 -mtune=native | FileCheck -check-prefix=MTUNE-NATIVE %s
35+
// MTUNE-NATIVE-NOT: "-tune-cpu" "native"
36+
2937
// mcpu with default march
3038
// RUN: %clang --target=riscv64 -### -c %s 2>&1 -mcpu=sifive-e20 | FileCheck -check-prefix=MCPU-SIFIVE-E20 %s
3139
// MCPU-SIFIVE-E20: "-nostdsysteminc" "-target-cpu" "sifive-e20"
@@ -130,10 +138,10 @@
130138
// Check failed cases
131139

132140
// RUN: %clang --target=riscv32 -### -c %s 2>&1 -mcpu=generic-rv321 | FileCheck -check-prefix=FAIL-MCPU-NAME %s
133-
// FAIL-MCPU-NAME: error: the clang compiler does not support '-mcpu=generic-rv321'
141+
// FAIL-MCPU-NAME: error: unsupported argument 'generic-rv321' to option '-mcpu='
134142

135143
// RUN: %clang --target=riscv32 -### -c %s 2>&1 -mcpu=generic-rv32 -march=rv64i | FileCheck -check-prefix=MISMATCH-ARCH %s
136-
// MISMATCH-ARCH: error: the clang compiler does not support '-mcpu=generic-rv32'
144+
// MISMATCH-ARCH: error: unsupported argument 'generic-rv32' to option '-mcpu='
137145

138146
// RUN: %clang --target=riscv32 -### -c %s 2>&1 -mcpu=generic-rv64 | FileCheck -check-prefix=MISMATCH-MCPU %s
139-
// MISMATCH-MCPU: error: the clang compiler does not support '-mcpu=generic-rv64'
147+
// MISMATCH-MCPU: error: unsupported argument 'generic-rv64' to option '-mcpu='

0 commit comments

Comments
 (0)