1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 11:13:28 +01:00
llvm-mirror/test/MC/RISCV/pcrel-fixups.s
James Clarke cab1120454 [RISCV] Fix evaluating %pcrel_lo against global and weak symbols
Summary:
Previously, we would erroneously turn %pcrel_lo(label), where label has
a %pcrel_hi against a weak symbol, into %pcrel_lo(label + offset), as
evaluatePCRelLo would believe the target independent logic was going to
fold it. Moreover, even if that were fixed, shouldForceRelocation lacks
an MCAsmLayout and thus cannot evaluate the %pcrel_hi fixup to a value
and check the symbol, so we would then erroneously constant-fold the
%pcrel_lo whilst leaving the %pcrel_hi intact. After D72197, this same
sequence also occurs for symbols with global binding, which is triggered
in real-world code.

Instead, as discussed in D71978, we introduce a new FKF_IsTarget flag to
avoid these kinds of issues. All the resolution logic happens in one
place, with no coordination required between RISCAsmBackend and
RISCVMCExpr to ensure they implement the same logic twice. Although the
implementation of %pcrel_hi can be left as target independent, we make
it target dependent to ensure that they are handled identically to
%pcrel_lo, otherwise we risk one of them being constant folded but the
other being preserved. This also allows us to properly support fixup
pairs where the instructions are in different fragments.

Reviewers: asb, lenary, efriedma

Reviewed By: efriedma

Subscribers: arichardson, hiraditya, rbar, johnrusso, simoncook, sabuasal, niosHD, kito-cheng, shiva0217, MaskRay, zzheng, edward-jones, rogfer01, MartinMosbeck, brucehoult, the_o, rkruppe, PkmX, jocewei, psnobl, benna, Jim, s.egerton, pzheng, sameer.abuasal, apazos, luismarques, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D73211
2020-01-23 02:05:48 +00:00

113 lines
3.2 KiB
ArmAsm

# RUN: llvm-mc -triple riscv32 -mattr=-relax -filetype obj %s \
# RUN: | llvm-objdump -M no-aliases -d -r - \
# RUN: | FileCheck --check-prefix NORELAX %s
# RUN: llvm-mc -triple riscv32 -mattr=+relax -filetype obj %s \
# RUN: | llvm-objdump -M no-aliases -d -r - \
# RUN: | FileCheck --check-prefix RELAX %s
# RUN: llvm-mc -triple riscv64 -mattr=-relax -filetype obj %s \
# RUN: | llvm-objdump -M no-aliases -d -r - \
# RUN: | FileCheck --check-prefix NORELAX %s
# RUN: llvm-mc -triple riscv64 -mattr=+relax -filetype obj %s \
# RUN: | llvm-objdump -M no-aliases -d -r - \
# RUN: | FileCheck --check-prefix RELAX %s
# Fixups for %pcrel_hi / %pcrel_lo can be evaluated within a section,
# regardless of the fragment containing the target address, provided symbol
# binding allows it.
function:
.Lpcrel_label1:
auipc a0, %pcrel_hi(local_function)
addi a1, a0, %pcrel_lo(.Lpcrel_label1)
# NORELAX: auipc a0, 0
# NORELAX-NOT: R_RISCV
# NORELAX: addi a1, a0, 16
# NORELAX-NOT: R_RISCV
# RELAX: auipc a0, 0
# RELAX: R_RISCV_PCREL_HI20 local_function
# RELAX: R_RISCV_RELAX *ABS*
# RELAX: addi a1, a0, 0
# RELAX: R_RISCV_PCREL_LO12_I .Lpcrel_label1
# RELAX: R_RISCV_RELAX *ABS*
.p2align 2 # Cause a new fragment be emitted here
.Lpcrel_label2:
auipc a0, %pcrel_hi(local_function)
addi a1, a0, %pcrel_lo(.Lpcrel_label2)
# NORELAX: auipc a0, 0
# NORELAX-NOT: R_RISCV
# NORELAX: addi a1, a0, 8
# NORELAX-NOT: R_RISCV
# RELAX: auipc a0, 0
# RELAX: R_RISCV_PCREL_HI20 local_function
# RELAX: R_RISCV_RELAX *ABS*
# RELAX: addi a1, a0, 0
# RELAX: R_RISCV_PCREL_LO12_I .Lpcrel_label2
# RELAX: R_RISCV_RELAX *ABS*
.type local_function,@function
local_function:
ret
# Check we correctly evaluate when fixups are in different fragments
.Lpcrel_label3:
auipc a0, %pcrel_hi(local_function)
.p2align 2 # Cause a new fragment be emitted here
addi a1, a0, %pcrel_lo(.Lpcrel_label3)
# NORELAX: auipc a0, 0
# NORELAX-NOT: R_RISCV
# NORELAX: addi a1, a0, -4
# NORELAX-NOT: R_RISCV
# RELAX: auipc a0, 0
# RELAX: R_RISCV_PCREL_HI20 local_function
# RELAX: R_RISCV_RELAX *ABS*
# RELAX: addi a1, a0, 0
# RELAX: R_RISCV_PCREL_LO12_I .Lpcrel_label3
# RELAX: R_RISCV_RELAX *ABS*
# Check handling of symbol binding.
.Lpcrel_label4:
auipc a0, %pcrel_hi(global_function)
addi a1, a0, %pcrel_lo(.Lpcrel_label4)
# NORELAX: auipc a0, 0
# NORELAX: R_RISCV_PCREL_HI20 global_function
# NORELAX: addi a1, a0, 0
# NORELAX: R_RISCV_PCREL_LO12_I .Lpcrel_label4
# RELAX: auipc a0, 0
# RELAX: R_RISCV_PCREL_HI20 global_function
# RELAX: R_RISCV_RELAX *ABS*
# RELAX: addi a1, a0, 0
# RELAX: R_RISCV_PCREL_LO12_I .Lpcrel_label4
# RELAX: R_RISCV_RELAX *ABS*
.Lpcrel_label5:
auipc a0, %pcrel_hi(weak_function)
addi a1, a0, %pcrel_lo(.Lpcrel_label5)
# NORELAX: auipc a0, 0
# NORELAX: R_RISCV_PCREL_HI20 weak_function
# NORELAX: addi a1, a0, 0
# NORELAX: R_RISCV_PCREL_LO12_I .Lpcrel_label5
# RELAX: auipc a0, 0
# RELAX: R_RISCV_PCREL_HI20 weak_function
# RELAX: R_RISCV_RELAX *ABS*
# RELAX: addi a1, a0, 0
# RELAX: R_RISCV_PCREL_LO12_I .Lpcrel_label5
# RELAX: R_RISCV_RELAX *ABS*
.global global_function
.type global_function,@function
global_function:
ret
.weak weak_function
.type weak_function,@function
weak_function:
ret