mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 11:13:28 +01:00
cab1120454
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
113 lines
3.2 KiB
ArmAsm
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
|