[clang] [Clang][RISCV] Forward --no-relax option to linker for RISC-V (PR #76432)

Andreu Carminati via cfe-commits cfe-commits at lists.llvm.org
Mon Jan 15 06:19:42 PST 2024


https://github.com/andcarminati updated https://github.com/llvm/llvm-project/pull/76432

>From f697a90f8375a66fb23bbaaefc2e1297e79e063a Mon Sep 17 00:00:00 2001
From: Andreu Carminati <andreu.carminati at hightec-rt.com>
Date: Mon, 15 Jan 2024 15:18:02 +0100
Subject: [PATCH] [Clang][RISCV] Forward --no-relax option to linker for RISC-V

In the case of -mno-relax option. Otherwise, we cannot prevent relaxation
if we split compilation and linking using Clang driver.

One can consider the following use case:

clang [...] -c -o myobject.o (just compile)
clang [...] myobject.o -o myobject.elf -mno-relax (linking)

In this case, myobject.elf will be relaxed, the -mno-relax will be silently ignored.
---
 clang/lib/Driver/ToolChains/BareMetal.cpp     |  3 ++
 clang/lib/Driver/ToolChains/Gnu.cpp           |  6 +++-
 .../lib/Driver/ToolChains/RISCVToolchain.cpp  |  3 ++
 clang/test/Driver/baremetal.cpp               | 12 +++++++
 clang/test/Driver/riscv32-toolchain.c         | 32 +++++++++++++++++++
 clang/test/Driver/riscv64-toolchain.c         | 32 +++++++++++++++++++
 6 files changed, 87 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Driver/ToolChains/BareMetal.cpp b/clang/lib/Driver/ToolChains/BareMetal.cpp
index 42c8336e626c7b..007a24f2b81ae7 100644
--- a/clang/lib/Driver/ToolChains/BareMetal.cpp
+++ b/clang/lib/Driver/ToolChains/BareMetal.cpp
@@ -443,6 +443,9 @@ void baremetal::Linker::ConstructJob(Compilation &C, const JobAction &JA,
 
   CmdArgs.push_back("-Bstatic");
 
+  if (TC.getTriple().isRISCV() && Args.hasArg(options::OPT_mno_relax))
+    CmdArgs.push_back("--no-relax");
+
   if (Triple.isARM() || Triple.isThumb()) {
     bool IsBigEndian = arm::isARMBigEndian(Triple, Args);
     if (IsBigEndian)
diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp
index 38361d6889a1c8..ad56c5a4e4473c 100644
--- a/clang/lib/Driver/ToolChains/Gnu.cpp
+++ b/clang/lib/Driver/ToolChains/Gnu.cpp
@@ -423,8 +423,12 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA,
     D.Diag(diag::err_target_unknown_triple) << Triple.str();
     return;
   }
-  if (Triple.isRISCV())
+
+  if (Triple.isRISCV()) {
     CmdArgs.push_back("-X");
+    if (Args.hasArg(options::OPT_mno_relax))
+      CmdArgs.push_back("--no-relax");
+  }
 
   const bool IsShared = Args.hasArg(options::OPT_shared);
   if (IsShared)
diff --git a/clang/lib/Driver/ToolChains/RISCVToolchain.cpp b/clang/lib/Driver/ToolChains/RISCVToolchain.cpp
index 7e6abd14442878..0be7d1a8899495 100644
--- a/clang/lib/Driver/ToolChains/RISCVToolchain.cpp
+++ b/clang/lib/Driver/ToolChains/RISCVToolchain.cpp
@@ -156,6 +156,9 @@ void RISCV::Linker::ConstructJob(Compilation &C, const JobAction &JA,
   if (!D.SysRoot.empty())
     CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
 
+  if (Args.hasArg(options::OPT_mno_relax))
+    CmdArgs.push_back("--no-relax");
+
   bool IsRV64 = ToolChain.getArch() == llvm::Triple::riscv64;
   CmdArgs.push_back("-m");
   if (IsRV64) {
diff --git a/clang/test/Driver/baremetal.cpp b/clang/test/Driver/baremetal.cpp
index c04f4506a0994d..7511d7d1adb4dd 100644
--- a/clang/test/Driver/baremetal.cpp
+++ b/clang/test/Driver/baremetal.cpp
@@ -460,3 +460,15 @@
 // RUN:   | FileCheck --check-prefix=CHECK-CLANGRT-ARCH %s
 // CHECK-CLANGRT-ARCH: "-lclang_rt.builtins-armv6m"
 // CHECK-CLANGRT-ARCH-NOT: "-lclang_rt.builtins"
+
+// Check that "--no-relax" is forwarded to the linker for RISC-V.
+// RUN: %clang %s -### 2>&1 --target=riscv64-unknown-elf -nostdinc -mno-relax \
+// RUN:     --sysroot=%S/Inputs/basic_riscv64_tree/riscv64-unknown-elf \
+// RUN:   | FileCheck --check-prefix=CHECK-RV64-NORELAX %s
+// CHECK-RV64-NORELAX: "--no-relax"
+
+// Check that "--no-relax" is not forwarded to the linker for RISC-V.
+// RUN: %clang %s -### 2>&1 --target=riscv64-unknown-elf -nostdinc \
+// RUN:     --sysroot=%S/Inputs/basic_riscv64_tree/riscv64-unknown-elf \
+// RUN:   | FileCheck --check-prefix=CHECK-RV64-RELAX %s
+// CHECK-RV64-RELAX-NOT: "--no-relax"
\ No newline at end of file
diff --git a/clang/test/Driver/riscv32-toolchain.c b/clang/test/Driver/riscv32-toolchain.c
index 63690c946ca0bc..bb2533cdf1bce2 100644
--- a/clang/test/Driver/riscv32-toolchain.c
+++ b/clang/test/Driver/riscv32-toolchain.c
@@ -215,6 +215,38 @@
 
 // RUN: %clang --target=riscv32 %s -emit-llvm -S -o - | FileCheck %s
 
+// Check that "--no-relax" is forwarded to the linker for RISC-V (RISCVToolchain.cpp).
+// RUN: env "PATH=" %clang %s -### 2>&1 -mno-relax \
+// RUN:   --target=riscv32-unknown-elf --rtlib=platform --unwindlib=platform --sysroot= \
+// RUN:   -march=rv32imac -mabi=lp32\
+// RUN:   --gcc-toolchain=%S/Inputs/multilib_riscv_elf_sdk 2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-RV32-NORELAX %s
+// CHECK-RV32-NORELAX: "--no-relax"
+
+// Check that "--no-relax" is not forwarded to the linker for RISC-V (RISCVToolchain.cpp).
+// RUN:env "PATH=" %clang %s -### 2>&1 \
+// RUN:   --target=riscv32-unknown-elf --rtlib=platform --unwindlib=platform --sysroot= \
+// RUN:   -march=rv32imac -mabi=lp32\
+// RUN:   --gcc-toolchain=%S/Inputs/multilib_riscv_elf_sdk 2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-RV32-RELAX %s
+// CHECK-RV32-RELAX-NOT: "--no-relax"
+
+// Check that "--no-relax" is forwarded to the linker for RISC-V (Gnu.cpp).
+// RUN: env "PATH=" %clang -### %s -fuse-ld=ld -no-pie -mno-relax \
+// RUN:   --target=riscv32-unknown-linux-gnu --rtlib=platform --unwindlib=platform -mabi=ilp32 \
+// RUN:   --gcc-toolchain=%S/Inputs/multilib_riscv_linux_sdk \
+// RUN:   --sysroot=%S/Inputs/multilib_riscv_linux_sdk/sysroot 2>&1 \
+// RUN:   | FileCheck -check-prefix=CHECK-RV32-GNU-NORELAX %s
+// CHECK-RV32-GNU-NORELAX: "--no-relax"
+
+// Check that "--no-relax" is not forwarded to the linker for RISC-V (Gnu.cpp).
+// RUN: env "PATH=" %clang -### %s -fuse-ld=ld -no-pie \
+// RUN:   --target=riscv32-unknown-linux-gnu --rtlib=platform --unwindlib=platform -mabi=ilp32 \
+// RUN:   --gcc-toolchain=%S/Inputs/multilib_riscv_linux_sdk \
+// RUN:   --sysroot=%S/Inputs/multilib_riscv_linux_sdk/sysroot 2>&1 \
+// RUN:   | FileCheck -check-prefix=CHECK-RV32-GNU-RELAX %s
+// CHECK-RV32-GNU-RELAX-NOT: "--no-relax"
+
 typedef __builtin_va_list va_list;
 typedef __SIZE_TYPE__ size_t;
 typedef __PTRDIFF_TYPE__ ptrdiff_t;
diff --git a/clang/test/Driver/riscv64-toolchain.c b/clang/test/Driver/riscv64-toolchain.c
index f177bff33dd4d7..381ee58c470c5e 100644
--- a/clang/test/Driver/riscv64-toolchain.c
+++ b/clang/test/Driver/riscv64-toolchain.c
@@ -171,6 +171,38 @@
 
 // RUN: %clang --target=riscv64 %s -emit-llvm -S -o - | FileCheck %s
 
+// Check that "--no-relax" is forwarded to the linker for RISC-V (RISCVToolchain.cpp).
+// RUN: env "PATH=" %clang %s -### 2>&1 -mno-relax \
+// RUN:   --target=riscv64-unknown-elf --rtlib=platform --unwindlib=platform --sysroot= \
+// RUN:   -march=rv64imac -mabi=lp64\
+// RUN:   --gcc-toolchain=%S/Inputs/multilib_riscv_elf_sdk 2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-RV64-NORELAX %s
+// CHECK-RV64-NORELAX: "--no-relax"
+
+// Check that "--no-relax" is not forwarded to the linker for RISC-V (RISCVToolchain.cpp).
+// RUN:env "PATH=" %clang %s -### 2>&1 \
+// RUN:   --target=riscv64-unknown-elf --rtlib=platform --unwindlib=platform --sysroot= \
+// RUN:   -march=rv64imac -mabi=lp64\
+// RUN:   --gcc-toolchain=%S/Inputs/multilib_riscv_elf_sdk 2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-RV64-RELAX %s
+// CHECK-RV64-RELAX-NOT: "--no-relax"
+
+// Check that "--no-relax" is forwarded to the linker for RISC-V (Gnu.cpp).
+// RUN: env "PATH=" %clang -### %s -fuse-ld=ld -no-pie -mno-relax \
+// RUN:   --target=riscv64-unknown-linux-gnu --rtlib=platform --unwindlib=platform -mabi=lp64 \
+// RUN:   --gcc-toolchain=%S/Inputs/multilib_riscv_linux_sdk \
+// RUN:   --sysroot=%S/Inputs/multilib_riscv_linux_sdk/sysroot 2>&1 \
+// RUN:   | FileCheck -check-prefix=CHECK-RV64-GNU-NORELAX %s
+// CHECK-RV64-GNU-NORELAX: "--no-relax"
+
+// Check that "--no-relax" is not forwarded to the linker for RISC-V (Gnu.cpp).
+// RUN: env "PATH=" %clang -### %s -fuse-ld=ld -no-pie \
+// RUN:   --target=riscv64-unknown-linux-gnu --rtlib=platform --unwindlib=platform -mabi=lp64 \
+// RUN:   --gcc-toolchain=%S/Inputs/multilib_riscv_linux_sdk \
+// RUN:   --sysroot=%S/Inputs/multilib_riscv_linux_sdk/sysroot 2>&1 \
+// RUN:   | FileCheck -check-prefix=CHECK-RV64-GNU-RELAX %s
+// CHECK-RV64-GNU-RELAX-NOT: "--no-relax"
+
 typedef __builtin_va_list va_list;
 typedef __SIZE_TYPE__ size_t;
 typedef __PTRDIFF_TYPE__ ptrdiff_t;



More information about the cfe-commits mailing list