Skip to content

Commit c6f1d7e

Browse files
ArcaneNibblenashif
authored andcommitted
[RISCV] Allow YAML file to control multilib selection (llvm#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 b221c37)
1 parent 010636d commit c6f1d7e

File tree

3 files changed

+43
-7
lines changed

3 files changed

+43
-7
lines changed

clang/lib/Driver/ToolChain.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "clang/Driver/ToolChain.h"
1010
#include "ToolChains/Arch/AArch64.h"
1111
#include "ToolChains/Arch/ARM.h"
12+
#include "ToolChains/Arch/RISCV.h"
1213
#include "ToolChains/Clang.h"
1314
#include "ToolChains/CommonArgs.h"
1415
#include "ToolChains/Flang.h"
@@ -43,6 +44,7 @@
4344
#include "llvm/Support/VersionTuple.h"
4445
#include "llvm/Support/VirtualFileSystem.h"
4546
#include "llvm/TargetParser/AArch64TargetParser.h"
47+
#include "llvm/TargetParser/RISCVISAInfo.h"
4648
#include "llvm/TargetParser/TargetParser.h"
4749
#include "llvm/TargetParser/Triple.h"
4850
#include <cassert>
@@ -258,6 +260,19 @@ static void getARMMultilibFlags(const Driver &D,
258260
}
259261
}
260262

263+
static void getRISCVMultilibFlags(const Driver &D, const llvm::Triple &Triple,
264+
const llvm::opt::ArgList &Args,
265+
Multilib::flags_list &Result) {
266+
std::string Arch = riscv::getRISCVArch(Args, Triple);
267+
// Canonicalize arch for easier matching
268+
auto ISAInfo = llvm::RISCVISAInfo::parseArchString(
269+
Arch, /*EnableExperimentalExtensions*/ true);
270+
if (!llvm::errorToBool(ISAInfo.takeError()))
271+
Result.push_back("-march=" + (*ISAInfo)->toString());
272+
273+
Result.push_back(("-mabi=" + riscv::getRISCVABI(Args, Triple)).str());
274+
}
275+
261276
Multilib::flags_list
262277
ToolChain::getMultilibFlags(const llvm::opt::ArgList &Args) const {
263278
using namespace clang::driver::options;
@@ -278,6 +293,10 @@ ToolChain::getMultilibFlags(const llvm::opt::ArgList &Args) const {
278293
case llvm::Triple::thumbeb:
279294
getARMMultilibFlags(D, Triple, Args, Result);
280295
break;
296+
case llvm::Triple::riscv32:
297+
case llvm::Triple::riscv64:
298+
getRISCVMultilibFlags(D, Triple, Args, Result);
299+
break;
281300
default:
282301
break;
283302
}

clang/lib/Driver/ToolChains/BareMetal.cpp

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -218,17 +218,19 @@ static std::string computeBaseSysRoot(const Driver &D,
218218
void BareMetal::findMultilibs(const Driver &D, const llvm::Triple &Triple,
219219
const ArgList &Args) {
220220
DetectedMultilibs Result;
221-
if (isRISCVBareMetal(Triple)) {
221+
// Look for a multilib.yaml before trying target-specific hardwired logic.
222+
// If it exists, always do what it specifies.
223+
llvm::SmallString<128> MultilibPath(computeBaseSysRoot(D, Triple));
224+
llvm::sys::path::append(MultilibPath, MultilibFilename);
225+
if (D.getVFS().exists(MultilibPath)) {
226+
findMultilibsFromYAML(*this, D, MultilibPath, Args, Result);
227+
SelectedMultilibs = Result.SelectedMultilibs;
228+
Multilibs = Result.Multilibs;
229+
} else if (isRISCVBareMetal(Triple)) {
222230
if (findRISCVMultilibs(D, Triple, Args, Result)) {
223231
SelectedMultilibs = Result.SelectedMultilibs;
224232
Multilibs = Result.Multilibs;
225233
}
226-
} else {
227-
llvm::SmallString<128> MultilibPath(computeBaseSysRoot(D, Triple));
228-
llvm::sys::path::append(MultilibPath, MultilibFilename);
229-
findMultilibsFromYAML(*this, D, MultilibPath, Args, Result);
230-
SelectedMultilibs = Result.SelectedMultilibs;
231-
Multilibs = Result.Multilibs;
232234
}
233235
}
234236

clang/test/Driver/print-multi-selection-flags.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,3 +58,18 @@
5858
// RUN: %clang -print-multi-flags-experimental --target=aarch64-none-elf -march=armv9-a | FileCheck --check-prefix=CHECK-SVE2 %s
5959
// CHECK-SVE2: --target=aarch64-unknown-none-elf
6060
// CHECK-SVE2: -march=armv{{.*}}-a{{.*}}+simd{{.*}}+sve{{.*}}+sve2{{.*}}
61+
62+
// RUN: %clang -print-multi-flags-experimental --target=riscv32-none-elf -march=rv32g | FileCheck --check-prefix=CHECK-RV32 %s
63+
// CHECK-RV32: --target=riscv32-unknown-none-elf
64+
// CHECK-RV32: -mabi=ilp32d
65+
// 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]+}}
66+
67+
// RUN: %clang -print-multi-flags-experimental --target=riscv64-none-elf -march=rv64g | FileCheck --check-prefix=CHECK-RV64 %s
68+
// CHECK-RV64: --target=riscv64-unknown-none-elf
69+
// CHECK-RV64: -mabi=lp64d
70+
// 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]+}}
71+
72+
// RUN: %clang -print-multi-flags-experimental --target=riscv32-none-elf -march=rv32e_zicsr_c | FileCheck --check-prefix=CHECK-RV32E-ORDER %s
73+
// CHECK-RV32E-ORDER: --target=riscv32-unknown-none-elf
74+
// CHECK-RV32E-ORDER: -mabi=ilp32e
75+
// CHECK-RV32E-ORDER: -march=rv32e{{[0-9]+p[0-9]+}}_c{{[0-9]+p[0-9]+}}_zicsr{{[0-9]+p[0-9]+}}

0 commit comments

Comments
 (0)