Skip to content

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

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

Merged
merged 1 commit into from
Jan 26, 2024

Conversation

andcarminati
Copy link
Contributor

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.

@llvmbot llvmbot added clang Clang issues not falling into any other category backend:RISC-V clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' labels Dec 27, 2023
@llvmbot
Copy link
Member

llvmbot commented Dec 27, 2023

@llvm/pr-subscribers-clang

@llvm/pr-subscribers-clang-driver

Author: Andreu Carminati (andcarminati)

Changes

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.


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

5 Files Affected:

  • (modified) clang/lib/Driver/ToolChains/BareMetal.cpp (+3)
  • (modified) clang/lib/Driver/ToolChains/RISCVToolchain.cpp (+3)
  • (modified) clang/test/Driver/baremetal.cpp (+12)
  • (modified) clang/test/Driver/riscv32-toolchain.c (+16)
  • (modified) clang/test/Driver/riscv64-toolchain.c (+16)
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/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..701da05da9189d 100644
--- a/clang/test/Driver/riscv32-toolchain.c
+++ b/clang/test/Driver/riscv32-toolchain.c
@@ -215,6 +215,22 @@
 
 // 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"
+
 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..da07c57d8e1fc4 100644
--- a/clang/test/Driver/riscv64-toolchain.c
+++ b/clang/test/Driver/riscv64-toolchain.c
@@ -171,6 +171,22 @@
 
 // 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"
+
 typedef __builtin_va_list va_list;
 typedef __SIZE_TYPE__ size_t;
 typedef __PTRDIFF_TYPE__ ptrdiff_t;

@llvmbot
Copy link
Member

llvmbot commented Dec 27, 2023

@llvm/pr-subscribers-backend-risc-v

Author: Andreu Carminati (andcarminati)

Changes

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.


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

5 Files Affected:

  • (modified) clang/lib/Driver/ToolChains/BareMetal.cpp (+3)
  • (modified) clang/lib/Driver/ToolChains/RISCVToolchain.cpp (+3)
  • (modified) clang/test/Driver/baremetal.cpp (+12)
  • (modified) clang/test/Driver/riscv32-toolchain.c (+16)
  • (modified) clang/test/Driver/riscv64-toolchain.c (+16)
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/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..701da05da9189d 100644
--- a/clang/test/Driver/riscv32-toolchain.c
+++ b/clang/test/Driver/riscv32-toolchain.c
@@ -215,6 +215,22 @@
 
 // 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"
+
 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..da07c57d8e1fc4 100644
--- a/clang/test/Driver/riscv64-toolchain.c
+++ b/clang/test/Driver/riscv64-toolchain.c
@@ -171,6 +171,22 @@
 
 // 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"
+
 typedef __builtin_va_list va_list;
 typedef __SIZE_TYPE__ size_t;
 typedef __PTRDIFF_TYPE__ ptrdiff_t;

@topperc
Copy link
Collaborator

topperc commented Dec 28, 2023

Should this also be done in tools::gnutools::Linker::ConstructJob?

@andcarminati
Copy link
Contributor Author

Should this also be done in tools::gnutools::Linker::ConstructJob?

Addressed with a new commit.

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.
@andcarminati andcarminati force-pushed the clang-rv-pass-no-relax-linker branch from b1acbb1 to f697a90 Compare January 15, 2024 14:19
@andcarminati
Copy link
Contributor Author

After approval, commits are now squashed to merge.

@topperc
Copy link
Collaborator

topperc commented Jan 26, 2024

Do you need someone to commit this?

@andcarminati
Copy link
Contributor Author

Do you need someone to commit this?

Hi @topperc, if you can commit for me I would appreciate it.

@topperc topperc merged commit be8e462 into llvm:main Jan 26, 2024
brad0 added a commit to brad0/llvm-project that referenced this pull request Feb 28, 2024
brad0 added a commit to brad0/llvm-project that referenced this pull request Feb 28, 2024
brad0 added a commit to brad0/llvm-project that referenced this pull request Mar 3, 2024
brad0 added a commit to brad0/llvm-project that referenced this pull request Mar 3, 2024
brad0 added a commit to brad0/llvm-project that referenced this pull request Mar 3, 2024
brad0 added a commit to brad0/llvm-project that referenced this pull request Mar 3, 2024
brad0 added a commit that referenced this pull request Mar 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend:RISC-V 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.

4 participants