https://github.com/MythreyaK updated https://github.com/llvm/llvm-project/pull/227965
>From ea6ec604e122df7ae834f6664046cdd63403ad79 Mon Sep 17 00:00:00 2001 From: Mythreya Kuricheti <[email protected]> Date: Thu, 1 Oct 2026 05:43:57 +0000 Subject: [PATCH 1/3] [clang]: baremetal `multilib.yaml` discovery Clang does not auto-detect `multilib.yaml` in the triple dirs correctly because baremetal targets use `SYSROOT` as a fallback dir, unlike the linux `multilib.yaml` discovery, which correctly searches the triple-specific dirs first (`FallbackDir` dir is unset). `findMultilibsYAML` treats `FallbackDir` and `getStdlibPath()` as mutually-exclusive settings. Because baremetal uses a fallback path `SYSROOT/multilib.yaml`, `getStdlibPath()` is never searched (`SYSROOT/usr/lib/<triple>/multilib.yaml`). With this change to shared `Toolchain.cpp`, baremetal targets look for a `multilib.yaml` in the triple-specific dirs first, before attempting to locate it in SYSROOT. Attempt triple-specific dirs first if present, `FallbackDir` otherwise. --- clang/lib/Driver/ToolChain.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp index 255a9c9602b54..037e0b5477348 100644 --- a/clang/lib/Driver/ToolChain.cpp +++ b/clang/lib/Driver/ToolChain.cpp @@ -202,10 +202,10 @@ ToolChain::findMultilibsYAML(const llvm::opt::ArgList &Args, const Driver &D, } SmallString<128> MultilibPath; - if (!FallbackDir.empty()) - MultilibPath = FallbackDir; - else if (std::optional<std::string> StdlibDir = getStdlibPath()) + if (std::optional<std::string> StdlibDir = getStdlibPath()) MultilibPath = *StdlibDir; + else if (!FallbackDir.empty()) + MultilibPath = FallbackDir; else return std::nullopt; llvm::sys::path::append(MultilibPath, "multilib.yaml"); >From c1007519ebb77271b6e41bad45eb62fb69e759b0 Mon Sep 17 00:00:00 2001 From: Mythreya Kuricheti <[email protected]> Date: Thu, 1 Oct 2026 08:46:26 +0000 Subject: [PATCH 2/3] add lit test --- .../baremetal-multilib-autodiscovery.yaml | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 clang/test/Driver/baremetal-multilib-autodiscovery.yaml diff --git a/clang/test/Driver/baremetal-multilib-autodiscovery.yaml b/clang/test/Driver/baremetal-multilib-autodiscovery.yaml new file mode 100644 index 0000000000000..5472a3ef215d7 --- /dev/null +++ b/clang/test/Driver/baremetal-multilib-autodiscovery.yaml @@ -0,0 +1,64 @@ +# UNSUPPORTED: system-windows + +# Test that baremetal toolchain discovers multilib.yaml in per-triple dirs +# when no sysroot-level multilib.yaml exists. This tests the fallthrough +# from FallbackDir to getStdlibPath() in findMultilibsYAML. + +## Test 1: per-triple autodiscovery (no sysroot-level YAML) +# +# getStdlibPath() = D.Dir/../lib/<triple> = %t/a/sysroot/usr/lib/riscv64-unknown-none-elf +# FallbackDir = D.SysRoot = %t/a/sysroot (no multilib.yaml here) +# +# RUN: mkdir -p %t/a/sysroot/usr/bin +# RUN: mkdir -p %t/a/sysroot/usr/lib/riscv64-unknown-none-elf/rv64gc/lib +# RUN: cp %s %t/a/sysroot/usr/lib/riscv64-unknown-none-elf/multilib.yaml +# RUN: %clang -no-canonical-prefixes -print-multi-lib 2>&1 \ +# RUN: --target=riscv64-unknown-none-elf -march=rv64gc \ +# RUN: --sysroot=%t/a/sysroot \ +# RUN: -ccc-install-dir %t/a/sysroot/usr/bin \ +# RUN: | FileCheck --check-prefix=CHECK-FOUND %s +# CHECK-FOUND: rv64gc/lib;@-target=riscv64-unknown-none-elf@mabi=lp64d@march=rv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_zicsr2p0_zifencei2p0_zmmul1p0_zaamo1p0_zalrsc1p0_zca1p0_zcd1p0 + +# RUN: %clang -no-canonical-prefixes -print-multi-directory 2>&1 \ +# RUN: --target=riscv64-unknown-none-elf -march=rv64gc \ +# RUN: --sysroot=%t/a/sysroot \ +# RUN: -ccc-install-dir %t/a/sysroot/usr/bin \ +# RUN: | FileCheck --check-prefix=CHECK-DIR %s +# CHECK-DIR: rv64gc/lib + +## Test 2: sysroot-level YAML still works via FallbackDir +# +# Place YAML at sysroot root only, no per-triple YAML. +# +# RUN: mkdir -p %t/b/sysroot/usr/bin +# RUN: cp %s %t/b/sysroot/multilib.yaml +# RUN: %clang -no-canonical-prefixes -print-multi-lib 2>&1 \ +# RUN: --target=riscv64-unknown-none-elf -march=rv64gc \ +# RUN: --sysroot=%t/b/sysroot \ +# RUN: -ccc-install-dir %t/b/sysroot/usr/bin \ +# RUN: | FileCheck --check-prefix=CHECK-SYSROOT %s +# CHECK-SYSROOT: rv64gc/lib;@-target=riscv64-unknown-none-elf@mabi=lp64d@march=rv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_zicsr2p0_zifencei2p0_zmmul1p0_zaamo1p0_zalrsc1p0_zca1p0_zcd1p0 + +## Test 3: per-triple takes priority over sysroot-level +# +# Both exist: per-triple has real YAML, sysroot root has empty YAML. +# getStdlibPath() is tried before FallbackDir, so per-triple wins. +# +# RUN: mkdir -p %t/c/sysroot/usr/bin +# RUN: mkdir -p %t/c/sysroot/usr/lib/riscv64-unknown-none-elf/rv64gc/lib +# RUN: cp %s %t/c/sysroot/usr/lib/riscv64-unknown-none-elf/multilib.yaml +# RUN: cp %S/Inputs/multilib/empty.yaml %t/c/sysroot/multilib.yaml +# RUN: %clang -no-canonical-prefixes -print-multi-lib 2>&1 \ +# RUN: --target=riscv64-unknown-none-elf -march=rv64gc \ +# RUN: --sysroot=%t/c/sysroot \ +# RUN: -ccc-install-dir %t/c/sysroot/usr/bin \ +# RUN: | FileCheck --check-prefix=CHECK-PRIORITY %s +# CHECK-PRIORITY: rv64gc/lib;@-target=riscv64-unknown-none-elf@mabi=lp64d@march=rv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_zicsr2p0_zifencei2p0_zmmul1p0_zaamo1p0_zalrsc1p0_zca1p0_zcd1p0 + +--- +MultilibVersion: 1.0 + +Variants: +- Dir: rv64gc/lib + Flags: [--target=riscv64-unknown-none-elf, -mabi=lp64d, + -march=rv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_zicsr2p0_zifencei2p0_zmmul1p0_zaamo1p0_zalrsc1p0_zca1p0_zcd1p0] >From 766dfab7e90ce011f96c3cd179ef95c21bc17100 Mon Sep 17 00:00:00 2001 From: Mythreya Kuricheti <[email protected]> Date: Sat, 10 Oct 2026 01:41:05 -0700 Subject: [PATCH 3/3] code review - Ensure that `multilib.yaml` existing exists before committing to it - Add a test for the case that @vhscampos caught during review --- clang/lib/Driver/ToolChain.cpp | 30 ++++++++++++------- .../baremetal-multilib-autodiscovery.yaml | 30 ++++++++++++++----- 2 files changed, 42 insertions(+), 18 deletions(-) diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp index 037e0b5477348..84724440cb812 100644 --- a/clang/lib/Driver/ToolChain.cpp +++ b/clang/lib/Driver/ToolChain.cpp @@ -52,6 +52,7 @@ #include <cassert> #include <cstddef> #include <cstring> +#include <optional> #include <string> using namespace clang; @@ -201,17 +202,24 @@ ToolChain::findMultilibsYAML(const llvm::opt::ArgList &Args, const Driver &D, return std::string(MultilibPath); } - SmallString<128> MultilibPath; - if (std::optional<std::string> StdlibDir = getStdlibPath()) - MultilibPath = *StdlibDir; - else if (!FallbackDir.empty()) - MultilibPath = FallbackDir; - else - return std::nullopt; - llvm::sys::path::append(MultilibPath, "multilib.yaml"); - if (!D.getVFS().exists(MultilibPath)) - return std::nullopt; - return std::string(MultilibPath); + const auto getMultilibYaml = + [&](StringRef Dir) -> std::optional<std::string> { + SmallString<128> MultilibPath(Dir); + llvm::sys::path::append(MultilibPath, "multilib.yaml"); + if (!D.getVFS().exists(MultilibPath)) + return std::nullopt; + return std::string(MultilibPath); + }; + + if (const auto StdlibDir = getStdlibPath()) { + if (auto MultilibYaml = getMultilibYaml(*StdlibDir)) + return *MultilibYaml; + } + + if (auto MultilibYaml = getMultilibYaml(FallbackDir)) + return *MultilibYaml; + + return std::nullopt; } void ToolChain::setTripleEnvironment(llvm::Triple::EnvironmentType Env) { diff --git a/clang/test/Driver/baremetal-multilib-autodiscovery.yaml b/clang/test/Driver/baremetal-multilib-autodiscovery.yaml index 5472a3ef215d7..f0ffe7af69cfc 100644 --- a/clang/test/Driver/baremetal-multilib-autodiscovery.yaml +++ b/clang/test/Driver/baremetal-multilib-autodiscovery.yaml @@ -2,9 +2,9 @@ # Test that baremetal toolchain discovers multilib.yaml in per-triple dirs # when no sysroot-level multilib.yaml exists. This tests the fallthrough -# from FallbackDir to getStdlibPath() in findMultilibsYAML. +# from getStdlibPath() to FallbackDir in findMultilibsYAML. -## Test 1: per-triple autodiscovery (no sysroot-level YAML) +## Test 1: per-triple autodiscovery (no sysroot-level yaml) # # getStdlibPath() = D.Dir/../lib/<triple> = %t/a/sysroot/usr/lib/riscv64-unknown-none-elf # FallbackDir = D.SysRoot = %t/a/sysroot (no multilib.yaml here) @@ -26,9 +26,9 @@ # RUN: | FileCheck --check-prefix=CHECK-DIR %s # CHECK-DIR: rv64gc/lib -## Test 2: sysroot-level YAML still works via FallbackDir +## Test 2: sysroot-level yaml still works via FallbackDir # -# Place YAML at sysroot root only, no per-triple YAML. +# Place yaml at sysroot root only, no per-triple yaml. # # RUN: mkdir -p %t/b/sysroot/usr/bin # RUN: cp %s %t/b/sysroot/multilib.yaml @@ -39,10 +39,26 @@ # RUN: | FileCheck --check-prefix=CHECK-SYSROOT %s # CHECK-SYSROOT: rv64gc/lib;@-target=riscv64-unknown-none-elf@mabi=lp64d@march=rv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_zicsr2p0_zifencei2p0_zmmul1p0_zaamo1p0_zalrsc1p0_zca1p0_zcd1p0 -## Test 3: per-triple takes priority over sysroot-level +## Test 3: fallthrough when getStdlibPath() dir exists but has no yaml # -# Both exist: per-triple has real YAML, sysroot root has empty YAML. -# getStdlibPath() is tried before FallbackDir, so per-triple wins. +# getStdlibPath() dir exists but contains no multilib.yaml. +# Use sysroot-level yaml must still be found via FallbackDir. +# +# RUN: mkdir -p %t/d/sysroot/usr/bin +# RUN: mkdir -p %t/d/sysroot/usr/lib/riscv64-unknown-none-elf +# RUN: cp %s %t/d/sysroot/multilib.yaml +# RUN: mkdir -p %t/d/sysroot/rv64gc/lib +# RUN: %clang -no-canonical-prefixes -print-multi-lib 2>&1 \ +# RUN: --target=riscv64-unknown-none-elf -march=rv64gc \ +# RUN: --sysroot=%t/d/sysroot \ +# RUN: -ccc-install-dir %t/d/sysroot/usr/bin \ +# RUN: | FileCheck --check-prefix=CHECK-FALLTHROUGH %s +# CHECK-FALLTHROUGH: rv64gc/lib;@-target=riscv64-unknown-none-elf@mabi=lp64d@march=rv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_zicsr2p0_zifencei2p0_zmmul1p0_zaamo1p0_zalrsc1p0_zca1p0_zcd1p0 + +## Test 4: per-triple takes priority over sysroot-level +# +# Both exist: per-triple has real yaml, sysroot has empty yaml. +# getStdlibPath() is tried before FallbackDir, so per-triple should be selected. # # RUN: mkdir -p %t/c/sysroot/usr/bin # RUN: mkdir -p %t/c/sysroot/usr/lib/riscv64-unknown-none-elf/rv64gc/lib _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
