llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang-driver

Author: Mintsuki (Mintsuki)

<details>
<summary>Changes</summary>

Clang did not handle loongarch32-\*-none-elf and loongarch64-\*-none-elf in the
bare-metal toolchain, so these targets fell back to the generic ELF toolchain,
which links by running gcc. Any -fuse-ld or --ld-path option is forwarded to
gcc, and linking fails when there is no gcc. On a host whose gcc does not target
LoongArch, which is the usual case when cross compiling, gcc drives the linker
for the host, and the link fails with errors such as "a.o is incompatible with
elf_x86_64". The generic ELF toolchain also searches /usr/local/include and
/usr/include of the host.

The other bare-metal targets, Arm, AArch64, RISC-V, PowerPC, and x86 since
25f0d08bafa4, use the bare-metal toolchain, which runs the selected linker
directly and does not search host include directories.

Handle LoongArch there as well. As the GNU toolchain does for LoongArch, and the
bare-metal toolchain already does for RISC-V, pass -X to the linker, and
--no-relax with -mno-relax.

Assisted-by: Claude Code (Claude Opus 5)


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


4 Files Affected:

- (modified) clang/docs/ReleaseNotes.md (+5) 
- (modified) clang/lib/Driver/ToolChains/BareMetal.cpp (+9-2) 
- (modified) clang/test/Driver/baremetal.cpp (+46) 
- (modified) clang/test/Driver/loongarch-toolchain.c (+4) 


``````````diff
diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index 043a0ddae2a6c..1a052ff8b7db9 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -769,6 +769,11 @@ features cannot lower the translation-unit ABI level;
 
 #### LoongArch Support
 
+- `loongarch32-*-none-elf` and `loongarch64-*-none-elf` targets now use the
+  bare-metal toolchain, like other bare-metal targets. The linker is run
+  directly instead of through `gcc`, and host include directories are no
+  longer searched.
+
 #### RISC-V Support
 
 - Fixed a bug where the `interrupt` attribute did not accept `machine` together
diff --git a/clang/lib/Driver/ToolChains/BareMetal.cpp 
b/clang/lib/Driver/ToolChains/BareMetal.cpp
index 19fbb6b07cebe..619a7fb974615 100644
--- a/clang/lib/Driver/ToolChains/BareMetal.cpp
+++ b/clang/lib/Driver/ToolChains/BareMetal.cpp
@@ -55,6 +55,12 @@ static bool isX86BareMetal(const llvm::Triple &Triple) {
          Triple.getEnvironmentName() == "elf";
 }
 
+/// Is the triple loongarch{32,64}-*-none-elf?
+static bool isLoongArchBareMetal(const llvm::Triple &Triple) {
+  return Triple.isLoongArch() && Triple.getOS() == llvm::Triple::UnknownOS &&
+         Triple.getEnvironmentName() == "elf";
+}
+
 static bool findRISCVMultilibs(const Driver &D,
                                const llvm::Triple &TargetTriple,
                                const ArgList &Args, DetectedMultilibs &Result) 
{
@@ -281,7 +287,8 @@ void BareMetal::findMultilibs(const Driver &D, const 
llvm::Triple &Triple,
 bool BareMetal::handlesTarget(const llvm::Triple &Triple) {
   return arm::isARMEABIBareMetal(Triple) ||
          aarch64::isAArch64BareMetal(Triple) || isRISCVBareMetal(Triple) ||
-         isPPCBareMetal(Triple) || isX86BareMetal(Triple);
+         isPPCBareMetal(Triple) || isX86BareMetal(Triple) ||
+         isLoongArchBareMetal(Triple);
 }
 
 Tool *BareMetal::buildLinker() const {
@@ -547,7 +554,7 @@ void baremetal::Linker::ConstructJob(Compilation &C, const 
JobAction &JA,
     return;
   }
 
-  if (Triple.isRISCV()) {
+  if (Triple.isLoongArch() || Triple.isRISCV()) {
     CmdArgs.push_back("-X");
     if (Args.hasArg(options::OPT_mno_relax))
       CmdArgs.push_back("--no-relax");
diff --git a/clang/test/Driver/baremetal.cpp b/clang/test/Driver/baremetal.cpp
index aa2aa9696c08e..0e08e946d68c5 100644
--- a/clang/test/Driver/baremetal.cpp
+++ b/clang/test/Driver/baremetal.cpp
@@ -300,6 +300,22 @@
 // CHECK-PCX86_64-NO-HOST-INC-SAME: "-internal-isystem" 
"[[RESOURCE]]{{[/\\]+}}include"
 // CHECK-PCX86_64-NO-HOST-INC-SAME: "-internal-isystem" 
"[[INSTALLEDDIR]]{{[/\\]+}}..{{[/\\]+}}lib{{[/\\]+}}clang-runtimes{{[/\\]+[^"]*}}include"
 
+// RUN: %clang -no-canonical-prefixes %s -### --target=loongarch32-unknown-elf 
2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-LA32-NO-HOST-INC %s
+// CHECK-LA32-NO-HOST-INC: InstalledDir: [[INSTALLEDDIR:.+]]
+// CHECK-LA32-NO-HOST-INC: "-resource-dir" "[[RESOURCE:[^"]+]]"
+// CHECK-LA32-NO-HOST-INC-SAME: "-internal-isystem" 
"[[INSTALLEDDIR]]{{[/\\]+}}..{{[/\\]+}}lib{{[/\\]+}}clang-runtimes{{[/\\]+[^"]*}}include{{[/\\]+}}c++{{[/\\]+}}v1"
+// CHECK-LA32-NO-HOST-INC-SAME: "-internal-isystem" 
"[[RESOURCE]]{{[/\\]+}}include"
+// CHECK-LA32-NO-HOST-INC-SAME: "-internal-isystem" 
"[[INSTALLEDDIR]]{{[/\\]+}}..{{[/\\]+}}lib{{[/\\]+}}clang-runtimes{{[/\\]+[^"]*}}include"
+
+// RUN: %clang -no-canonical-prefixes %s -### --target=loongarch64-unknown-elf 
2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-LA64-NO-HOST-INC %s
+// CHECK-LA64-NO-HOST-INC: InstalledDir: [[INSTALLEDDIR:.+]]
+// CHECK-LA64-NO-HOST-INC: "-resource-dir" "[[RESOURCE:[^"]+]]"
+// CHECK-LA64-NO-HOST-INC-SAME: "-internal-isystem" 
"[[INSTALLEDDIR]]{{[/\\]+}}..{{[/\\]+}}lib{{[/\\]+}}clang-runtimes{{[/\\]+[^"]*}}include{{[/\\]+}}c++{{[/\\]+}}v1"
+// CHECK-LA64-NO-HOST-INC-SAME: "-internal-isystem" 
"[[RESOURCE]]{{[/\\]+}}include"
+// CHECK-LA64-NO-HOST-INC-SAME: "-internal-isystem" 
"[[INSTALLEDDIR]]{{[/\\]+}}..{{[/\\]+}}lib{{[/\\]+}}clang-runtimes{{[/\\]+[^"]*}}include"
+
 // RUN: %clang %s -### --target=riscv64-unknown-elf -o %t.out -L 
some/directory/user/asked/for \
 // RUN:     --sysroot=%S/Inputs/basic_riscv64_tree/riscv64-unknown-elf 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-RV64 %s
@@ -646,6 +662,36 @@
 // CHECK-PCX86_64ELF-SAME: "-lc"
 // CHECK-PCX86_64ELF-SAME: "-o" "a.out"
 
+// RUN: %clang -no-canonical-prefixes %s -### --target=loongarch32-unknown-elf 
2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-LA32ELF %s
+// CHECK-LA32ELF: InstalledDir: [[INSTALLEDDIR:.+]]
+// CHECK-LA32ELF: "-nostdsysteminc"
+// CHECK-LA32ELF-SAME: "-resource-dir" "[[RESOURCE:[^"]+]]"
+// CHECK-LA32ELF-SAME: "-internal-isystem" 
"[[INSTALLEDDIR]]{{[/\\]+}}..{{[/\\]+}}lib{{[/\\]+}}clang-runtimes{{[/\\]+[^"]*}}include{{[/\\]+}}c++{{[/\\]+}}v1"
+// CHECK-LA32ELF-SAME: "-internal-isystem" "[[RESOURCE]]{{[/\\]+}}include"
+// CHECK-LA32ELF-SAME: "-internal-isystem" 
"[[INSTALLEDDIR]]{{[/\\]+}}..{{[/\\]+}}lib{{[/\\]+}}clang-runtimes{{[/\\]+[^"]*}}include"
+// CHECK-LA32ELF-NEXT: ld{{(.exe)?}}" "-Bstatic" "-m" "elf32loongarch" "-X"
+// CHECK-LA32ELF-SAME: 
"-L[[INSTALLEDDIR]]{{[/\\]+}}..{{[/\\]+}}lib{{[/\\]+}}clang-runtimes{{[/\\]+[^"]*}}lib"
+// CHECK-LA32ELF-SAME:"{{.*}}.o"
+// CHECK-LA32ELF-SAME: "{{[^"]*}}libclang_rt.builtins.a"
+// CHECK-LA32ELF-SAME: "-lc"
+// CHECK-LA32ELF-SAME: "-o" "a.out"
+
+// RUN: %clang -no-canonical-prefixes %s -### --target=loongarch64-unknown-elf 
2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-LA64ELF %s
+// CHECK-LA64ELF: InstalledDir: [[INSTALLEDDIR:.+]]
+// CHECK-LA64ELF: "-nostdsysteminc"
+// CHECK-LA64ELF-SAME: "-resource-dir" "[[RESOURCE:[^"]+]]"
+// CHECK-LA64ELF-SAME: "-internal-isystem" 
"[[INSTALLEDDIR]]{{[/\\]+}}..{{[/\\]+}}lib{{[/\\]+}}clang-runtimes{{[/\\]+[^"]*}}include{{[/\\]+}}c++{{[/\\]+}}v1"
+// CHECK-LA64ELF-SAME: "-internal-isystem" "[[RESOURCE]]{{[/\\]+}}include"
+// CHECK-LA64ELF-SAME: "-internal-isystem" 
"[[INSTALLEDDIR]]{{[/\\]+}}..{{[/\\]+}}lib{{[/\\]+}}clang-runtimes{{[/\\]+[^"]*}}include"
+// CHECK-LA64ELF-NEXT: ld{{(.exe)?}}" "-Bstatic" "-m" "elf64loongarch" "-X"
+// CHECK-LA64ELF-SAME: 
"-L[[INSTALLEDDIR]]{{[/\\]+}}..{{[/\\]+}}lib{{[/\\]+}}clang-runtimes{{[/\\]+[^"]*}}lib"
+// CHECK-LA64ELF-SAME:"{{.*}}.o"
+// CHECK-LA64ELF-SAME: "{{[^"]*}}libclang_rt.builtins.a"
+// CHECK-LA64ELF-SAME: "-lc"
+// CHECK-LA64ELF-SAME: "-o" "a.out"
+
 // Check that compiler-rt library without the arch filename suffix will
 // be used if present.
 // RUN: rm -rf %t.dir/baremetal_clang_rt_noarch
diff --git a/clang/test/Driver/loongarch-toolchain.c 
b/clang/test/Driver/loongarch-toolchain.c
index 54a2519e0a70d..de7720b34ea53 100644
--- a/clang/test/Driver/loongarch-toolchain.c
+++ b/clang/test/Driver/loongarch-toolchain.c
@@ -31,6 +31,10 @@
 // RUN:   FileCheck --check-prefix=LA64-RELAX %s
 // RUN: %clang --target=loongarch64-unknown-linux-gnu -mno-relax -### %s 2>&1 
| \
 // RUN:   FileCheck --check-prefix=LA64-NORELAX %s
+// RUN: %clang --target=loongarch64-unknown-elf -### %s 2>&1 | \
+// RUN:   FileCheck --check-prefix=LA64-RELAX %s
+// RUN: %clang --target=loongarch64-unknown-elf -mno-relax -### %s 2>&1 | \
+// RUN:   FileCheck --check-prefix=LA64-NORELAX %s
 // LA64-RELAX:     "-X"
 // LA64-RELAX-NOT: "--no-relax"
 // LA64-NORELAX:   "-X" "--no-relax"

``````````

</details>


https://github.com/llvm/llvm-project/pull/223703
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to