Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[ELF][RISCV] Relax local-exec TLS model
In -mrelax mode, GCC/Clang may generate a local-exec TLS code sequence like: ``` # R_RISCV_TPREL_HI20, R_RISCV_RELAX lui rd, %tprel_hi(x) # R_RISCV_TPREL_ADD, R_RISCV_RELAX add rd, rd, tp, %tprel_add(x) # (R_RISCV_TPREL_LO12_I || R_RISCV_TPREL_LO12_S), R_RISCV_RELAX addi rd, rd, %tprel_lo(x) || sw rs, %tprel(x)(rd) ``` Note: st_value(x) for TLS should be in the range [0,p_memsz(PT_TLS)). When st_value(x) < 2048 (i.e. hi20(x) == 0), the linker can relax the code sequence to: ``` addi rd, tp, st_value(x) || sw rs, st_value(x)(rd) ``` Differential Revision: https://reviews.llvm.org/D129425
- Loading branch information
Showing
2 changed files
with
129 additions
and
34 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,48 +1,91 @@ | ||
# REQUIRES: riscv | ||
|
||
## Additionally test that (a) -no-pie/-pie have the same behavior | ||
## (b) --no-relax/--relax have the same behavior when R_RISCV_RELAX is suppressed. | ||
# RUN: llvm-mc -filetype=obj -triple=riscv32 %s -o %t.32.o | ||
# RUN: ld.lld %t.32.o -o %t.32 | ||
# RUN: ld.lld --relax %t.32.o -o %t.32 | ||
# RUN: llvm-nm -p %t.32 | FileCheck --check-prefixes=NM %s | ||
# RUN: llvm-objdump -d --no-show-raw-insn %t.32 | FileCheck --check-prefixes=LE %s | ||
# RUN: ld.lld -pie %t.32.o -o %t.32 | ||
# RUN: ld.lld -pie --no-relax %t.32.o -o %t.32 | ||
# RUN: llvm-objdump -d --no-show-raw-insn %t.32 | FileCheck --check-prefixes=LE %s | ||
|
||
# RUN: llvm-mc -filetype=obj -triple=riscv64 %s -o %t.64.o | ||
# RUN: ld.lld %t.64.o -o %t.64 | ||
# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+relax %s -o %t.64.o | ||
# RUN: ld.lld --no-relax %t.64.o -o %t.64 | ||
# RUN: llvm-objdump -d --no-show-raw-insn %t.64 | FileCheck --check-prefixes=LE %s | ||
# RUN: ld.lld -pie %t.64.o -o %t.64 | ||
# RUN: ld.lld -pie --no-relax %t.64.o -o %t.64 | ||
# RUN: llvm-objdump -d --no-show-raw-insn %t.64 | FileCheck --check-prefixes=LE %s | ||
# RUN: ld.lld %t.64.o -o %t.64.relax | ||
# RUN: llvm-objdump -d --no-show-raw-insn %t.64.relax | FileCheck --check-prefixes=LE-RELAX %s | ||
|
||
# RUN: not ld.lld -shared %t.32.o -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR --implicit-check-not=error: | ||
|
||
# ERR: error: relocation R_RISCV_TPREL_HI20 against .LANCHOR0 cannot be used with -shared | ||
# ERR: error: relocation R_RISCV_TPREL_LO12_I against .LANCHOR0 cannot be used with -shared | ||
# ERR: error: relocation R_RISCV_TPREL_HI20 against a cannot be used with -shared | ||
# ERR: error: relocation R_RISCV_TPREL_LO12_I against a cannot be used with -shared | ||
# ERR: error: relocation R_RISCV_TPREL_HI20 against a cannot be used with -shared | ||
# ERR: error: relocation R_RISCV_TPREL_LO12_S against a cannot be used with -shared | ||
# ERR: error: relocation R_RISCV_TPREL_HI20 against a cannot be used with -shared | ||
# ERR: error: relocation R_RISCV_TPREL_LO12_S against a cannot be used with -shared | ||
|
||
# NM: {{0*}}00000008 b .LANCHOR0 | ||
# NM: {{0*}}0000000c B a | ||
# NM: {{0*}}00000800 B a | ||
|
||
## .LANCHOR0@tprel = 8 | ||
## a@tprel = 12 | ||
# LE: lui a5, 0 | ||
# LE-NEXT: add a5, a5, tp | ||
# LE-NEXT: addi a5, a5, 8 | ||
# LE-NEXT: lui a5, 0 | ||
# LE-NEXT: add a5, a5, tp | ||
# LE-NEXT: sw a0, 12(a5) | ||
# LE: lui a1, 0 | ||
# LE-NEXT: add a1, a1, tp | ||
# LE-NEXT: addi a1, a1, 8 | ||
# LE-NEXT: lui a2, 0 | ||
# LE-NEXT: add a2, a2, tp | ||
# LE-NEXT: addi a2, a2, 2044 | ||
# LE-NEXT: lui a3, 0 | ||
# LE-NEXT: addi a0, a0, 1 | ||
# LE-NEXT: add a3, a3, tp | ||
# LE-NEXT: addi a0, a0, 2 | ||
# LE-NEXT: sw a0, 2044(a3) | ||
# LE-NEXT: lui a4, 1 | ||
# LE-NEXT: add a4, a4, tp | ||
# LE-NEXT: sw a0, -2048(a4) | ||
# LE-EMPTY: | ||
|
||
# LE-RELAX: <.text>: | ||
# LE-RELAX-NEXT: addi a1, tp, 8 | ||
# LE-RELAX-NEXT: addi a2, tp, 2044 | ||
# LE-RELAX-NEXT: addi a0, a0, 1 | ||
# LE-RELAX-NEXT: addi a0, a0, 2 | ||
# LE-RELAX-NEXT: sw a0, 2044(tp) | ||
# LE-RELAX-NEXT: lui a4, 1 | ||
# LE-RELAX-NEXT: add a4, a4, tp | ||
# LE-RELAX-NEXT: sw a0, -2048(a4) | ||
# LE-RELAX-EMPTY: | ||
|
||
lui a5, %tprel_hi(.LANCHOR0) | ||
add a5, a5, tp, %tprel_add(.LANCHOR0) | ||
addi a5, a5, %tprel_lo(.LANCHOR0) | ||
lui a1, %tprel_hi(.LANCHOR0) | ||
add a1, a1, tp, %tprel_add(.LANCHOR0) | ||
addi a1, a1, %tprel_lo(.LANCHOR0) | ||
|
||
lui a5, %tprel_hi(a) | ||
add a5, a5, tp, %tprel_add(a) | ||
sw a0, %tprel_lo(a)(a5) | ||
## hi20(a-4) = hi20(0x7fc) = 0. relaxable | ||
lui a2, %tprel_hi(a-4) | ||
add a2, a2, tp, %tprel_add(a-4) | ||
addi a2, a2, %tprel_lo(a-4) | ||
|
||
## hi20(a-4) = hi20(0x7fc) = 0. relaxable | ||
## Test non-adjacent instructions. | ||
lui a3, %tprel_hi(a-4) | ||
addi a0, a0, 1 | ||
add a3, a3, tp, %tprel_add(a-4) | ||
addi a0, a0, 2 | ||
sw a0, %tprel_lo(a-4)(a3) | ||
|
||
## hi20(a) = hi20(0x800) = 1. not relaxable | ||
lui a4, %tprel_hi(a) | ||
add a4, a4, tp, %tprel_add(a) | ||
sw a0, %tprel_lo(a)(a4) | ||
|
||
.section .tbss | ||
.space 8 | ||
.LANCHOR0: | ||
.zero 4 | ||
.space 0x800-8 | ||
.globl a | ||
a: | ||
.zero 4 |