Skip to content

Commit 555e0e7

Browse files
Vitaly Cheptsovtstellar
authored andcommitted
[RISCV] Support emulated TLS
As discussed earlier in the [GitHub issue](#59500), currently LLVM generates invalid code when emulated TLS is used. There were attempts to resolve this previously (D102527), but they were not merged because the component owners raised concerns about emulated TLS efficiency. The current state of the art is that: - OpenBSD team, which raised the initial issue, simply has [patches downstream](https://github.com/openbsd/src/blob/a0747c9/gnu/llvm/llvm/lib/Target/RISCV/RISCVISelLowering.cpp#L2850-L2852). - Our team, which raised the GH issue, has patches downstream as well. We also do not use `malloc` or any [dynamic allocations](#59500 (comment)) with emulated TLS, so the concerns raised in the original issue does not apply to us. - GCC compatibility is broken, because GCC supports emulated TLS. - RISC-V is the only architecture in LLVM that does not support emulated TLS, and work is being done to at least warn the users about it (D143619). With all these in mind I believe it is important to address the consumers' needs especially given that there is little to no maintenance downsides. Differential Revision: https://reviews.llvm.org/D143708 (cherry picked from commit f5e63f8)
1 parent 356cb7e commit 555e0e7

File tree

2 files changed

+142
-0
lines changed

2 files changed

+142
-0
lines changed

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4540,6 +4540,9 @@ SDValue RISCVTargetLowering::lowerGlobalTLSAddress(SDValue Op,
45404540
GlobalAddressSDNode *N = cast<GlobalAddressSDNode>(Op);
45414541
assert(N->getOffset() == 0 && "unexpected offset in global node");
45424542

4543+
if (DAG.getTarget().useEmulatedTLS())
4544+
return LowerToTLSEmulatedModel(N, DAG);
4545+
45434546
TLSModel::Model Model = getTargetMachine().getTLSModel(N->getGlobal());
45444547

45454548
if (DAG.getMachineFunction().getFunction().getCallingConv() ==

llvm/test/CodeGen/RISCV/emutls.ll

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2+
; RUN: llc -mtriple=riscv32 -emulated-tls -relocation-model=pic < %s \
3+
; RUN: | FileCheck -check-prefix=RV32 %s
4+
; RUN: llc -mtriple=riscv64 -emulated-tls -relocation-model=pic < %s \
5+
; RUN: | FileCheck -check-prefix=RV64 %s
6+
7+
@external_x = external thread_local global i32, align 8
8+
@y = thread_local global i8 7, align 2
9+
@internal_z = internal thread_local global i64 9, align 16
10+
11+
define ptr @get_external_x() nounwind {
12+
; RV32-LABEL: get_external_x:
13+
; RV32: # %bb.0: # %entry
14+
; RV32-NEXT: addi sp, sp, -16
15+
; RV32-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
16+
; RV32-NEXT: .Lpcrel_hi0:
17+
; RV32-NEXT: auipc a0, %got_pcrel_hi(__emutls_v.external_x)
18+
; RV32-NEXT: lw a0, %pcrel_lo(.Lpcrel_hi0)(a0)
19+
; RV32-NEXT: call __emutls_get_address@plt
20+
; RV32-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
21+
; RV32-NEXT: addi sp, sp, 16
22+
; RV32-NEXT: ret
23+
;
24+
; RV64-LABEL: get_external_x:
25+
; RV64: # %bb.0: # %entry
26+
; RV64-NEXT: addi sp, sp, -16
27+
; RV64-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
28+
; RV64-NEXT: .Lpcrel_hi0:
29+
; RV64-NEXT: auipc a0, %got_pcrel_hi(__emutls_v.external_x)
30+
; RV64-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi0)(a0)
31+
; RV64-NEXT: call __emutls_get_address@plt
32+
; RV64-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
33+
; RV64-NEXT: addi sp, sp, 16
34+
; RV64-NEXT: ret
35+
entry:
36+
ret ptr @external_x
37+
}
38+
39+
define ptr @get_y() nounwind {
40+
; RV32-LABEL: get_y:
41+
; RV32: # %bb.0: # %entry
42+
; RV32-NEXT: addi sp, sp, -16
43+
; RV32-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
44+
; RV32-NEXT: .Lpcrel_hi1:
45+
; RV32-NEXT: auipc a0, %got_pcrel_hi(__emutls_v.y)
46+
; RV32-NEXT: lw a0, %pcrel_lo(.Lpcrel_hi1)(a0)
47+
; RV32-NEXT: call __emutls_get_address@plt
48+
; RV32-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
49+
; RV32-NEXT: addi sp, sp, 16
50+
; RV32-NEXT: ret
51+
;
52+
; RV64-LABEL: get_y:
53+
; RV64: # %bb.0: # %entry
54+
; RV64-NEXT: addi sp, sp, -16
55+
; RV64-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
56+
; RV64-NEXT: .Lpcrel_hi1:
57+
; RV64-NEXT: auipc a0, %got_pcrel_hi(__emutls_v.y)
58+
; RV64-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi1)(a0)
59+
; RV64-NEXT: call __emutls_get_address@plt
60+
; RV64-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
61+
; RV64-NEXT: addi sp, sp, 16
62+
; RV64-NEXT: ret
63+
entry:
64+
ret ptr @y
65+
}
66+
67+
define ptr @get_internal_z() nounwind {
68+
; RV32-LABEL: get_internal_z:
69+
; RV32: # %bb.0: # %entry
70+
; RV32-NEXT: addi sp, sp, -16
71+
; RV32-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
72+
; RV32-NEXT: .Lpcrel_hi2:
73+
; RV32-NEXT: auipc a0, %pcrel_hi(__emutls_v.internal_z)
74+
; RV32-NEXT: addi a0, a0, %pcrel_lo(.Lpcrel_hi2)
75+
; RV32-NEXT: call __emutls_get_address@plt
76+
; RV32-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
77+
; RV32-NEXT: addi sp, sp, 16
78+
; RV32-NEXT: ret
79+
;
80+
; RV64-LABEL: get_internal_z:
81+
; RV64: # %bb.0: # %entry
82+
; RV64-NEXT: addi sp, sp, -16
83+
; RV64-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
84+
; RV64-NEXT: .Lpcrel_hi2:
85+
; RV64-NEXT: auipc a0, %pcrel_hi(__emutls_v.internal_z)
86+
; RV64-NEXT: addi a0, a0, %pcrel_lo(.Lpcrel_hi2)
87+
; RV64-NEXT: call __emutls_get_address@plt
88+
; RV64-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
89+
; RV64-NEXT: addi sp, sp, 16
90+
; RV64-NEXT: ret
91+
entry:
92+
ret ptr @internal_z
93+
}
94+
95+
; UTC_ARGS: --disable
96+
97+
; RV32: .data
98+
; RV32: .globl __emutls_v.y
99+
; RV32: .p2align 2
100+
; RV32-LABEL: __emutls_v.y:
101+
; RV32-NEXT: .word 1
102+
; RV32-NEXT: .word 2
103+
; RV32-NEXT: .word 0
104+
; RV32-NEXT: .word __emutls_t.y
105+
; RV32: .section .rodata,
106+
; RV32-LABEL: __emutls_t.y:
107+
; RV32-NEXT: .byte 7
108+
; RV32: .data
109+
; RV32: .p2align 2
110+
; RV32-LABEL: __emutls_v.internal_z:
111+
; RV32-NEXT: .word 8
112+
; RV32-NEXT: .word 16
113+
; RV32-NEXT: .word 0
114+
; RV32-NEXT: .word __emutls_t.internal_z
115+
; RV32: .section .rodata,
116+
; RV32-LABEL: __emutls_t.internal_z:
117+
; RV32-NEXT: .quad 9
118+
119+
; RV64: .data
120+
; RV64: .globl __emutls_v.y
121+
; RV64: .p2align 3
122+
; RV64-LABEL: __emutls_v.y:
123+
; RV64-NEXT: .quad 1
124+
; RV64-NEXT: .quad 2
125+
; RV64-NEXT: .quad 0
126+
; RV64-NEXT: .quad __emutls_t.y
127+
; RV64: .section .rodata,
128+
; RV64-LABEL: __emutls_t.y:
129+
; RV64-NEXT: .byte 7
130+
; RV64: .data
131+
; RV64: .p2align 3
132+
; RV64-LABEL: __emutls_v.internal_z:
133+
; RV64-NEXT: .quad 8
134+
; RV64-NEXT: .quad 16
135+
; RV64-NEXT: .quad 0
136+
; RV64-NEXT: .quad __emutls_t.internal_z
137+
; RV64: .section .rodata,
138+
; RV64-LABEL: __emutls_t.internal_z:
139+
; RV64-NEXT: .quad 9

0 commit comments

Comments
 (0)