xref: /llvm-project/llvm/test/CodeGen/AArch64/emutls.ll (revision 5ddce70ef0e5a641d7fea95e31fc5e2439cb98cb)
1; RUN: llc -emulated-tls -mtriple=aarch64-linux-android \
2; RUN:     -relocation-model=pic -frame-pointer=all < %s | FileCheck -check-prefix=ARM64 %s
3; RUN: llc -mtriple=aarch64-linux-android \
4; RUN:     -relocation-model=pic -frame-pointer=all < %s | FileCheck -check-prefix=ARM64 %s
5
6; Copied from X86/emutls.ll
7
8; Use my_emutls_get_address like __emutls_get_address.
9@my_emutls_v_xyz = external global ptr, align 4
10declare ptr @my_emutls_get_address(ptr)
11
12define i32 @my_get_xyz() uwtable {
13; ARM64-LABEL: my_get_xyz:
14; ARM64:        adrp x0, :got:my_emutls_v_xyz
15; ARM64-NEXT:   ldr x0, [x0, :got_lo12:my_emutls_v_xyz]
16; ARM64-NEXT:   bl my_emutls_get_address
17; ARM64-NEXT:   ldr  w0, [x0]
18; ARM64-NEXT: 	.cfi_def_cfa wsp, 16
19; ARM64-NEXT:   ldp x29, x30, [sp]
20
21entry:
22  %call = call ptr @my_emutls_get_address(ptr @my_emutls_v_xyz)
23  %0 = load i32, ptr %call, align 4
24  ret i32 %0
25}
26
27@i1 = thread_local global i32 15
28@i2 = external thread_local global i32
29@i3 = internal thread_local global i32 15
30@i4 = hidden thread_local global i32 15
31@i5 = external hidden thread_local global i32
32@s1 = thread_local global i16 15
33@b1 = thread_local global i8 0
34
35define i32 @f1() uwtable {
36; ARM64-LABEL: f1:
37; ARM64:        adrp x0, :got:__emutls_v.i1
38; ARM64-NEXT:   ldr x0, [x0, :got_lo12:__emutls_v.i1]
39; ARM64-NEXT:   bl __emutls_get_address
40; ARM64-NEXT:   ldr  w0, [x0]
41; ARM64-NEXT: 	.cfi_def_cfa wsp, 16
42; ARM64-NEXT:   ldp x29, x30, [sp]
43
44entry:
45  %tmp1 = load i32, ptr @i1
46  ret i32 %tmp1
47}
48
49define ptr @f2() uwtable {
50; ARM64-LABEL: f2:
51; ARM64:        adrp x0, :got:__emutls_v.i1
52; ARM64-NEXT:   ldr x0, [x0, :got_lo12:__emutls_v.i1]
53; ARM64-NEXT:   bl __emutls_get_address
54; ARM64-NEXT: 	.cfi_def_cfa wsp, 16
55; ARM64-NEXT:   ldp x29, x30, [sp]
56
57entry:
58  ret ptr @i1
59}
60
61define i32 @f5() nounwind {
62; ARM64-LABEL: f5:
63; ARM64:        adrp x0, __emutls_v.i3
64; ARM64:        add x0, x0, :lo12:__emutls_v.i3
65; ARM64:        bl __emutls_get_address
66; ARM64-NEXT:   ldr w0, [x0]
67
68entry:
69  %tmp1 = load i32, ptr @i3
70  ret i32 %tmp1
71}
72
73define ptr @f6() uwtable {
74; ARM64-LABEL: f6:
75; ARM64:        adrp x0, __emutls_v.i3
76; ARM64:        add x0, x0, :lo12:__emutls_v.i3
77; ARM64-NEXT:   bl __emutls_get_address
78; ARM64-NEXT: 	.cfi_def_cfa wsp, 16
79; ARM64-NEXT:   ldp x29, x30, [sp]
80
81entry:
82  ret ptr @i3
83}
84
85; Simple test of comdat __thread variables.
86; template <class T> struct A { static __thread T x; };
87; template <class T> T __thread A<T>::x;
88; int getIntX() { return A<int>::x++; }
89; float getFloatX() { return A<float>::x++; }
90
91$_ZN1AIiE1xE = comdat any
92$_ZN1AIfE1xE = comdat any
93@_ZN1AIiE1xE = linkonce_odr thread_local global i32 0, comdat, align 4
94@_ZN1AIfE1xE = linkonce_odr thread_local global float 0.000000e+00, comdat, align 4
95
96define i32 @_Z7getIntXv() {
97; ARM64-LABEL: _Z7getIntXv:
98; ARM64:        adrp x0, :got:__emutls_v._ZN1AIiE1xE
99; ARM64:        ldr x0, [x0, :got_lo12:__emutls_v._ZN1AIiE1xE]
100; ARM64-NEXT:   bl __emutls_get_address
101; ARM64:        ldr {{.*}}, [x0]
102; ARM64:        add
103; ARM64:        str {{.*}}, [x8]
104
105entry:
106  %0 = load i32, ptr @_ZN1AIiE1xE, align 4
107  %inc = add nsw i32 %0, 1
108  store i32 %inc, ptr @_ZN1AIiE1xE, align 4
109  ret i32 %0
110}
111
112define float @_Z9getFloatXv() {
113; ARM64-LABEL: _Z9getFloatXv:
114; ARM64:        adrp x0, :got:__emutls_v._ZN1AIfE1xE
115; ARM64:        ldr x0, [x0, :got_lo12:__emutls_v._ZN1AIfE1xE]
116; ARM64-NEXT:   bl __emutls_get_address
117; ARM64:        ldr {{.*}}, [x0]
118; ARM64:        fadd s{{.*}}, s
119; ARM64:        str s{{.*}}, [x0]
120
121entry:
122  %0 = load float, ptr @_ZN1AIfE1xE, align 4
123  %inc = fadd float %0, 1.000000e+00
124  store float %inc, ptr @_ZN1AIfE1xE, align 4
125  ret float %0
126}
127
128
129;;;;;;;;;;;;;; 64-bit __emutls_v. and __emutls_t.
130
131; ARM64:      .data{{$}}
132; ARM64:      .globl __emutls_v.i1
133; ARM64-LABEL: __emutls_v.i1:
134; ARM64-NEXT: .xword 4
135; ARM64-NEXT: .xword 4
136; ARM64-NEXT: .xword 0
137; ARM64-NEXT: .xword __emutls_t.i1
138
139; ARM64:      .section .rodata,
140; ARM64-LABEL: __emutls_t.i1:
141; ARM64-NEXT: .word 15
142
143; ARM64-NOT:   __emutls_v.i2
144
145; ARM64:      .data{{$}}
146; ARM64-NOT:  .globl
147; ARM64-LABEL: __emutls_v.i3:
148; ARM64-NEXT: .xword 4
149; ARM64-NEXT: .xword 4
150; ARM64-NEXT: .xword 0
151; ARM64-NEXT: .xword __emutls_t.i3
152
153; ARM64:      .section .rodata,
154; ARM64-LABEL: __emutls_t.i3:
155; ARM64-NEXT: .word 15
156
157; ARM64:      .hidden __emutls_v.i4
158; ARM64:      .data{{$}}
159; ARM64:      .globl __emutls_v.i4
160; ARM64-LABEL: __emutls_v.i4:
161; ARM64-NEXT: .xword 4
162; ARM64-NEXT: .xword 4
163; ARM64-NEXT: .xword 0
164; ARM64-NEXT: .xword __emutls_t.i4
165
166; ARM64:      .section .rodata,
167; ARM64-LABEL: __emutls_t.i4:
168; ARM64-NEXT: .word 15
169
170; ARM64-NOT:   __emutls_v.i5:
171; ARM64:      .hidden __emutls_v.i5
172; ARM64-NOT:   __emutls_v.i5:
173
174; ARM64:      .data{{$}}
175; ARM64:      .globl __emutls_v.s1
176; ARM64-LABEL: __emutls_v.s1:
177; ARM64-NEXT: .xword 2
178; ARM64-NEXT: .xword 2
179; ARM64-NEXT: .xword 0
180; ARM64-NEXT: .xword __emutls_t.s1
181
182; ARM64:      .section .rodata,
183; ARM64-LABEL: __emutls_t.s1:
184; ARM64-NEXT: .hword 15
185
186; ARM64:      .data{{$}}
187; ARM64-LABEL: __emutls_v.b1:
188; ARM64-NEXT: .xword 1
189; ARM64-NEXT: .xword 1
190; ARM64-NEXT: .xword 0
191; ARM64-NEXT: .xword 0
192
193; ARM64-NOT:   __emutls_t.b1
194
195; ARM64:      .section .data.__emutls_v._ZN1AIiE1xE,{{.*}},__emutls_v._ZN1AIiE1xE,comdat
196; ARM64:      .weak __emutls_v._ZN1AIiE1xE
197; ARM64:      .p2align 3
198; ARM64-LABEL: __emutls_v._ZN1AIiE1xE:
199; ARM64-NEXT: .xword 4
200; ARM64-NEXT: .xword 4
201; ARM64-NEXT: .xword 0
202; ARM64-NEXT: .xword 0
203
204; ARM64:      .section .data.__emutls_v._ZN1AIfE1xE,{{.*}},__emutls_v._ZN1AIfE1xE,comdat
205; ARM64:      .weak __emutls_v._ZN1AIfE1xE
206; ARM64:      .p2align 3
207; ARM64-LABEL: __emutls_v._ZN1AIfE1xE:
208; ARM64-NEXT: .xword 4
209; ARM64-NEXT: .xword 4
210; ARM64-NEXT: .xword 0
211; ARM64-NEXT: .xword __emutls_t._ZN1AIfE1xE
212
213; ARM64:      .section .rodata.__emutls_t._ZN1AIfE1xE,{{.*}},__emutls_t._ZN1AIfE1xE,comdat
214; ARM64:      .weak __emutls_t._ZN1AIfE1xE
215; ARM64:      .p2align 2
216; ARM64-LABEL: __emutls_t._ZN1AIfE1xE:
217; ARM64-NEXT: .word 0
218; ARM64-NEXT: .size
219