Skip to content

Commit 54a41b3

Browse files
msizanoen1cuviper
authored andcommitted
[RISCV] Fix evaluation of %pcrel_lo (#29)
The following testcase function: .Lpcrel_label1: auipc a0, %pcrel_hi(other_function) addi a1, a0, %pcrel_lo(.Lpcrel_label1) .p2align 2 # Causes a new fragment to be emitted .type other_function,@function other_function: ret exposes an odd behaviour in which only the %pcrel_hi relocation is evaluated but not the %pcrel_lo. $ llvm-mc -triple riscv64 -filetype obj t.s | llvm-objdump -d -r - <stdin>: file format ELF64-riscv Disassembly of section .text: 0000000000000000 function: 0: 17 05 00 00 auipc a0, 0 4: 93 05 05 00 mv a1, a0 0000000000000004: R_RISCV_PCREL_LO12_I other_function+4 0000000000000008 other_function: 8: 67 80 00 00 ret The reason seems to be that in RISCVAsmBackend::shouldForceRelocation we only consider the fragment but in RISCVMCExpr::evaluatePCRelLo we consider the section. This usually works but there are cases where the section may still be the same but the fragment may be another one. In that case we end forcing a %pcrel_lo relocation without any %pcrel_hi. This patch makes RISCVAsmBackend::shouldForceRelocation use the section, if any, to determine if the relocation must be forced or not. Differential Revision: https://reviews.llvm.org/D60657
1 parent 2eb727a commit 54a41b3

File tree

2 files changed

+59
-3
lines changed

2 files changed

+59
-3
lines changed

Diff for: llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp

+7-3
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,15 @@ bool RISCVAsmBackend::shouldForceRelocation(const MCAssembler &Asm,
5757
case RISCV::fixup_riscv_tls_gd_hi20:
5858
ShouldForce = true;
5959
break;
60-
case RISCV::fixup_riscv_pcrel_hi20:
61-
ShouldForce = T->getValue()->findAssociatedFragment() !=
62-
Fixup.getValue()->findAssociatedFragment();
60+
case RISCV::fixup_riscv_pcrel_hi20: {
61+
MCFragment *TFragment = T->getValue()->findAssociatedFragment();
62+
MCFragment *FixupFragment = Fixup.getValue()->findAssociatedFragment();
63+
assert(FixupFragment && "We should have a fragment for this fixup");
64+
ShouldForce =
65+
!TFragment || TFragment->getParent() != FixupFragment->getParent();
6366
break;
6467
}
68+
}
6569
break;
6670
}
6771

Diff for: llvm/test/MC/RISCV/pcrel-fixups.s

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# RUN: llvm-mc -triple riscv32 -mattr=-relax -filetype obj %s \
2+
# RUN: | llvm-objdump -M no-aliases -d -r - \
3+
# RUN: | FileCheck --check-prefix NORELAX %s
4+
# RUN: llvm-mc -triple riscv32 -mattr=+relax -filetype obj %s \
5+
# RUN: | llvm-objdump -M no-aliases -d -r - \
6+
# RUN: | FileCheck --check-prefix RELAX %s
7+
# RUN: llvm-mc -triple riscv64 -mattr=-relax -filetype obj %s \
8+
# RUN: | llvm-objdump -M no-aliases -d -r - \
9+
# RUN: | FileCheck --check-prefix NORELAX %s
10+
# RUN: llvm-mc -triple riscv64 -mattr=+relax -filetype obj %s \
11+
# RUN: | llvm-objdump -M no-aliases -d -r - \
12+
# RUN: | FileCheck --check-prefix RELAX %s
13+
14+
# Fixups for %pcrel_hi / %pcrel_lo can be evaluated within a section,
15+
# regardless of the fragment containing the target address.
16+
17+
function:
18+
.Lpcrel_label1:
19+
auipc a0, %pcrel_hi(other_function)
20+
addi a1, a0, %pcrel_lo(.Lpcrel_label1)
21+
# NORELAX: auipc a0, 0
22+
# NORELAX-NOT: R_RISCV
23+
# NORELAX: addi a1, a0, 16
24+
# NORELAX-NOT: R_RISCV
25+
26+
# RELAX: auipc a0, 0
27+
# RELAX: R_RISCV_PCREL_HI20 other_function
28+
# RELAX: R_RISCV_RELAX *ABS*
29+
# RELAX: addi a1, a0, 0
30+
# RELAX: R_RISCV_PCREL_LO12_I .Lpcrel_label1
31+
# RELAX: R_RISCV_RELAX *ABS*
32+
33+
.p2align 2 # Cause a new fragment be emitted here
34+
.Lpcrel_label2:
35+
auipc a0, %pcrel_hi(other_function)
36+
addi a1, a0, %pcrel_lo(.Lpcrel_label2)
37+
# NORELAX: auipc a0, 0
38+
# NORELAX-NOT: R_RISCV
39+
# NORELAX: addi a1, a0, 8
40+
# NORELAX-NOT: R_RISCV
41+
42+
# RELAX: auipc a0, 0
43+
# RELAX: R_RISCV_PCREL_HI20 other_function
44+
# RELAX: R_RISCV_RELAX *ABS*
45+
# RELAX: addi a1, a0, 0
46+
# RELAX: R_RISCV_PCREL_LO12_I .Lpcrel_label2
47+
# RELAX: R_RISCV_RELAX *ABS*
48+
49+
.type other_function,@function
50+
other_function:
51+
ret
52+

0 commit comments

Comments
 (0)