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 getRISCVTuneCPU(const llvm::opt::ArgList &Args, + const llvm::Triple &Triple); std::string getRISCVTargetCPU(const llvm::opt::ArgList &Args, const llvm::Triple &Triple); } // end namespace riscv 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 @@ -305,6 +305,24 @@ } } +std::string riscv::getRISCVTuneCPU(const llvm::opt::ArgList &Args, + const llvm::Triple &Triple) { + assert(Triple.isRISCV() && "Unexpected triple"); + + if (const Arg *A = Args.getLastArg(options::OPT_mtune_EQ)) { + if (strcmp(A->getValue(), "native") == 0) + return llvm::sys::getHostCPUName().str(); + + return A->getValue(); + } + + std::string CPU = getRISCVTargetCPU(Args, Triple); + if (!CPU.empty()) + return CPU; + + return std::string(); +} + std::string riscv::getRISCVTargetCPU(const llvm::opt::ArgList &Args, const llvm::Triple &Triple) { std::string CPU; 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 @@ -2099,12 +2099,12 @@ options::OPT_mno_implicit_float, true)) CmdArgs.push_back("-no-implicit-float"); - if (const Arg *A = Args.getLastArg(options::OPT_mtune_EQ)) { + std::string TuneCpu = + riscv::getRISCVTuneCPU(Args, getToolChain().getTriple()); + + if (!TuneCpu.empty()) { 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()); + CmdArgs.push_back(Args.MakeArgString(TuneCpu)); } } @@ -5453,11 +5453,14 @@ Args.AddLastArg(CmdArgs, options::OPT_mtls_size_EQ); } - // Add the target cpu - std::string CPU = getCPUName(D, Args, Triple, /*FromAs*/ false); - if (!CPU.empty()) { - CmdArgs.push_back("-target-cpu"); - CmdArgs.push_back(Args.MakeArgString(CPU)); + // RISC-V will handle -mcpu option in Clang::AddRISCVTargetArgs. + if (!Triple.isRISCV()) { + // Add the target cpu + std::string CPU = getCPUName(D, Args, Triple, /*FromAs*/ false); + if (!CPU.empty()) { + CmdArgs.push_back("-target-cpu"); + CmdArgs.push_back(Args.MakeArgString(CPU)); + } } RenderTargetOptions(Triple, Args, KernelOrKext, CmdArgs); @@ -7807,6 +7810,14 @@ CmdArgs.push_back("-target-abi"); CmdArgs.push_back(ABIName.data()); + + std::string TuneCpu = + riscv::getRISCVTuneCPU(Args, getToolChain().getTriple()); + + if (!TuneCpu.empty()) { + CmdArgs.push_back("-tune-cpu"); + CmdArgs.push_back(Args.MakeArgString(TuneCpu)); + } } void ClangAs::ConstructJob(Compilation &C, const JobAction &JA, @@ -7850,11 +7861,14 @@ CmdArgs.push_back("-main-file-name"); CmdArgs.push_back(Clang::getBaseInputName(Args, Input)); - // Add the target cpu - std::string CPU = getCPUName(D, Args, Triple, /*FromAs*/ true); - if (!CPU.empty()) { - CmdArgs.push_back("-target-cpu"); - CmdArgs.push_back(Args.MakeArgString(CPU)); + // RISC-V will handle -mcpu in ClangAs::AddRISCVTargetArgs. + if (!Triple.isRISCV()) { + // Add the target cpu + std::string CPU = getCPUName(D, Args, Triple, /*FromAs*/ true); + if (!CPU.empty()) { + CmdArgs.push_back("-target-cpu"); + CmdArgs.push_back(Args.MakeArgString(CPU)); + } } // Add the target features 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 @@ -1,21 +1,21 @@ // Check target CPUs are correctly passed. // RUN: %clang --target=riscv32 -### -c %s 2>&1 -mcpu=rocket-rv32 | FileCheck -check-prefix=MCPU-ROCKET32 %s -// MCPU-ROCKET32: "-nostdsysteminc" "-target-cpu" "rocket-rv32" +// MCPU-ROCKET32: "-tune-cpu" "rocket-rv32" // RUN: %clang --target=riscv64 -### -c %s 2>&1 -mcpu=rocket-rv64 | FileCheck -check-prefix=MCPU-ROCKET64 %s -// MCPU-ROCKET64: "-nostdsysteminc" "-target-cpu" "rocket-rv64" // MCPU-ROCKET64: "-target-feature" "+64bit" +// MCPU-ROCKET64: "-tune-cpu" "rocket-rv64" // RUN: %clang --target=riscv32 -### -c %s 2>&1 -mcpu=syntacore-scr1-base | FileCheck -check-prefix=MCPU-SYNTACORE-SCR1-BASE %s -// MCPU-SYNTACORE-SCR1-BASE: "-target-cpu" "syntacore-scr1-base" // MCPU-SYNTACORE-SCR1-BASE: "-target-feature" "+c" "-target-feature" "-64bit" // MCPU-SYNTACORE-SCR1-BASE: "-target-abi" "ilp32" +// MCPU-SYNTACORE-SCR1-BASE: "-tune-cpu" "syntacore-scr1-base" // RUN: %clang --target=riscv32 -### -c %s 2>&1 -mcpu=syntacore-scr1-max | FileCheck -check-prefix=MCPU-SYNTACORE-SCR1-MAX %s -// MCPU-SYNTACORE-SCR1-MAX: "-target-cpu" "syntacore-scr1-max" // MCPU-SYNTACORE-SCR1-MAX: "-target-feature" "+m" "-target-feature" "+c" "-target-feature" "-64bit" // MCPU-SYNTACORE-SCR1-MAX: "-target-abi" "ilp32" +// MCPU-SYNTACORE-SCR1-MAX: "-tune-cpu" "syntacore-scr1-max" // 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 @@ -52,90 +52,91 @@ // 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" // MCPU-SIFIVE-E20: "-target-feature" "+m" "-target-feature" "+c" // MCPU-SIFIVE-E20: "-target-abi" "ilp32" +// MCPU-SIFIVE-E20: "-tune-cpu" "sifive-e20" // mcpu with default march // RUN: %clang --target=riscv64 -### -c %s 2>&1 -mcpu=sifive-e21 | FileCheck -check-prefix=MCPU-SIFIVE-E21 %s -// MCPU-SIFIVE-E21: "-nostdsysteminc" "-target-cpu" "sifive-e21" // MCPU-SIFIVE-E21: "-target-feature" "+m" "-target-feature" "+a" "-target-feature" "+c" // MCPU-SIFIVE-E21: "-target-abi" "ilp32" +// MCPU-SIFIVE-E21: "-tune-cpu" "sifive-e21" // mcpu with default march // RUN: %clang --target=riscv64 -### -c %s 2>&1 -mcpu=sifive-e24 | FileCheck -check-prefix=MCPU-SIFIVE-E24 %s -// MCPU-SIFIVE-E24: "-nostdsysteminc" "-target-cpu" "sifive-e24" // MCPU-SIFIVE-E24: "-target-feature" "+m" "-target-feature" "+a" "-target-feature" "+f" // MCPU-SIFIVE-E24: "-target-feature" "+c" // MCPU-SIFIVE-E24: "-target-abi" "ilp32" +// MCPU-SIFIVE-E24: "-tune-cpu" "sifive-e24" // mcpu with default march // RUN: %clang --target=riscv64 -### -c %s 2>&1 -mcpu=sifive-e34 | FileCheck -check-prefix=MCPU-SIFIVE-E34 %s -// MCPU-SIFIVE-E34: "-nostdsysteminc" "-target-cpu" "sifive-e34" // MCPU-SIFIVE-E34: "-target-feature" "+m" "-target-feature" "+a" "-target-feature" "+f" // MCPU-SIFIVE-E34: "-target-feature" "+c" // MCPU-SIFIVE-E34: "-target-abi" "ilp32" +// MCPU-SIFIVE-E34: "-tune-cpu" "sifive-e34" // mcpu with mabi option // RUN: %clang --target=riscv64 -### -c %s 2>&1 -mcpu=sifive-s21 -mabi=lp64 | FileCheck -check-prefix=MCPU-ABI-SIFIVE-S21 %s -// MCPU-ABI-SIFIVE-S21: "-nostdsysteminc" "-target-cpu" "sifive-s21" // MCPU-ABI-SIFIVE-S21: "-target-feature" "+m" "-target-feature" "+a" // MCPU-ABI-SIFIVE-S21: "-target-feature" "+c" "-target-feature" "+64bit" // MCPU-ABI-SIFIVE-S21: "-target-abi" "lp64" +// MCPU-ABI-SIFIVE-S21: "-tune-cpu" "sifive-s21" // mcpu with mabi option // RUN: %clang --target=riscv64 -### -c %s 2>&1 -mcpu=sifive-s51 -mabi=lp64 | FileCheck -check-prefix=MCPU-ABI-SIFIVE-S51 %s -// MCPU-ABI-SIFIVE-S51: "-nostdsysteminc" "-target-cpu" "sifive-s51" // MCPU-ABI-SIFIVE-S51: "-target-feature" "+m" "-target-feature" "+a" // MCPU-ABI-SIFIVE-S51: "-target-feature" "+c" "-target-feature" "+64bit" // MCPU-ABI-SIFIVE-S51: "-target-abi" "lp64" +// MCPU-ABI-SIFIVE-S51: "-tune-cpu" "sifive-s51" // mcpu with default march // RUN: %clang --target=riscv64 -### -c %s 2>&1 -mcpu=sifive-s54 | FileCheck -check-prefix=MCPU-SIFIVE-S54 %s -// MCPU-SIFIVE-S54: "-nostdsysteminc" "-target-cpu" "sifive-s54" // MCPU-SIFIVE-S54: "-target-feature" "+m" "-target-feature" "+a" "-target-feature" "+f" "-target-feature" "+d" // MCPU-SIFIVE-S54: "-target-feature" "+c" "-target-feature" "+64bit" // MCPU-SIFIVE-S54: "-target-abi" "lp64d" +// MCPU-SIFIVE-S54: "-tune-cpu" "sifive-s54" // mcpu with mabi option // RUN: %clang --target=riscv64 -### -c %s 2>&1 -mcpu=sifive-s76 | FileCheck -check-prefix=MCPU-SIFIVE-S76 %s -// MCPU-SIFIVE-S76: "-nostdsysteminc" "-target-cpu" "sifive-s76" // MCPU-SIFIVE-S76: "-target-feature" "+m" "-target-feature" "+a" "-target-feature" "+f" "-target-feature" "+d" // MCPU-SIFIVE-S76: "-target-feature" "+c" "-target-feature" "+64bit" // MCPU-SIFIVE-S76: "-target-abi" "lp64d" +// MCPU-SIFIVE-S76: "-tune-cpu" "sifive-s76" // mcpu with default march // RUN: %clang --target=riscv64 -### -c %s 2>&1 -mcpu=sifive-u54 | FileCheck -check-prefix=MCPU-SIFIVE-U54 %s -// MCPU-SIFIVE-U54: "-nostdsysteminc" "-target-cpu" "sifive-u54" // MCPU-SIFIVE-U54: "-target-feature" "+m" "-target-feature" "+a" "-target-feature" "+f" "-target-feature" "+d" // MCPU-SIFIVE-U54: "-target-feature" "+c" "-target-feature" "+64bit" // MCPU-SIFIVE-U54: "-target-abi" "lp64d" +// MCPU-SIFIVE-U54: "-tune-cpu" "sifive-u54" // mcpu with mabi option // RUN: %clang --target=riscv64 -### -c %s 2>&1 -mcpu=sifive-u54 -mabi=lp64 | FileCheck -check-prefix=MCPU-ABI-SIFIVE-U54 %s -// MCPU-ABI-SIFIVE-U54: "-nostdsysteminc" "-target-cpu" "sifive-u54" // MCPU-ABI-SIFIVE-U54: "-target-feature" "+m" "-target-feature" "+a" "-target-feature" "+f" "-target-feature" "+d" // MCPU-ABI-SIFIVE-U54: "-target-feature" "+c" "-target-feature" "+64bit" // MCPU-ABI-SIFIVE-U54: "-target-abi" "lp64" +// MCPU-ABI-SIFIVE-U54: "-tune-cpu" "sifive-u54" // mcpu with default march // RUN: %clang --target=riscv64 -### -c %s 2>&1 -mcpu=sifive-e76 | FileCheck -check-prefix=MCPU-SIFIVE-E76 %s -// MCPU-SIFIVE-E76: "-nostdsysteminc" "-target-cpu" "sifive-e76" // MCPU-SIFIVE-E76: "-target-feature" "+m" "-target-feature" "+a" "-target-feature" "+f" // MCPU-SIFIVE-E76: "-target-feature" "+c" // MCPU-SIFIVE-E76: "-target-abi" "ilp32" +// MCPU-SIFIVE-E76: "-tune-cpu" "sifive-e76" // mcpu with mabi option // RUN: %clang --target=riscv64 -### -c %s 2>&1 -mcpu=sifive-u74 -mabi=lp64 | FileCheck -check-prefix=MCPU-ABI-SIFIVE-U74 %s -// MCPU-ABI-SIFIVE-U74: "-nostdsysteminc" "-target-cpu" "sifive-u74" // MCPU-ABI-SIFIVE-U74: "-target-feature" "+m" "-target-feature" "+a" "-target-feature" "+f" "-target-feature" "+d" // MCPU-ABI-SIFIVE-U74: "-target-feature" "+c" "-target-feature" "+64bit" // MCPU-ABI-SIFIVE-U74: "-target-abi" "lp64" +// MCPU-ABI-SIFIVE-U74: "-tune-cpu" "sifive-u74" // march overwrite mcpu's default march // RUN: %clang --target=riscv32 -### -c %s 2>&1 -mcpu=sifive-e31 -march=rv32imc | FileCheck -check-prefix=MCPU-MARCH %s -// MCPU-MARCH: "-nostdsysteminc" "-target-cpu" "sifive-e31" "-target-feature" "+m" "-target-feature" "+c" +// MCPU-MARCH: "-target-feature" "+m" "-target-feature" "+c" // MCPU-MARCH: "-target-abi" "ilp32" +// MCPU-MARCH: "-tune-cpu" "sifive-e31" // Check interaction between mcpu and mtune, mtune won't affect arch related // target feature, but mcpu will. @@ -144,9 +145,8 @@ // should not enabled. // // RUN: %clang --target=riscv32 -### -c %s 2>&1 -mcpu=sifive-e31 -mtune=sifive-e76 | FileCheck -check-prefix=MTUNE-E31-MCPU-E76 %s -// MTUNE-E31-MCPU-E76: "-target-cpu" "sifive-e31" // MTUNE-E31-MCPU-E76-NOT: "-target-feature" "+f" -// MTUNE-E31-MCPU-E76-SAME: "-target-feature" "+m" +// MTUNE-E31-MCPU-E76: "-target-feature" "+m" // MTUNE-E31-MCPU-E76-SAME: "-target-feature" "+a" // MTUNE-E31-MCPU-E76-SAME: "-target-feature" "+c" // MTUNE-E31-MCPU-E76-SAME: "-tune-cpu" "sifive-e76" diff --git a/clang/test/Driver/riscv-march-mcpu-mtune.c b/clang/test/Driver/riscv-march-mcpu-mtune.c new file mode 100644 --- /dev/null +++ b/clang/test/Driver/riscv-march-mcpu-mtune.c @@ -0,0 +1,82 @@ +// Check the priority between -mcpu, -mtune and -march + +// sifive-e76 is rv32imafc and sifive-e31 is rv32imac + +// -mcpu, -mtune and -march are not given, pipeline model and arch ext. use +// default setting. +// RUN: %clang --target=riscv32-elf -### -c %s 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK-DEFAULT %s +// CHECK-DEFAULT: "-target-feature" "+m" "-target-feature" "+a" +// CHECK-DEFAULT: "-target-feature" "+c" +// CHECK-DEFAULT: "-tune-cpu" "generic-rv32" +// CHECK-DEFAULT-NOT: "-target-cpu" + +// -mtune is given, pipeline model take from -mtune, arch ext. use +// default setting. +// RUN: %clang --target=riscv32 -mtune=sifive-e76 -### -c %s 2>&1 \ +// RUN: | FileCheck -check-prefix=MTUNE-E76 %s +// MTUNE-E76: "-target-feature" "+m" "-target-feature" "+a" +// MTUNE-E76: "-target-feature" "+c" +// MTUNE-E76: "-tune-cpu" "sifive-e76" +// MTUNE-E76-NOT: "-target-cpu" +// MTUNE-E76-NOT: "-target-feature" "+f" + +// -march is given, arch ext. take from -march, pipeline model use +// default setting. +// RUN: %clang --target=riscv32 -### -c %s -march=rv32imafdc 2>&1 \ +// RUN: | FileCheck -check-prefix=MARCH-RV32IMAFDC %s +// MARCH-RV32IMAFDC: "-target-feature" "+m" "-target-feature" "+a" +// MARCH-RV32IMAFDC: "-target-feature" "+f" "-target-feature" "+d" +// MARCH-RV32IMAFDC: "-target-feature" "+c" +// MARCH-RV32IMAFDC: "-tune-cpu" "generic-rv32" +// MARCH-RV32IMAFDC-NOT: "-target-cpu" + +// -mcpu is given, pipeline model and arch ext. from -mcpu. +// RUN: %clang --target=riscv32 -### -c %s -mcpu=sifive-e76 2>&1 \ +// RUN: | FileCheck -check-prefix=MCPU-E76 %s +// MCPU-E76: "-target-feature" "+m" "-target-feature" "+a" +// MCPU-E76: "-target-feature" "+f" "-target-feature" "+c" +// MCPU-E76: "-tune-cpu" "sifive-e76" +// MCPU-E76-NOT: "-target-cpu" + +// -mcpu and -mtune are given, so pipeline model take from -mtune, and arch ext. +// take from -mcpu since -march is not given. +// RUN: %clang --target=riscv32 -### -c %s -mcpu=sifive-e76 -mtune=sifive-e31 2>&1 \ +// RUN: | FileCheck -check-prefix=MCPU-E76-MTUNE-E31 %s +// MCPU-E76-MTUNE-E31: "-target-feature" "+m" "-target-feature" "+a" +// MCPU-E76-MTUNE-E31: "-target-feature" "+f" "-target-feature" "+c" +// MCPU-E76-MTUNE-E31: "-tune-cpu" "sifive-e31" +// MCPU-E76-MTUNE-E31-NOT: "-tune-cpu" "sifive-e76" +// MCPU-E76-MTUNE-E31-NOT: "-target-cpu" + +// RUN: %clang --target=riscv32 -### -c %s -mtune=sifive-e76 -mcpu=sifive-e31 2>&1 \ +// RUN: | FileCheck -check-prefix=MTUNE-E76-MCPU-E31 %s +// MTUNE-E76-MCPU-E31: "-target-feature" "+m" "-target-feature" "+a" +// MTUNE-E76-MCPU-E31: "-target-feature" "+c" +// MTUNE-E76-MCPU-E31: "-tune-cpu" "sifive-e76" +// MTUNE-E76-MCPU-E31-NOT: "-tune-cpu" "sifive-e31" +// MTUNE-E76-MCPU-E31-NOT: "-target-cpu" +// MTUNE-E76-MCPU-E31-NOT: "-target-feature" "+f" + +// -mcpu and -march are given, so pipeline model take from -mcpu since -mtune is +// not given, and arch ext. take from -march. +// RUN: %clang --target=riscv32 -### -c %s -mcpu=sifive-e31 -march=rv32ic 2>&1 \ +// RUN: | FileCheck -check-prefix=MCPU-E31-MARCH-RV32I %s +// MCPU-E31-MARCH-RV32I: "-target-feature" "+c" +// MCPU-E31-MARCH-RV32I: "-tune-cpu" "sifive-e31" +// MCPU-E31-MARCH-RV32I-NOT: "-target-cpu" +// MCPU-E31-MARCH-RV32I-NOT: "-target-feature" "+m" +// MCPU-E31-MARCH-RV32I-NOT: "-target-feature" "+a" +// MCPU-E31-MARCH-RV32I-NOT: "-target-feature" "+f" + +// -mcpu, -march and -mtune are given, so pipeline model take from -mtune +// and arch ext. take from -march, -mcpu is unused. +// RUN: %clang --target=riscv32 -### -c %s -mcpu=sifive-e31 -mtune=sifive-e76 -march=rv32ic 2>&1 \ +// RUN: | FileCheck -check-prefix=MCPU-E31-MTUNE-E76-MARCH-RV32I %s +// MCPU-E31-MTUNE-E76-MARCH-RV32I: "-target-feature" "+c" +// MCPU-E31-MTUNE-E76-MARCH-RV32I: "-tune-cpu" "sifive-e76" +// MCPU-E31-MTUNE-E76-MARCH-RV32I-NOT: "-target-cpu" +// MCPU-E31-MTUNE-E76-MARCH-RV32I-NOT: "-tune-cpu" "sifive-e31" +// MCPU-E31-MTUNE-E76-MARCH-RV32I-NOT: "-target-feature" "+m" +// MCPU-E31-MTUNE-E76-MARCH-RV32I-NOT: "-target-feature" "+a" +// MCPU-E31-MTUNE-E76-MARCH-RV32I-NOT: "-target-feature" "+f"