[Clang][Driver] Support linker relaxation options for LoongArch (#123587)

This commit completed four tasks:
- Add `-mrelax/-mno-relax` options support for LoongArch in clang
driver.
- Print error for `-gsplit-dwarf` with LoongArch linker relaxation
(`-mrelax`).
- Pass `-X` to linker to discard a plethora of `.L` symbols due to
linker relaxation.
- Forward `--no-relax` option to linker.
This commit is contained in:
ZhaoQi
2025-01-23 10:02:35 +08:00
committed by GitHub
parent 2646e2d487
commit ba70368f13
4 changed files with 56 additions and 1 deletions

View File

@@ -808,6 +808,9 @@ def err_drv_loongarch_invalid_simd_option_combination : Error<
def err_drv_loongarch_invalid_msimd_EQ : Error<
"invalid argument '%0' to -msimd=; must be one of: none, lsx, lasx">;
def err_drv_loongarch_unsupported_with_linker_relaxation : Error<
"%0 is unsupported with LoongArch linker relaxation (-mrelax)">;
def err_drv_expand_response_file : Error<
"failed to expand response file: %0">;

View File

@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "LoongArch.h"
#include "../Clang.h"
#include "ToolChains/CommonArgs.h"
#include "clang/Basic/DiagnosticDriver.h"
#include "clang/Driver/Driver.h"
@@ -134,6 +135,24 @@ void loongarch::getLoongArchTargetFeatures(const Driver &D,
(!Args.hasArgNoClaim(clang::driver::options::OPT_march_EQ)))
Features.push_back("+lsx");
// FIXME: Now we must use -mrelax to enable relax, maybe -mrelax will be set
// as default in the future.
if (const Arg *A =
Args.getLastArg(options::OPT_mrelax, options::OPT_mno_relax)) {
if (A->getOption().matches(options::OPT_mrelax)) {
Features.push_back("+relax");
// -gsplit-dwarf -mrelax requires DW_AT_high_pc/DW_AT_ranges/... indexing
// into .debug_addr, which is currently not implemented.
Arg *A;
if (getDebugFissionKind(D, Args, A) != DwarfFissionKind::None)
D.Diag(
clang::diag::err_drv_loongarch_unsupported_with_linker_relaxation)
<< A->getAsString(Args);
} else {
Features.push_back("-relax");
}
}
std::string ArchName;
const Arg *MArch = Args.getLastArg(options::OPT_march_EQ);
if (MArch)

View File

@@ -422,7 +422,7 @@ void tools::gnutools::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");

View File

@@ -0,0 +1,33 @@
/// Test -m[no-]relax options.
// RUN: %clang --target=loongarch32 -S -emit-llvm %s -o - | FileCheck %s --check-prefix=LA32
// RUN: %clang --target=loongarch64 -S -emit-llvm %s -o - | FileCheck %s --check-prefix=LA64
// RUN: %clang --target=loongarch32 -mno-relax -S -emit-llvm %s -o - | FileCheck %s --check-prefix=LA32-NORELAX
// RUN: %clang --target=loongarch64 -mno-relax -S -emit-llvm %s -o - | FileCheck %s --check-prefix=LA64-NORELAX
// RUN: %clang --target=loongarch32 -mrelax -S -emit-llvm %s -o - | FileCheck %s --check-prefix=LA32-RELAX
// RUN: %clang --target=loongarch64 -mrelax -S -emit-llvm %s -o - | FileCheck %s --check-prefix=LA64-RELAX
/// Error when using -gsplit-dwarf with linker relaxation (-mrelax).
// RUN: %clang -### -c --target=loongarch32 -mno-relax -g -gsplit-dwarf %s 2>&1 | FileCheck %s --check-prefix=SPLIT-DWARF
// RUN: not %clang -c --target=loongarch32-linux-gnu -mrelax -gsplit-dwarf %s 2>&1 | FileCheck %s --check-prefix=ERR-SPLIT-DWARF
// RUN: not %clang -c --target=loongarch32 -mrelax -gsplit-dwarf=single %s 2>&1 | FileCheck %s --check-prefix=ERR-SPLIT-DWARF
// RUN: %clang -### -c --target=loongarch64 -mno-relax -g -gsplit-dwarf %s 2>&1 | FileCheck %s --check-prefix=SPLIT-DWARF
// RUN: not %clang -c --target=loongarch64-linux-gnu -mrelax -gsplit-dwarf %s 2>&1 | FileCheck %s --check-prefix=ERR-SPLIT-DWARF
// RUN: not %clang -c --target=loongarch64 -mrelax -gsplit-dwarf=single %s 2>&1 | FileCheck %s --check-prefix=ERR-SPLIT-DWARF
// LA32: "target-features"="+32bit"
// LA64: "target-features"="+64bit,+d,+f,+lsx,+ual"
// LA32-NORELAX: "target-features"="+32bit,-relax"
// LA64-NORELAX: "target-features"="+64bit,+d,+f,+lsx,+ual,-relax"
// LA32-RELAX: "target-features"="+32bit,+relax"
// LA64-RELAX: "target-features"="+64bit,+d,+f,+lsx,+relax,+ual"
// SPLIT-DWARF: "-split-dwarf-file"
// ERR-SPLIT-DWARF: error: -gsplit-dwarf{{.*}} is unsupported with LoongArch linker relaxation (-mrelax)
int foo(void) {
return 3;
}