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

Reply via email to