Skip to content

Commit

Permalink
[Clang][RISCV] Forward --no-relax option to linker for RISC-V (#76432)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
Andreu Carminati committed Jan 26, 2024
1 parent 45f883e commit be8e462
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 1 deletion.
3 changes: 3 additions & 0 deletions clang/lib/Driver/ToolChains/BareMetal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,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)
Expand Down
6 changes: 5 additions & 1 deletion clang/lib/Driver/ToolChains/Gnu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/Driver/ToolChains/RISCVToolchain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
12 changes: 12 additions & 0 deletions clang/test/Driver/baremetal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
32 changes: 32 additions & 0 deletions clang/test/Driver/riscv32-toolchain.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
32 changes: 32 additions & 0 deletions clang/test/Driver/riscv64-toolchain.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit be8e462

Please sign in to comment.