Skip to content

Commit febd4b9

Browse files
committed
[LoongArch][MC] Refine conditions for emitting ALIGN relocations
According to the suggestions in #150816, this commit refine the conditions for emitting R_LARCH_ALIGN relocations. Some existing tests are updated to avoid being affected by this optimization. New tests are added to verify: removal of redundant ALIGN relocations, ALIGN emitted after the first linker-relaxable instruction, and conservatively emitted ALIGN in lower-numbered subsections.
1 parent 1c49935 commit febd4b9

File tree

8 files changed

+170
-49
lines changed

8 files changed

+170
-49
lines changed

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

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -216,10 +216,19 @@ getRelocPairForSize(unsigned Size) {
216216
// size, the fixup encodes MaxBytesToEmit in the higher bits and references a
217217
// per-section marker symbol.
218218
bool LoongArchAsmBackend::relaxAlign(MCFragment &F, unsigned &Size) {
219+
// Alignments before the first linker-relaxable instruction have fixed sizes
220+
// and do not require relocations. Alignments after a linker-relaxable
221+
// instruction require a relocation, even if the STI specifies norelax.
222+
//
223+
// firstLinkerRelaxable is the layout order within the subsection, which may
224+
// be smaller than the section's order. Therefore, alignments in a
225+
// lower-numbered subsection may be unnecessarily treated as linker-relaxable.
226+
auto *Sec = F.getParent();
227+
if (F.getLayoutOrder() <= Sec->firstLinkerRelaxable())
228+
return false;
229+
219230
// Use default handling unless linker relaxation is enabled and the
220231
// MaxBytesToEmit >= the nop size.
221-
if (!F.getSubtargetInfo()->hasFeature(LoongArch::FeatureRelax))
222-
return false;
223232
const unsigned MinNopLen = 4;
224233
unsigned MaxBytesToEmit = F.getAlignMaxBytesToEmit();
225234
if (MaxBytesToEmit < MinNopLen)
@@ -254,8 +263,6 @@ bool LoongArchAsmBackend::relaxAlign(MCFragment &F, unsigned &Size) {
254263
MCFixup::create(0, Expr, FirstLiteralRelocationKind + ELF::R_LARCH_ALIGN);
255264
F.setVarFixups({Fixup});
256265
F.setLinkerRelaxable();
257-
if (!F.getParent()->isLinkerRelaxable())
258-
F.getParent()->setFirstLinkerRelaxable(F.getLayoutOrder());
259266
return true;
260267
}
261268

llvm/test/CodeGen/LoongArch/linker-relaxation.ll

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,8 @@ declare void @callee1() nounwind
2929
declare dso_local void @callee2() nounwind
3030
declare dso_local void @callee3() nounwind
3131

32-
define ptr @caller() nounwind {
33-
; RELAX: R_LARCH_ALIGN - 0x1C
3432
; CHECK-RELOC: R_LARCH_GOT_PC_HI20 g_e 0x0
35-
; RELAX-NEXT: R_LARCH_RELAX - 0x0
33+
; RELAX: R_LARCH_RELAX - 0x0
3634
; CHECK-RELOC-NEXT: R_LARCH_GOT_PC_LO12 g_e 0x0
3735
; RELAX-NEXT: R_LARCH_RELAX - 0x0
3836
; PCALA-RELOC: R_LARCH_PCALA_HI20 .bss 0x0
@@ -77,26 +75,35 @@ define ptr @caller() nounwind {
7775
; RELAX-NEXT: R_LARCH_RELAX - 0x0
7876
; CHECK-RELOC-NEXT: R_LARCH_TLS_LE_LO12_R t_le 0x0
7977
; RELAX-NEXT: R_LARCH_RELAX - 0x0
80-
; CHECK-RELOC-NEXT: R_LARCH_CALL36 callee1 0x0
81-
; RELAX-NEXT: R_LARCH_RELAX - 0x0
82-
; CHECK-RELOC-NEXT: R_LARCH_CALL36 callee2 0x0
83-
; RELAX-NEXT: R_LARCH_RELAX - 0x0
84-
; CHECK-RELOC-NEXT: R_LARCH_CALL36 callee3 0x0
85-
; RELAX-NEXT: R_LARCH_RELAX - 0x0
8678
; PCALA-RELOC: R_LARCH_PCALA_HI20 .data 0x0
8779
; RELAX-NEXT: R_LARCH_PCALA_HI20 g_i1 0x0
8880
; RELAX-NEXT: R_LARCH_RELAX - 0x0
8981
; PCALA-RELOC: R_LARCH_PCALA_LO12 .data 0x0
9082
; RELAX-NEXT: R_LARCH_PCALA_LO12 g_i1 0x0
9183
; RELAX-NEXT: R_LARCH_RELAX - 0x0
84+
; RELAX-NEXT: R_LARCH_ALIGN - 0x1C
85+
; CHECK-RELOC-NEXT: R_LARCH_CALL36 callee1 0x0
86+
; RELAX-NEXT: R_LARCH_RELAX - 0x0
87+
; CHECK-RELOC-NEXT: R_LARCH_CALL36 callee2 0x0
88+
; RELAX-NEXT: R_LARCH_RELAX - 0x0
89+
; CHECK-RELOC-NEXT: R_LARCH_CALL36 callee3 0x0
90+
; RELAX-NEXT: R_LARCH_RELAX - 0x0
91+
92+
;; No ALIGN reloc will emit before the first linker-relaxable instruction.
93+
define ptr @loader() nounwind {
9294
%a = load volatile i32, ptr @g_e
9395
%b = load volatile i32, ptr @g_i
9496
%c = load volatile i32, ptr @t_un
9597
%d = load volatile i32, ptr @t_ld
9698
%e = load volatile i32, ptr @t_ie
9799
%f = load volatile i32, ptr @t_le
100+
ret ptr @g_i1
101+
}
102+
103+
;; ALIGN reloc will be emitted here.
104+
define void @caller() nounwind {
98105
call i32 @callee1()
99106
call i32 @callee2()
100107
tail call i32 @callee3()
101-
ret ptr @g_i1
108+
ret void
102109
}

llvm/test/MC/LoongArch/Misc/cfi-advance.s

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,22 @@
55
# RUN: | llvm-readobj -r - | FileCheck --check-prefix=RELAX %s
66

77
# RELOC: Relocations [
8-
# RELOC-NEXT: .rela.eh_frame {
8+
# RELOC: .rela.eh_frame {
99
# RELOC-NEXT: 0x1C R_LARCH_32_PCREL .text 0x0
1010
# RELOC-NEXT: }
1111
# RELOC-NEXT: ]
12-
# DWARFDUMP: DW_CFA_advance_loc: 4
12+
# DWARFDUMP: DW_CFA_advance_loc: 8
1313
# DWARFDUMP-NEXT: DW_CFA_def_cfa_offset: +8
14-
# DWARFDUMP-NEXT: DW_CFA_advance_loc: 8
14+
# DWARFDUMP-NEXT: DW_CFA_advance_loc: 4
1515
# DWARFDUMP-NEXT: DW_CFA_def_cfa_offset: +8
1616

1717
# RELAX: Relocations [
1818
# RELAX: .rela.eh_frame {
1919
# RELAX-NEXT: 0x1C R_LARCH_32_PCREL .L{{.*}} 0x0
2020
# RELAX-NEXT: 0x20 R_LARCH_ADD32 .L{{.*}} 0x0
2121
# RELAX-NEXT: 0x20 R_LARCH_SUB32 .L{{.*}} 0x0
22+
# RELAX-NEXT: 0x25 R_LARCH_ADD6 .L{{.*}} 0x0
23+
# RELAX-NEXT: 0x25 R_LARCH_SUB6 .L{{.*}} 0x0
2224
# RELAX-NEXT: 0x28 R_LARCH_ADD6 .L{{.*}} 0x0
2325
# RELAX-NEXT: 0x28 R_LARCH_SUB6 .L{{.*}} 0x0
2426
# RELAX-NEXT: }
@@ -30,7 +32,7 @@
3032
.type test,@function
3133
test:
3234
.cfi_startproc
33-
nop
35+
call36 foo
3436
.cfi_def_cfa_offset 8
3537
.p2align 3
3638
nop
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
## The file testing R_LARCH_ALIGN emitting when linker-relaxation enabled.
2+
3+
# RUN: llvm-mc --filetype=obj --triple=loongarch64 --mattr=-relax %s -o %t.n
4+
# RUN: llvm-objdump -dr %t.n | FileCheck %s --check-prefix=NORELAX
5+
# RUN: llvm-mc --filetype=obj --triple=loongarch64 --mattr=+relax %s -o %t.r
6+
# RUN: llvm-objdump -dr %t.r | FileCheck %s --check-prefix=RELAX
7+
8+
# NORELAX: pcaddu18i $ra, 0
9+
# NORELAX-NEXT: R_LARCH_CALL36 f
10+
# NORELAX-NEXT: jirl $ra, $ra, 0
11+
# NORELAX-COUNT-6: nop
12+
# NORELAX: pcaddu18i $ra, 0
13+
# NORELAX-NEXT: R_LARCH_CALL36 f
14+
# NORELAX-NEXT: jirl $ra, $ra, 0
15+
# NORELAX-COUNT-6: nop
16+
# NORELAX: pcaddu18i $ra, 0
17+
# NORELAX-NEXT: R_LARCH_CALL36 f
18+
# NORELAX-NEXT: jirl $ra, $ra, 0
19+
20+
# RELAX: pcaddu18i $ra, 0
21+
# RELAX-NEXT: R_LARCH_CALL36 f
22+
# RELAX-NEXT: R_LARCH_RELAX *ABS*
23+
# RELAX-NEXT: jirl $ra, $ra, 0
24+
# RELAX-NEXT: nop
25+
# RELAX-NEXT: R_LARCH_ALIGN *ABS*+0x1c
26+
# RELAX-COUNT-6: nop
27+
# RELAX: pcaddu18i $ra, 0
28+
# RELAX-NEXT: R_LARCH_CALL36 f
29+
# RELAX-NEXT: R_LARCH_RELAX *ABS*
30+
# RELAX-NEXT: jirl $ra, $ra, 0
31+
# RELAX-NEXT: nop
32+
# RELAX-NEXT: R_LARCH_ALIGN *ABS*+0x1c
33+
# RELAX-COUNT-6: nop
34+
# RELAX: pcaddu18i $ra, 0
35+
# RELAX-NEXT: R_LARCH_CALL36 f
36+
# RELAX-NEXT: jirl $ra, $ra, 0
37+
38+
.text
39+
## No R_LARCH_ALIGN before the first linker-relaxable instruction.
40+
.p2align 5
41+
foo:
42+
call36 f
43+
44+
## R_LARCH_ALIGN is required after the first linker-relaxable instruction.
45+
.p2align 5
46+
bar:
47+
call36 f
48+
49+
.option push
50+
.option norelax
51+
## R_LARCH_ALIGN is required even if norelax, because it is after a
52+
## linker-relaxable instruction. No R_LARCH_RELAX for call36 because
53+
## of the norelax.
54+
.p2align 5
55+
baz:
56+
call36 f
57+
.option pop

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

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@
55

66
# NORELAX: Relocations [
77
# NORELAX-NEXT: Section ({{.*}}) .rela.text {
8-
# NORELAX-NEXT: 0x10 R_LARCH_PCALA_HI20 .text 0x0
9-
# NORELAX-NEXT: 0x14 R_LARCH_PCALA_LO12 .text 0x0
8+
# NORELAX-NEXT: 0x0 R_LARCH_CALL36 foo 0x0
9+
# NORELAX-NEXT: 0x10 R_LARCH_PCALA_HI20 .text 0x8
10+
# NORELAX-NEXT: 0x14 R_LARCH_PCALA_LO12 .text 0x8
1011
# NORELAX-NEXT: }
1112
# NORELAX-NEXT: Section ({{.*}}) .rela.data {
1213
# NORELAX-NEXT: 0x30 R_LARCH_ADD8 foo 0x0
@@ -22,17 +23,19 @@
2223

2324
# NORELAX: Hex dump of section '.data':
2425
# NORELAX-NEXT: 0x00000000 04040004 00000004 00000000 00000004
25-
# NORELAX-NEXT: 0x00000010 0c0c000c 0000000c 00000000 0000000c
26+
# NORELAX-NEXT: 0x00000010 04040004 00000004 00000000 00000004
2627
# NORELAX-NEXT: 0x00000020 08080008 00000008 00000000 00000008
2728
# NORELAX-NEXT: 0x00000030 00000000 00000000 00000000 000000
2829

2930
# RELAX: Relocations [
3031
# RELAX-NEXT: Section ({{.*}}) .rela.text {
31-
# RELAX-NEXT: 0x4 R_LARCH_ALIGN - 0xC
32-
# RELAX-NEXT: 0x10 R_LARCH_PCALA_HI20 .L1 0x0
33-
# RELAX-NEXT: 0x10 R_LARCH_RELAX - 0x0
34-
# RELAX-NEXT: 0x14 R_LARCH_PCALA_LO12 .L1 0x0
35-
# RELAX-NEXT: 0x14 R_LARCH_RELAX - 0x0
32+
# RELAX-NEXT: 0x0 R_LARCH_CALL36 foo 0x0
33+
# RELAX-NEXT: 0x0 R_LARCH_RELAX - 0x0
34+
# RELAX-NEXT: 0xC R_LARCH_ALIGN - 0xC
35+
# RELAX-NEXT: 0x18 R_LARCH_PCALA_HI20 .L1 0x0
36+
# RELAX-NEXT: 0x18 R_LARCH_RELAX - 0x0
37+
# RELAX-NEXT: 0x1C R_LARCH_PCALA_LO12 .L1 0x0
38+
# RELAX-NEXT: 0x1C R_LARCH_RELAX - 0x0
3639
# RELAX-NEXT: }
3740
# RELAX-NEXT: Section ({{.*}}) .rela.data {
3841
# RELAX-NEXT: 0x10 R_LARCH_ADD8 .L3 0x0
@@ -73,6 +76,7 @@
7376
# RELAX-NEXT: 0x00000030 00000000 00000000 00000000 000000
7477

7578
.text
79+
call36 foo
7680
.L1:
7781
nop
7882
.L2:
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
## The file testing R_LARCH_ALIGN emitting when linker-relaxation enabled.
2+
3+
# RUN: llvm-mc --filetype=obj --triple=loongarch64 --mattr=+relax %s -o %t.n
4+
# RUN: llvm-objdump -dr %t.n | FileCheck %s --check-prefix=RELAX
5+
# RUN: llvm-mc --filetype=obj --triple=loongarch64 --mattr=+relax --defsym FILL=1 %s -o %t.f
6+
# RUN: llvm-objdump -dr %t.f | FileCheck %s --check-prefixes=RELAX,ALIGN
7+
8+
# ALIGN: nop
9+
# ALIGN-NEXT: R_LARCH_ALIGN *ABS*+0x1c
10+
# ALIGN-COUNT-6: nop
11+
# RELAX: ret
12+
# RELAX: pcaddu18i $ra, 0
13+
# RELAX-NEXT: R_LARCH_CALL36 f
14+
# RELAX-NEXT: R_LARCH_RELAX *ABS*
15+
# RELAX-NEXT: jirl $ra, $ra, 0
16+
17+
.text
18+
.option push
19+
.option norelax
20+
## When FILL is defined, the order of Alignment directive in this lower-numbered
21+
## subsection will be larger, and even larger than the section order of the first
22+
## linker-relaxable call36 instruction. It should conservatively be treated as
23+
## linker-relaxable even has norelax.
24+
.ifdef FILL
25+
.space 0
26+
.endif
27+
.p2align 5
28+
foo:
29+
ret
30+
.option pop
31+
32+
.text 1
33+
.space 0
34+
bar:
35+
call36 f

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

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@
88
# RUN: llvm-readobj -r %t.r | FileCheck %s --check-prefixes=RELOC,RELAX-RELOC
99

1010
.text
11-
break 0
12-
# INSTR: break 0
11+
call36 foo
12+
# INSTR: pcaddu18i $ra, 0
13+
# INSTR-NEXT: jirl $ra, $ra, 0
1314

1415
## Not emit R_LARCH_ALIGN if alignment directive is less than or equal to
1516
## minimum code alignment(a.k.a 4).
@@ -24,8 +25,8 @@ break 0
2425
## The behavior is the same as GNU assembler.
2526
break 1
2627
.p2align 4, 1
27-
# INSTR-NEXT: break 1
28-
# INSTR-COUNT-2: 01 01 01 01
28+
# INSTR-NEXT: break 1
29+
# INSTR-NEXT: 01 01 01 01
2930

3031
break 2
3132
.p2align 4, 1, 12
@@ -62,20 +63,25 @@ ret
6263

6364
## Test the symbol index is different from .text.
6465
.section .text2, "ax"
66+
call36 foo
6567
.p2align 4
6668
.p2align 4, , 4
6769
break 7
6870

6971
# RELOC: Relocations [
70-
# RELAX-RELOC-NEXT: Section ({{.*}}) .rela.text {
72+
# RELOC-NEXT: Section ({{.*}}) .rela.text {
73+
# RELOC-NEXT: 0x0 R_LARCH_CALL36 foo 0x0
74+
# RELAX-RELOC-NEXT: 0x0 R_LARCH_RELAX - 0x0
7175
# RELAX-RELOC-NEXT: 0x24 R_LARCH_ALIGN - 0xC
7276
# RELAX-RELOC-NEXT: 0x34 R_LARCH_ALIGN - 0x1C
7377
# RELAX-RELOC-NEXT: 0x50 R_LARCH_ALIGN - 0xC
7478
# RELAX-RELOC-NEXT: 0x60 R_LARCH_ALIGN .Lla-relax-align0 0xB04
7579
# RELAX-RELOC-NEXT: 0x70 R_LARCH_ALIGN - 0xC
76-
# RELAX-RELOC-NEXT: }
77-
# RELAX-RELOC-NEXT: Section ({{.*}}) .rela.text2 {
78-
# RELAX-RELOC-NEXT: 0x0 R_LARCH_ALIGN - 0xC
79-
# RELAX-RELOC-NEXT: 0xC R_LARCH_ALIGN .Lla-relax-align1 0x404
80-
# RELAX-RELOC-NEXT: }
80+
# RELOC-NEXT: }
81+
# RELOC-NEXT: Section ({{.*}}) .rela.text2 {
82+
# RELOC-NEXT: 0x0 R_LARCH_CALL36 foo 0x0
83+
# RELAX-RELOC-NEXT: 0x0 R_LARCH_RELAX - 0x0
84+
# RELAX-RELOC-NEXT: 0x8 R_LARCH_ALIGN - 0xC
85+
# RELAX-RELOC-NEXT: 0x14 R_LARCH_ALIGN .Lla-relax-align1 0x404
86+
# RELOC-NEXT: }
8187
# RELOC-NEXT: ]

llvm/test/MC/LoongArch/Relocations/sub-expr.s

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,28 +11,29 @@
1111
# CHECK-NEXT: Section ({{.*}}) .rela.sx {
1212
# CHECK-NEXT: 0x4 R_LARCH_PCALA_HI20 z 0x0
1313
# CHECK-NEXT: 0x8 R_LARCH_PCALA_LO12 z 0x0
14-
# CHECK-NEXT: 0xC R_LARCH_32_PCREL .sy 0xC
14+
# CHECK-NEXT: 0xC R_LARCH_32_PCREL .sy 0x10
1515
# CHECK-NEXT: }
1616
# CHECK-NEXT: Section ({{.*}}) .rela.data {
1717
# CHECK-NEXT: 0x0 R_LARCH_64_PCREL .sx 0x4
18-
# CHECK-NEXT: 0x8 R_LARCH_64_PCREL .sy 0x4
18+
# CHECK-NEXT: 0x8 R_LARCH_64_PCREL .sy 0x8
1919
# CHECK-NEXT: 0x10 R_LARCH_32_PCREL .sx 0x4
20-
# CHECK-NEXT: 0x14 R_LARCH_32_PCREL .sy 0x4
20+
# CHECK-NEXT: 0x14 R_LARCH_32_PCREL .sy 0x8
2121
# CHECK-NEXT: 0x18 R_LARCH_ADD64 .sx 0x4
22-
# CHECK-NEXT: 0x18 R_LARCH_SUB64 .sy 0x4
23-
# CHECK-NEXT: 0x20 R_LARCH_ADD64 .sy 0x4
22+
# CHECK-NEXT: 0x18 R_LARCH_SUB64 .sy 0x8
23+
# CHECK-NEXT: 0x20 R_LARCH_ADD64 .sy 0x8
2424
# CHECK-NEXT: 0x20 R_LARCH_SUB64 .sx 0x4
2525
# CHECK-NEXT: 0x28 R_LARCH_ADD32 .sx 0x4
26-
# CHECK-NEXT: 0x28 R_LARCH_SUB32 .sy 0x4
27-
# CHECK-NEXT: 0x2C R_LARCH_ADD32 .sy 0x4
26+
# CHECK-NEXT: 0x28 R_LARCH_SUB32 .sy 0x8
27+
# CHECK-NEXT: 0x2C R_LARCH_ADD32 .sy 0x8
2828
# CHECK-NEXT: 0x2C R_LARCH_SUB32 .sx 0x4
2929
# CHECK-NEXT: 0x30 R_LARCH_ADD64 .data 0x30
3030
# CHECK-NEXT: 0x30 R_LARCH_SUB64 .sx 0x4
3131
# CHECK-NEXT: 0x38 R_LARCH_ADD32 .data 0x38
32-
# CHECK-NEXT: 0x38 R_LARCH_SUB32 .sy 0x4
32+
# CHECK-NEXT: 0x38 R_LARCH_SUB32 .sy 0x8
3333
# CHECK-NEXT: }
3434
# CHECK-NEXT: Section ({{.*}}) .rela.sy {
35-
# CHECK-NEXT: 0x10 R_LARCH_32_PCREL .sx 0x10
35+
# CHECK-NEXT: 0x0 R_LARCH_CALL36 foo 0x0
36+
# CHECK-NEXT: 0x10 R_LARCH_32_PCREL .sx 0xC
3637
# CHECK-NEXT: }
3738
# CHECK-NEXT: ]
3839

@@ -64,9 +65,11 @@
6465
# RELAX-NEXT: 0x38 R_LARCH_SUB32 y 0x0
6566
# RELAX-NEXT: }
6667
# RELAX-NEXT: Section ({{.*}}) .rela.sy {
67-
# RELAX-NEXT: 0x4 R_LARCH_ALIGN - 0xC
68-
# RELAX-NEXT: 0x10 R_LARCH_ADD32 x 0x0
69-
# RELAX-NEXT: 0x10 R_LARCH_SUB32 y 0x0
68+
# RELAX-NEXT: 0x0 R_LARCH_CALL36 foo 0x0
69+
# RELAX-NEXT: 0x0 R_LARCH_RELAX - 0x0
70+
# RELAX-NEXT: 0x8 R_LARCH_ALIGN - 0xC
71+
# RELAX-NEXT: 0x14 R_LARCH_ADD32 x 0x0
72+
# RELAX-NEXT: 0x14 R_LARCH_SUB32 y 0x0
7073
# RELAX-NEXT: }
7174
# RELAX-NEXT: ]
7275

@@ -89,7 +92,7 @@ la.pcrel $a0, z
8992
.4byte .-y
9093

9194
.section .sy,"ax"
92-
nop
95+
call36 foo
9396
y:
9497
.p2align 4
9598
.4byte x-y

0 commit comments

Comments
 (0)