Skip to content

Commit b3ef8dc

Browse files
authored
[LoongArch] Emit R_LARCH_RELAX when expanding some LoadAddress (#72961)
Emit relax relocs when expand non-large la.pcrel and non-large la.got on llvm-mc stage, which like what does on GAS. 1, la.pcrel -> PCALA_HI20 + RELAX + PCALA_LO12 + RELAX 2, la.got -> GOT_PC_HI20 + RELAX + GOT_PC_LO12 + RELAX
1 parent 5a402c5 commit b3ef8dc

File tree

7 files changed

+115
-27
lines changed

7 files changed

+115
-27
lines changed

llvm/lib/Target/LoongArch/AsmParser/LoongArchAsmParser.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ class LoongArchAsmParser : public MCTargetAsmParser {
8585
// "emitLoadAddress*" functions.
8686
void emitLAInstSeq(MCRegister DestReg, MCRegister TmpReg,
8787
const MCExpr *Symbol, SmallVectorImpl<Inst> &Insts,
88-
SMLoc IDLoc, MCStreamer &Out);
88+
SMLoc IDLoc, MCStreamer &Out, bool RelaxHint = false);
8989

9090
// Helper to emit pseudo instruction "la.abs $rd, sym".
9191
void emitLoadAddressAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
@@ -748,12 +748,14 @@ bool LoongArchAsmParser::ParseInstruction(ParseInstructionInfo &Info,
748748
void LoongArchAsmParser::emitLAInstSeq(MCRegister DestReg, MCRegister TmpReg,
749749
const MCExpr *Symbol,
750750
SmallVectorImpl<Inst> &Insts,
751-
SMLoc IDLoc, MCStreamer &Out) {
751+
SMLoc IDLoc, MCStreamer &Out,
752+
bool RelaxHint) {
752753
MCContext &Ctx = getContext();
753754
for (LoongArchAsmParser::Inst &Inst : Insts) {
754755
unsigned Opc = Inst.Opc;
755756
LoongArchMCExpr::VariantKind VK = Inst.VK;
756-
const LoongArchMCExpr *LE = LoongArchMCExpr::create(Symbol, VK, Ctx);
757+
const LoongArchMCExpr *LE =
758+
LoongArchMCExpr::create(Symbol, VK, Ctx, RelaxHint);
757759
switch (Opc) {
758760
default:
759761
llvm_unreachable("unexpected opcode");
@@ -854,7 +856,7 @@ void LoongArchAsmParser::emitLoadAddressPcrel(MCInst &Inst, SMLoc IDLoc,
854856
Insts.push_back(
855857
LoongArchAsmParser::Inst(ADDI, LoongArchMCExpr::VK_LoongArch_PCALA_LO12));
856858

857-
emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
859+
emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out, true);
858860
}
859861

860862
void LoongArchAsmParser::emitLoadAddressPcrelLarge(MCInst &Inst, SMLoc IDLoc,
@@ -900,7 +902,7 @@ void LoongArchAsmParser::emitLoadAddressGot(MCInst &Inst, SMLoc IDLoc,
900902
Insts.push_back(
901903
LoongArchAsmParser::Inst(LD, LoongArchMCExpr::VK_LoongArch_GOT_PC_LO12));
902904

903-
emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out);
905+
emitLAInstSeq(DestReg, DestReg, Symbol, Insts, IDLoc, Out, true);
904906
}
905907

906908
void LoongArchAsmParser::emitLoadAddressGotLarge(MCInst &Inst, SMLoc IDLoc,

llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCCodeEmitter.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "llvm/MC/MCInstBuilder.h"
2020
#include "llvm/MC/MCInstrInfo.h"
2121
#include "llvm/MC/MCRegisterInfo.h"
22+
#include "llvm/MC/MCSubtargetInfo.h"
2223
#include "llvm/Support/Casting.h"
2324
#include "llvm/Support/EndianStream.h"
2425

@@ -120,12 +121,15 @@ LoongArchMCCodeEmitter::getExprOpValue(const MCInst &MI, const MCOperand &MO,
120121
SmallVectorImpl<MCFixup> &Fixups,
121122
const MCSubtargetInfo &STI) const {
122123
assert(MO.isExpr() && "getExprOpValue expects only expressions");
124+
bool RelaxCandidate = false;
125+
bool EnableRelax = STI.hasFeature(LoongArch::FeatureRelax);
123126
const MCExpr *Expr = MO.getExpr();
124127
MCExpr::ExprKind Kind = Expr->getKind();
125128
LoongArch::Fixups FixupKind = LoongArch::fixup_loongarch_invalid;
126129
if (Kind == MCExpr::Target) {
127130
const LoongArchMCExpr *LAExpr = cast<LoongArchMCExpr>(Expr);
128131

132+
RelaxCandidate = LAExpr->getRelaxHint();
129133
switch (LAExpr->getKind()) {
130134
case LoongArchMCExpr::VK_LoongArch_None:
131135
case LoongArchMCExpr::VK_LoongArch_Invalid:
@@ -270,6 +274,15 @@ LoongArchMCCodeEmitter::getExprOpValue(const MCInst &MI, const MCOperand &MO,
270274

271275
Fixups.push_back(
272276
MCFixup::create(0, Expr, MCFixupKind(FixupKind), MI.getLoc()));
277+
278+
// Emit an R_LARCH_RELAX if linker relaxation is enabled and LAExpr has relax
279+
// hint.
280+
if (EnableRelax && RelaxCandidate) {
281+
const MCConstantExpr *Dummy = MCConstantExpr::create(0, Ctx);
282+
Fixups.push_back(MCFixup::create(
283+
0, Dummy, MCFixupKind(LoongArch::fixup_loongarch_relax), MI.getLoc()));
284+
}
285+
273286
return 0;
274287
}
275288

llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCExpr.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,10 @@ using namespace llvm;
2525

2626
#define DEBUG_TYPE "loongarch-mcexpr"
2727

28-
const LoongArchMCExpr *
29-
LoongArchMCExpr::create(const MCExpr *Expr, VariantKind Kind, MCContext &Ctx) {
30-
return new (Ctx) LoongArchMCExpr(Expr, Kind);
28+
const LoongArchMCExpr *LoongArchMCExpr::create(const MCExpr *Expr,
29+
VariantKind Kind, MCContext &Ctx,
30+
bool Hint) {
31+
return new (Ctx) LoongArchMCExpr(Expr, Kind, Hint);
3132
}
3233

3334
void LoongArchMCExpr::printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const {

llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCExpr.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,16 +67,18 @@ class LoongArchMCExpr : public MCTargetExpr {
6767
private:
6868
const MCExpr *Expr;
6969
const VariantKind Kind;
70+
const bool RelaxHint;
7071

71-
explicit LoongArchMCExpr(const MCExpr *Expr, VariantKind Kind)
72-
: Expr(Expr), Kind(Kind) {}
72+
explicit LoongArchMCExpr(const MCExpr *Expr, VariantKind Kind, bool Hint)
73+
: Expr(Expr), Kind(Kind), RelaxHint(Hint) {}
7374

7475
public:
7576
static const LoongArchMCExpr *create(const MCExpr *Expr, VariantKind Kind,
76-
MCContext &Ctx);
77+
MCContext &Ctx, bool Hint = false);
7778

7879
VariantKind getKind() const { return Kind; }
7980
const MCExpr *getSubExpr() const { return Expr; }
81+
bool getRelaxHint() const { return RelaxHint; }
8082

8183
void printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const override;
8284
bool evaluateAsRelocatableImpl(MCValue &Res, const MCAsmLayout *Layout,
Lines changed: 73 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,128 @@
11
# RUN: llvm-mc --triple=loongarch64 %s | FileCheck %s
2+
# RUN: llvm-mc --filetype=obj --triple=loongarch64 --mattr=-relax %s -o %t
3+
# RUN: llvm-readobj -r %t | FileCheck %s --check-prefix=RELOC
4+
# RUN: llvm-mc --filetype=obj --triple=loongarch64 --mattr=+relax %s -o %t.relax
5+
# RUN: llvm-readobj -r %t.relax | FileCheck %s --check-prefixes=RELOC,RELAX
6+
7+
# RELOC: Relocations [
8+
# RELOC-NEXT: Section ({{.*}}) .rela.text {
29

310
la.abs $a0, sym_abs
411
# CHECK: lu12i.w $a0, %abs_hi20(sym_abs)
512
# CHECK-NEXT: ori $a0, $a0, %abs_lo12(sym_abs)
613
# CHECK-NEXT: lu32i.d $a0, %abs64_lo20(sym_abs)
714
# CHECK-NEXT: lu52i.d $a0, $a0, %abs64_hi12(sym_abs)
15+
# CHECK-EMPTY:
16+
# RELOC-NEXT: R_LARCH_ABS_HI20 sym_abs 0x0
17+
# RELOC-NEXT: R_LARCH_ABS_LO12 sym_abs 0x0
18+
# RELOC-NEXT: R_LARCH_ABS64_LO20 sym_abs 0x0
19+
# RELOC-NEXT: R_LARCH_ABS64_HI12 sym_abs 0x0
820

921
la.pcrel $a0, sym_pcrel
10-
# CHECK: pcalau12i $a0, %pc_hi20(sym_pcrel)
22+
# CHECK-NEXT: pcalau12i $a0, %pc_hi20(sym_pcrel)
1123
# CHECK-NEXT: addi.d $a0, $a0, %pc_lo12(sym_pcrel)
24+
# CHECK-EMPTY:
25+
# RELOC-NEXT: R_LARCH_PCALA_HI20 sym_pcrel 0x0
26+
# RELAX-NEXT: R_LARCH_RELAX - 0x0
27+
# RELOC-NEXT: R_LARCH_PCALA_LO12 sym_pcrel 0x0
28+
# RELAX-NEXT: R_LARCH_RELAX - 0x0
1229

1330
la.pcrel $a0, $a1, sym_pcrel_large
14-
# CHECK: pcalau12i $a0, %pc_hi20(sym_pcrel_large)
31+
# CHECK-NEXT: pcalau12i $a0, %pc_hi20(sym_pcrel_large)
1532
# CHECK-NEXT: addi.d $a1, $zero, %pc_lo12(sym_pcrel_large)
1633
# CHECK-NEXT: lu32i.d $a1, %pc64_lo20(sym_pcrel_large)
1734
# CHECK-NEXT: lu52i.d $a1, $a1, %pc64_hi12(sym_pcrel_large)
1835
# CHECK-NEXT: add.d $a0, $a0, $a1
36+
# CHECK-EMPTY:
37+
# RELOC-NEXT: R_LARCH_PCALA_HI20 sym_pcrel_large 0x0
38+
# RELOC-NEXT: R_LARCH_PCALA_LO12 sym_pcrel_large 0x0
39+
# RELOC-NEXT: R_LARCH_PCALA64_LO20 sym_pcrel_large 0x0
40+
# RELOC-NEXT: R_LARCH_PCALA64_HI12 sym_pcrel_large 0x0
1941

2042
la.got $a0, sym_got
21-
# CHECK: pcalau12i $a0, %got_pc_hi20(sym_got)
43+
# CHECK-NEXT: pcalau12i $a0, %got_pc_hi20(sym_got)
2244
# CHECK-NEXT: ld.d $a0, $a0, %got_pc_lo12(sym_got)
45+
# CHECK-EMPTY:
46+
# RELOC-NEXT: R_LARCH_GOT_PC_HI20 sym_got 0x0
47+
# RELAX-NEXT: R_LARCH_RELAX - 0x0
48+
# RELOC-NEXT: R_LARCH_GOT_PC_LO12 sym_got 0x0
49+
# RELAX-NEXT: R_LARCH_RELAX - 0x0
2350

2451
la.got $a0, $a1, sym_got_large
25-
# CHECK: pcalau12i $a0, %got_pc_hi20(sym_got_large)
52+
# CHECK-NEXT: pcalau12i $a0, %got_pc_hi20(sym_got_large)
2653
# CHECK-NEXT: addi.d $a1, $zero, %got_pc_lo12(sym_got_large)
2754
# CHECK-NEXT: lu32i.d $a1, %got64_pc_lo20(sym_got_large)
2855
# CHECK-NEXT: lu52i.d $a1, $a1, %got64_pc_hi12(sym_got_large)
2956
# CHECK-NEXT: ldx.d $a0, $a0, $a1
57+
# CHECK-EMPTY:
58+
# RELOC-NEXT: R_LARCH_GOT_PC_HI20 sym_got_large 0x0
59+
# RELOC-NEXT: R_LARCH_GOT_PC_LO12 sym_got_large 0x0
60+
# RELOC-NEXT: R_LARCH_GOT64_PC_LO20 sym_got_large 0x0
61+
# RELOC-NEXT: R_LARCH_GOT64_PC_HI12 sym_got_large 0x0
3062

3163
la.tls.le $a0, sym_le
32-
# CHECK: lu12i.w $a0, %le_hi20(sym_le)
64+
# CHECK-NEXT: lu12i.w $a0, %le_hi20(sym_le)
3365
# CHECK-NEXT: ori $a0, $a0, %le_lo12(sym_le)
66+
# CHECK-EMPTY:
67+
# RELOC-NEXT: R_LARCH_TLS_LE_HI20 sym_le 0x0
68+
# RELOC-NEXT: R_LARCH_TLS_LE_LO12 sym_le 0x0
3469

3570
la.tls.ie $a0, sym_ie
36-
# CHECK: pcalau12i $a0, %ie_pc_hi20(sym_ie)
71+
# CHECK-NEXT: pcalau12i $a0, %ie_pc_hi20(sym_ie)
3772
# CHECK-NEXT: ld.d $a0, $a0, %ie_pc_lo12(sym_ie)
73+
# CHECK-EMPTY:
74+
# RELOC-NEXT: R_LARCH_TLS_IE_PC_HI20 sym_ie 0x0
75+
# RELOC-NEXT: R_LARCH_TLS_IE_PC_LO12 sym_ie 0x0
3876

3977
la.tls.ie $a0, $a1, sym_ie_large
40-
# CHECK: pcalau12i $a0, %ie_pc_hi20(sym_ie_large)
78+
# CHECK-NEXT: pcalau12i $a0, %ie_pc_hi20(sym_ie_large)
4179
# CHECK-NEXT: addi.d $a1, $zero, %ie_pc_lo12(sym_ie_large)
4280
# CHECK-NEXT: lu32i.d $a1, %ie64_pc_lo20(sym_ie_large)
4381
# CHECK-NEXT: lu52i.d $a1, $a1, %ie64_pc_hi12(sym_ie_large)
4482
# CHECK-NEXT: ldx.d $a0, $a0, $a1
83+
# CHECK-EMPTY:
84+
# RELOC-NEXT: R_LARCH_TLS_IE_PC_HI20 sym_ie_large 0x0
85+
# RELOC-NEXT: R_LARCH_TLS_IE_PC_LO12 sym_ie_large 0x0
86+
# RELOC-NEXT: R_LARCH_TLS_IE64_PC_LO20 sym_ie_large 0x0
87+
# RELOC-NEXT: R_LARCH_TLS_IE64_PC_HI12 sym_ie_large 0x0
4588

4689
la.tls.ld $a0, sym_ld
47-
# CHECK: pcalau12i $a0, %ld_pc_hi20(sym_ld)
90+
# CHECK-NEXT: pcalau12i $a0, %ld_pc_hi20(sym_ld)
4891
# CHECK-NEXT: addi.d $a0, $a0, %got_pc_lo12(sym_ld)
92+
# CHECK-EMPTY:
93+
# RELOC-NEXT: R_LARCH_TLS_LD_PC_HI20 sym_ld 0x0
94+
# RELOC-NEXT: R_LARCH_GOT_PC_LO12 sym_ld 0x0
4995

5096
la.tls.ld $a0, $a1, sym_ld_large
51-
# CHECK: pcalau12i $a0, %ld_pc_hi20(sym_ld_large)
97+
# CHECK-NEXT: pcalau12i $a0, %ld_pc_hi20(sym_ld_large)
5298
# CHECK-NEXT: addi.d $a1, $zero, %got_pc_lo12(sym_ld_large)
5399
# CHECK-NEXT: lu32i.d $a1, %got64_pc_lo20(sym_ld_large)
54100
# CHECK-NEXT: lu52i.d $a1, $a1, %got64_pc_hi12(sym_ld_large)
55101
# CHECK-NEXT: add.d $a0, $a0, $a1
102+
# CHECK-EMPTY:
103+
# RELOC-NEXT: R_LARCH_TLS_LD_PC_HI20 sym_ld_large 0x0
104+
# RELOC-NEXT: R_LARCH_GOT_PC_LO12 sym_ld_large 0x0
105+
# RELOC-NEXT: R_LARCH_GOT64_PC_LO20 sym_ld_large 0x0
106+
# RELOC-NEXT: R_LARCH_GOT64_PC_HI12 sym_ld_large 0x0
56107

57108
la.tls.gd $a0, sym_gd
58-
# CHECK: pcalau12i $a0, %gd_pc_hi20(sym_gd)
109+
# CHECK-NEXT: pcalau12i $a0, %gd_pc_hi20(sym_gd)
59110
# CHECK-NEXT: addi.d $a0, $a0, %got_pc_lo12(sym_gd)
111+
# CHECK-EMPTY:
112+
# RELOC-NEXT: R_LARCH_TLS_GD_PC_HI20 sym_gd 0x0
113+
# RELOC-NEXT: R_LARCH_GOT_PC_LO12 sym_gd 0x0
60114

61115
la.tls.gd $a0, $a1, sym_gd_large
62-
# CHECK: pcalau12i $a0, %gd_pc_hi20(sym_gd_large)
116+
# CHECK-NEXT: pcalau12i $a0, %gd_pc_hi20(sym_gd_large)
63117
# CHECK-NEXT: addi.d $a1, $zero, %got_pc_lo12(sym_gd_large)
64118
# CHECK-NEXT: lu32i.d $a1, %got64_pc_lo20(sym_gd_large)
65119
# CHECK-NEXT: lu52i.d $a1, $a1, %got64_pc_hi12(sym_gd_large)
66120
# CHECK-NEXT: add.d $a0, $a0, $a1
121+
# CHECK-EMPTY:
122+
# RELOC-NEXT: R_LARCH_TLS_GD_PC_HI20 sym_gd_large 0x0
123+
# RELOC-NEXT: R_LARCH_GOT_PC_LO12 sym_gd_large 0x0
124+
# RELOC-NEXT: R_LARCH_GOT64_PC_LO20 sym_gd_large 0x0
125+
# RELOC-NEXT: R_LARCH_GOT64_PC_HI12 sym_gd_large 0x0
126+
127+
# RELOC-NEXT: }
128+
# RELOC-NEXT: ]

llvm/test/MC/LoongArch/Misc/subsection.s

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# RUN: not llvm-mc --filetype=obj --triple=loongarch64 --mattr=-relax %s -o /dev/null 2>&1 | FileCheck %s --check-prefixes=ERR,NORELAX --implicit-check-not=error:
2-
## TODO: not llvm-mc --filetype=obj --triple=loongarch64 --mattr=+relax %s -o /dev/null 2>&1 | FileCheck %s --check-prefixes=ERR,RELAX --implicit-check-not=error:
2+
# RUN: not llvm-mc --filetype=obj --triple=loongarch64 --mattr=+relax %s -o /dev/null 2>&1 | FileCheck %s --check-prefixes=ERR,RELAX --implicit-check-not=error:
33

44
a:
55
nop

llvm/test/MC/LoongArch/Relocations/relax-addsub.s

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@
1818
# RELAX: Relocations [
1919
# RELAX-NEXT: Section ({{.*}}) .rela.text {
2020
# RELAX-NEXT: 0x10 R_LARCH_PCALA_HI20 .L1 0x0
21+
# RELAX-NEXT: 0x10 R_LARCH_RELAX - 0x0
2122
# RELAX-NEXT: 0x14 R_LARCH_PCALA_LO12 .L1 0x0
23+
# RELAX-NEXT: 0x14 R_LARCH_RELAX - 0x0
2224
# RELAX-NEXT: }
2325
# RELAX-NEXT: Section ({{.*}}) .rela.data {
2426
# RELAX-NEXT: 0xF R_LARCH_ADD8 .L3 0x0
@@ -29,13 +31,21 @@
2931
# RELAX-NEXT: 0x12 R_LARCH_SUB32 .L2 0x0
3032
# RELAX-NEXT: 0x16 R_LARCH_ADD64 .L3 0x0
3133
# RELAX-NEXT: 0x16 R_LARCH_SUB64 .L2 0x0
34+
# RELAX-NEXT: 0x1E R_LARCH_ADD8 .L4 0x0
35+
# RELAX-NEXT: 0x1E R_LARCH_SUB8 .L3 0x0
36+
# RELAX-NEXT: 0x1F R_LARCH_ADD16 .L4 0x0
37+
# RELAX-NEXT: 0x1F R_LARCH_SUB16 .L3 0x0
38+
# RELAX-NEXT: 0x21 R_LARCH_ADD32 .L4 0x0
39+
# RELAX-NEXT: 0x21 R_LARCH_SUB32 .L3 0x0
40+
# RELAX-NEXT: 0x25 R_LARCH_ADD64 .L4 0x0
41+
# RELAX-NEXT: 0x25 R_LARCH_SUB64 .L3 0x0
3242
# RELAX-NEXT: }
3343
# RELAX-NEXT: ]
3444

3545
# RELAX: Hex dump of section '.data':
3646
# RELAX-NEXT: 0x00000000 04040004 00000004 00000000 00000000
37-
# RELAX-NEXT: 0x00000010 00000000 00000000 00000000 00000808
38-
# RELAX-NEXT: 0x00000020 00080000 00080000 00000000 00
47+
# RELAX-NEXT: 0x00000010 00000000 00000000 00000000 00000000
48+
# RELAX-NEXT: 0x00000020 00000000 00000000 00000000 00
3949

4050
.text
4151
.L1:
@@ -60,8 +70,6 @@
6070
.short .L3 - .L2
6171
.word .L3 - .L2
6272
.dword .L3 - .L2
63-
## TODO
64-
## With relaxation, emit relocs because la.pcrel is a linker-relaxable inst.
6573
.byte .L4 - .L3
6674
.short .L4 - .L3
6775
.word .L4 - .L3

0 commit comments

Comments
 (0)