From 78a2847a783626e7bf83fa2f28485e7923f731de Mon Sep 17 00:00:00 2001 From: R Date: Fri, 16 Aug 2024 17:14:16 +0100 Subject: [PATCH] [RISCV] Allow YAML file to control multilib selection (#98856) This changes the bare-metal driver logic such that it _always_ tries multilib.yaml if it exists, and it falls back to the hardwired/default RISC-V multilib selection only if a multilib.yaml doesn't exist. In contrast, the current behavior is that RISC-V can never use multilib.yaml, but other targets will try it if it exists. The flags `-march=` and `-mabi=` are exposed for multilib.yaml to match on. There is no attempt to help YAML file creators to duplicate the existing hard-wired multilib reuse logic -- they will have to implement it using `Mappings`. This should be backwards-compatible with existing sysroots, as multilib.yaml was previously never used for RISC-V, and the behavior doesn't change after this PR if the file doesn't exist. (cherry picked from commit b221c37082707e35b492baa9ae8045c56b3ced0b) --- clang/lib/Driver/ToolChain.cpp | 19 +++++++++++++++++++ clang/lib/Driver/ToolChains/BareMetal.cpp | 16 +++++++++------- .../test/Driver/print-multi-selection-flags.c | 15 +++++++++++++++ 3 files changed, 43 insertions(+), 7 deletions(-) diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp index 20a555afb8092f..b42772c0169c51 100644 --- a/clang/lib/Driver/ToolChain.cpp +++ b/clang/lib/Driver/ToolChain.cpp @@ -9,6 +9,7 @@ #include "clang/Driver/ToolChain.h" #include "ToolChains/Arch/AArch64.h" #include "ToolChains/Arch/ARM.h" +#include "ToolChains/Arch/RISCV.h" #include "ToolChains/Clang.h" #include "ToolChains/CommonArgs.h" #include "ToolChains/Flang.h" @@ -43,6 +44,7 @@ #include "llvm/Support/VersionTuple.h" #include "llvm/Support/VirtualFileSystem.h" #include "llvm/TargetParser/AArch64TargetParser.h" +#include "llvm/TargetParser/RISCVISAInfo.h" #include "llvm/TargetParser/TargetParser.h" #include "llvm/TargetParser/Triple.h" #include @@ -258,6 +260,19 @@ static void getARMMultilibFlags(const Driver &D, } } +static void getRISCVMultilibFlags(const Driver &D, const llvm::Triple &Triple, + const llvm::opt::ArgList &Args, + Multilib::flags_list &Result) { + std::string Arch = riscv::getRISCVArch(Args, Triple); + // Canonicalize arch for easier matching + auto ISAInfo = llvm::RISCVISAInfo::parseArchString( + Arch, /*EnableExperimentalExtensions*/ true); + if (!llvm::errorToBool(ISAInfo.takeError())) + Result.push_back("-march=" + (*ISAInfo)->toString()); + + Result.push_back(("-mabi=" + riscv::getRISCVABI(Args, Triple)).str()); +} + Multilib::flags_list ToolChain::getMultilibFlags(const llvm::opt::ArgList &Args) const { using namespace clang::driver::options; @@ -278,6 +293,10 @@ ToolChain::getMultilibFlags(const llvm::opt::ArgList &Args) const { case llvm::Triple::thumbeb: getARMMultilibFlags(D, Triple, Args, Result); break; + case llvm::Triple::riscv32: + case llvm::Triple::riscv64: + getRISCVMultilibFlags(D, Triple, Args, Result); + break; default: break; } diff --git a/clang/lib/Driver/ToolChains/BareMetal.cpp b/clang/lib/Driver/ToolChains/BareMetal.cpp index 852e0442f50a23..95b4051cb74c71 100644 --- a/clang/lib/Driver/ToolChains/BareMetal.cpp +++ b/clang/lib/Driver/ToolChains/BareMetal.cpp @@ -218,17 +218,19 @@ static std::string computeBaseSysRoot(const Driver &D, void BareMetal::findMultilibs(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) { DetectedMultilibs Result; - if (isRISCVBareMetal(Triple)) { + // Look for a multilib.yaml before trying target-specific hardwired logic. + // If it exists, always do what it specifies. + llvm::SmallString<128> MultilibPath(computeBaseSysRoot(D, Triple)); + llvm::sys::path::append(MultilibPath, MultilibFilename); + if (D.getVFS().exists(MultilibPath)) { + findMultilibsFromYAML(*this, D, MultilibPath, Args, Result); + SelectedMultilibs = Result.SelectedMultilibs; + Multilibs = Result.Multilibs; + } else if (isRISCVBareMetal(Triple)) { if (findRISCVMultilibs(D, Triple, Args, Result)) { SelectedMultilibs = Result.SelectedMultilibs; Multilibs = Result.Multilibs; } - } else { - llvm::SmallString<128> MultilibPath(computeBaseSysRoot(D, Triple)); - llvm::sys::path::append(MultilibPath, MultilibFilename); - findMultilibsFromYAML(*this, D, MultilibPath, Args, Result); - SelectedMultilibs = Result.SelectedMultilibs; - Multilibs = Result.Multilibs; } } diff --git a/clang/test/Driver/print-multi-selection-flags.c b/clang/test/Driver/print-multi-selection-flags.c index 9f58d1b557fd74..2770a3ad5eaa1d 100644 --- a/clang/test/Driver/print-multi-selection-flags.c +++ b/clang/test/Driver/print-multi-selection-flags.c @@ -58,3 +58,18 @@ // RUN: %clang -print-multi-flags-experimental --target=aarch64-none-elf -march=armv9-a | FileCheck --check-prefix=CHECK-SVE2 %s // CHECK-SVE2: --target=aarch64-unknown-none-elf // CHECK-SVE2: -march=armv{{.*}}-a{{.*}}+simd{{.*}}+sve{{.*}}+sve2{{.*}} + +// RUN: %clang -print-multi-flags-experimental --target=riscv32-none-elf -march=rv32g | FileCheck --check-prefix=CHECK-RV32 %s +// CHECK-RV32: --target=riscv32-unknown-none-elf +// CHECK-RV32: -mabi=ilp32d +// CHECK-RV32: -march=rv32i{{[0-9]+p[0-9]+}}_m{{[0-9]+p[0-9]+}}_a{{[0-9]+p[0-9]+}}_f{{[0-9]+p[0-9]+}}_d{{[0-9]+p[0-9]+}}_zicsr{{[0-9]+p[0-9]+}}_zifencei{{[0-9]+p[0-9]+}}_zmmul{{[0-9]+p[0-9]+}} + +// RUN: %clang -print-multi-flags-experimental --target=riscv64-none-elf -march=rv64g | FileCheck --check-prefix=CHECK-RV64 %s +// CHECK-RV64: --target=riscv64-unknown-none-elf +// CHECK-RV64: -mabi=lp64d +// CHECK-RV64: -march=rv64i{{[0-9]+p[0-9]+}}_m{{[0-9]+p[0-9]+}}_a{{[0-9]+p[0-9]+}}_f{{[0-9]+p[0-9]+}}_d{{[0-9]+p[0-9]+}}_zicsr{{[0-9]+p[0-9]+}}_zifencei{{[0-9]+p[0-9]+}}_zmmul{{[0-9]+p[0-9]+}} + +// RUN: %clang -print-multi-flags-experimental --target=riscv32-none-elf -march=rv32e_zicsr_c | FileCheck --check-prefix=CHECK-RV32E-ORDER %s +// CHECK-RV32E-ORDER: --target=riscv32-unknown-none-elf +// CHECK-RV32E-ORDER: -mabi=ilp32e +// CHECK-RV32E-ORDER: -march=rv32e{{[0-9]+p[0-9]+}}_c{{[0-9]+p[0-9]+}}_zicsr{{[0-9]+p[0-9]+}}