Skip to content

Commit ba70368

Browse files
authored
[Clang][Driver] Support linker relaxation options for LoongArch (llvm#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.
1 parent 2646e2d commit ba70368

File tree

4 files changed

+56
-1
lines changed

4 files changed

+56
-1
lines changed

clang/include/clang/Basic/DiagnosticDriverKinds.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -808,6 +808,9 @@ def err_drv_loongarch_invalid_simd_option_combination : Error<
808808
def err_drv_loongarch_invalid_msimd_EQ : Error<
809809
"invalid argument '%0' to -msimd=; must be one of: none, lsx, lasx">;
810810

811+
def err_drv_loongarch_unsupported_with_linker_relaxation : Error<
812+
"%0 is unsupported with LoongArch linker relaxation (-mrelax)">;
813+
811814
def err_drv_expand_response_file : Error<
812815
"failed to expand response file: %0">;
813816

clang/lib/Driver/ToolChains/Arch/LoongArch.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "LoongArch.h"
10+
#include "../Clang.h"
1011
#include "ToolChains/CommonArgs.h"
1112
#include "clang/Basic/DiagnosticDriver.h"
1213
#include "clang/Driver/Driver.h"
@@ -134,6 +135,24 @@ void loongarch::getLoongArchTargetFeatures(const Driver &D,
134135
(!Args.hasArgNoClaim(clang::driver::options::OPT_march_EQ)))
135136
Features.push_back("+lsx");
136137

138+
// FIXME: Now we must use -mrelax to enable relax, maybe -mrelax will be set
139+
// as default in the future.
140+
if (const Arg *A =
141+
Args.getLastArg(options::OPT_mrelax, options::OPT_mno_relax)) {
142+
if (A->getOption().matches(options::OPT_mrelax)) {
143+
Features.push_back("+relax");
144+
// -gsplit-dwarf -mrelax requires DW_AT_high_pc/DW_AT_ranges/... indexing
145+
// into .debug_addr, which is currently not implemented.
146+
Arg *A;
147+
if (getDebugFissionKind(D, Args, A) != DwarfFissionKind::None)
148+
D.Diag(
149+
clang::diag::err_drv_loongarch_unsupported_with_linker_relaxation)
150+
<< A->getAsString(Args);
151+
} else {
152+
Features.push_back("-relax");
153+
}
154+
}
155+
137156
std::string ArchName;
138157
const Arg *MArch = Args.getLastArg(options::OPT_march_EQ);
139158
if (MArch)

clang/lib/Driver/ToolChains/Gnu.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,7 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA,
422422
return;
423423
}
424424

425-
if (Triple.isRISCV()) {
425+
if (Triple.isLoongArch() || Triple.isRISCV()) {
426426
CmdArgs.push_back("-X");
427427
if (Args.hasArg(options::OPT_mno_relax))
428428
CmdArgs.push_back("--no-relax");
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/// Test -m[no-]relax options.
2+
3+
// RUN: %clang --target=loongarch32 -S -emit-llvm %s -o - | FileCheck %s --check-prefix=LA32
4+
// RUN: %clang --target=loongarch64 -S -emit-llvm %s -o - | FileCheck %s --check-prefix=LA64
5+
// RUN: %clang --target=loongarch32 -mno-relax -S -emit-llvm %s -o - | FileCheck %s --check-prefix=LA32-NORELAX
6+
// RUN: %clang --target=loongarch64 -mno-relax -S -emit-llvm %s -o - | FileCheck %s --check-prefix=LA64-NORELAX
7+
// RUN: %clang --target=loongarch32 -mrelax -S -emit-llvm %s -o - | FileCheck %s --check-prefix=LA32-RELAX
8+
// RUN: %clang --target=loongarch64 -mrelax -S -emit-llvm %s -o - | FileCheck %s --check-prefix=LA64-RELAX
9+
10+
/// Error when using -gsplit-dwarf with linker relaxation (-mrelax).
11+
12+
// RUN: %clang -### -c --target=loongarch32 -mno-relax -g -gsplit-dwarf %s 2>&1 | FileCheck %s --check-prefix=SPLIT-DWARF
13+
// RUN: not %clang -c --target=loongarch32-linux-gnu -mrelax -gsplit-dwarf %s 2>&1 | FileCheck %s --check-prefix=ERR-SPLIT-DWARF
14+
// RUN: not %clang -c --target=loongarch32 -mrelax -gsplit-dwarf=single %s 2>&1 | FileCheck %s --check-prefix=ERR-SPLIT-DWARF
15+
// RUN: %clang -### -c --target=loongarch64 -mno-relax -g -gsplit-dwarf %s 2>&1 | FileCheck %s --check-prefix=SPLIT-DWARF
16+
// RUN: not %clang -c --target=loongarch64-linux-gnu -mrelax -gsplit-dwarf %s 2>&1 | FileCheck %s --check-prefix=ERR-SPLIT-DWARF
17+
// RUN: not %clang -c --target=loongarch64 -mrelax -gsplit-dwarf=single %s 2>&1 | FileCheck %s --check-prefix=ERR-SPLIT-DWARF
18+
19+
// LA32: "target-features"="+32bit"
20+
// LA64: "target-features"="+64bit,+d,+f,+lsx,+ual"
21+
22+
// LA32-NORELAX: "target-features"="+32bit,-relax"
23+
// LA64-NORELAX: "target-features"="+64bit,+d,+f,+lsx,+ual,-relax"
24+
25+
// LA32-RELAX: "target-features"="+32bit,+relax"
26+
// LA64-RELAX: "target-features"="+64bit,+d,+f,+lsx,+relax,+ual"
27+
28+
// SPLIT-DWARF: "-split-dwarf-file"
29+
// ERR-SPLIT-DWARF: error: -gsplit-dwarf{{.*}} is unsupported with LoongArch linker relaxation (-mrelax)
30+
31+
int foo(void) {
32+
return 3;
33+
}

0 commit comments

Comments
 (0)