Skip to content

Look for compiler-rt from subdir given by --target #88334

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from

Conversation

wzssyqa
Copy link
Contributor

@wzssyqa wzssyqa commented Apr 11, 2024

Currently, clang looks for compiler-rt only from the normalized triple subdir. While if we are configured with a non-normalized triple with -DLLVM_DEFAULT_TARGET_TRIPLE, such as triples without vendor section, clang will fail to find compiler_rt.

Let's look for compiler_rt from the subdir with name from --target option, too.

To archive this, we add a new member called Origin to class Triple.

Fixes: #87150.

Currently, clang looks for compiler-rt only from the normalized
triple subdir. While if we are configured with a non-normalized
triple with -DLLVM_DEFAULT_TARGET_TRIPLE, such as triples without
vendor section, clang will fail to find compiler_rt.

Let's look for compiler_rt from the subdir with name from --target
option.

To archive this, we add a new member called Origin to class Triple.

Fixes: llvm#87150.
@wzssyqa wzssyqa requested a review from MaskRay April 11, 2024 00:39
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' labels Apr 11, 2024
@llvmbot
Copy link
Member

llvmbot commented Apr 11, 2024

@llvm/pr-subscribers-clang

@llvm/pr-subscribers-clang-driver

Author: YunQiang Su (wzssyqa)

Changes

Currently, clang looks for compiler-rt only from the normalized triple subdir. While if we are configured with a non-normalized triple with -DLLVM_DEFAULT_TARGET_TRIPLE, such as triples without vendor section, clang will fail to find compiler_rt.

Let's look for compiler_rt from the subdir with name from --target option, too.

To archive this, we add a new member called Origin to class Triple.

Fixes: #87150.


Full diff: https://github.com/llvm/llvm-project/pull/88334.diff

4 Files Affected:

  • (modified) clang/lib/Driver/Driver.cpp (+1)
  • (modified) clang/lib/Driver/ToolChain.cpp (+6)
  • (modified) llvm/include/llvm/TargetParser/Triple.h (+6)
  • (modified) llvm/lib/TargetParser/Triple.cpp (+3-3)
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index e7335a61b10c53..4a0c939039eb31 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -516,6 +516,7 @@ static llvm::Triple computeTargetTriple(const Driver &D,
     TargetTriple = A->getValue();
 
   llvm::Triple Target(llvm::Triple::normalize(TargetTriple));
+  Target.setOrigin(TargetTriple);
 
   // GNU/Hurd's triples should have been -hurd-gnu*, but were historically made
   // -gnu* only, and we can not change this, so we have to detect that case as
diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp
index 237092ed07e5dc..57f27a61c4060b 100644
--- a/clang/lib/Driver/ToolChain.cpp
+++ b/clang/lib/Driver/ToolChain.cpp
@@ -755,6 +755,12 @@ std::optional<std::string>
 ToolChain::getTargetSubDirPath(StringRef BaseDir) const {
   auto getPathForTriple =
       [&](const llvm::Triple &Triple) -> std::optional<std::string> {
+    if (!Triple.getOrigin().empty()) {
+      SmallString<128> Po(BaseDir);
+      llvm::sys::path::append(Po, Triple.getOrigin());
+      if (getVFS().exists(Po))
+        return std::string(Po);
+    }
     SmallString<128> P(BaseDir);
     llvm::sys::path::append(P, Triple.str());
     if (getVFS().exists(P))
diff --git a/llvm/include/llvm/TargetParser/Triple.h b/llvm/include/llvm/TargetParser/Triple.h
index f256e2b205a889..a2fc28ada0ca31 100644
--- a/llvm/include/llvm/TargetParser/Triple.h
+++ b/llvm/include/llvm/TargetParser/Triple.h
@@ -298,6 +298,8 @@ class Triple {
 private:
   std::string Data;
 
+  StringRef Origin = StringRef();
+
   /// The parsed arch type.
   ArchType Arch{};
 
@@ -425,6 +427,8 @@ class Triple {
 
   const std::string &getTriple() const { return Data; }
 
+  const StringRef getOrigin() const { return Origin; }
+
   /// Get the architecture (first) component of the triple.
   StringRef getArchName() const;
 
@@ -1058,6 +1062,8 @@ class Triple {
   /// @name Mutators
   /// @{
 
+  void setOrigin(StringRef Orig) { Origin = Orig; };
+
   /// Set the architecture (first) component of the triple to a known type.
   void setArch(ArchType Kind, SubArchType SubArch = NoSubArch);
 
diff --git a/llvm/lib/TargetParser/Triple.cpp b/llvm/lib/TargetParser/Triple.cpp
index 624679ff507a7f..ce44903d0f7d70 100644
--- a/llvm/lib/TargetParser/Triple.cpp
+++ b/llvm/lib/TargetParser/Triple.cpp
@@ -928,9 +928,9 @@ static Triple::ObjectFormatType getDefaultFormat(const Triple &T) {
 /// This stores the string representation and parses the various pieces into
 /// enum members.
 Triple::Triple(const Twine &Str)
-    : Data(Str.str()), Arch(UnknownArch), SubArch(NoSubArch),
-      Vendor(UnknownVendor), OS(UnknownOS), Environment(UnknownEnvironment),
-      ObjectFormat(UnknownObjectFormat) {
+    : Data(Str.str()), Origin(Str.getSingleStringRef()), Arch(UnknownArch),
+      SubArch(NoSubArch), Vendor(UnknownVendor), OS(UnknownOS),
+      Environment(UnknownEnvironment), ObjectFormat(UnknownObjectFormat) {
   // Do minimal parsing by hand here.
   SmallVector<StringRef, 4> Components;
   StringRef(Data).split(Components, '-', /*MaxSplit*/ 3);

@wzssyqa wzssyqa marked this pull request as draft April 11, 2024 02:37
@MaskRay
Copy link
Member

MaskRay commented Apr 11, 2024

Can you provide CMake configure command and the compiler-rt file paths? I am not sure we need more changes to clangDriver.

@wzssyqa
Copy link
Contributor Author

wzssyqa commented Apr 11, 2024

Configure cmd

cmake ../llvm -G Ninja -DLLVM_DEFAULT_TARGET_TRIPLE=aarch64-linux-gnu -DLLVM_USE_LINKER=lld -DLLVM_ENABLE_RUNTIMES="compiler-rt;libunwind" -DLLVM_ENABLE_PROJECTS="mlir;clang;clang-tools-extra;lld" -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_BUILD_TYPE=RelWithDebInfo

Note, in -DLLVM_DEFAULT_TARGET_TRIPLE=aarch64-linux-gnu, there is no unknown aka vendor section.

With this configure, libclang_rt.builtin.a is present in
./lib/clang/19/lib/aarch64-linux-gnu/

While clang expects it in
./lib/clang/19/lib/aarch64-unknown-linux-gnu/ #### Note "unknown"

The reason is that in computeTargetTriple, the line

llvm::Triple Target(llvm::Triple::normalize(TargetTriple));

convert the triple to normalize.

@MaskRay
Copy link
Member

MaskRay commented Apr 11, 2024

cmake -Sllvm -B/tmp/out/d-a64 -G Ninja -DLLVM_DEFAULT_TARGET_TRIPLE=aarch64-linux-gnu -DLLVM_USE_LINKER=lld -DLLVM_ENABLE_RUNTIMES="compiler-rt;libunwind" -DLLVM_ENABLE_PROJECTS="clang;lld" -DCMAKE_C_COMPILER=~/Stable/bin/clang -DCMAKE_CXX_COMPILER=~/Stable/bin/clang++ -DCMAKE_BUILD_TYPE=Debug
ninja -C /tmp/out/d-a64 builtins

gives me /tmp/out/d-a64/lib/clang/19/lib/aarch64-linux-gnu/clang_rt.*. Sanitizer targets are not available. I haven't investigated why.

Anyhow, I posted a similar but probably more complete clang driver patch: https://reviews.llvm.org/D110663 , but I concluded that detecting Debian-style x86_64-linux-gnu is not a good idea (too much complexity to the driver when both normalized and un-normalized triples are supported. Error-prone when mix-and-matched.)

It's better to do some normalization in CMake.

@MaskRay MaskRay closed this Apr 11, 2024
@wzssyqa
Copy link
Contributor Author

wzssyqa commented Apr 11, 2024

It's better to do some normalization in CMake.

I will try to work in CMake, then.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Driver] Old compiler-rt library name (e.g. libclang_rt.builtins-aarch64.a) is reported when neither old/new library directory exists
3 participants