]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/CodeGen/X86/tls.ll
Vendor import of llvm trunk r291274:
[FreeBSD/FreeBSD.git] / test / CodeGen / X86 / tls.ll
1 ; RUN: llc < %s -march=x86 -mtriple=i386-linux-gnu | FileCheck -check-prefix=X32_LINUX %s
2 ; RUN: llc < %s -march=x86-64 -mtriple=x86_64-linux-gnu | FileCheck -check-prefix=X64_LINUX %s
3 ; RUN: llc < %s -march=x86 -mtriple=x86-pc-win32 | FileCheck -check-prefix=X32_WIN %s
4 ; RUN: llc < %s -march=x86-64 -mtriple=x86_64-pc-win32 | FileCheck -check-prefix=X64_WIN %s
5 ; RUN: llc < %s -march=x86 -mtriple=x86-pc-windows-gnu | FileCheck -check-prefix=MINGW32 %s
6 ; RUN: llc < %s -march=x86-64 -mtriple=x86_64-pc-windows-gnu | FileCheck -check-prefix=X64_WIN %s
7
8 @i1 = thread_local global i32 15
9 @i2 = external thread_local global i32
10 @i3 = internal thread_local global i32 15
11 @i4 = hidden thread_local global i32 15
12 @i5 = external hidden thread_local global i32
13 @i6 = external protected thread_local global i32
14 @s1 = thread_local global i16 15
15 @b1 = thread_local global i8 0
16 @b2 = thread_local(localexec) global i8 0
17
18 define i32 @f1() {
19 ; X32_LINUX-LABEL: f1:
20 ; X32_LINUX:      movl %gs:i1@NTPOFF, %eax
21 ; X32_LINUX-NEXT: ret
22 ; X64_LINUX-LABEL: f1:
23 ; X64_LINUX:      movl %fs:i1@TPOFF, %eax
24 ; X64_LINUX-NEXT: ret
25 ; X32_WIN-LABEL: f1:
26 ; X32_WIN:      movl __tls_index, %eax
27 ; X32_WIN-NEXT: movl %fs:__tls_array, %ecx
28 ; X32_WIN-NEXT: movl (%ecx,%eax,4), %eax
29 ; X32_WIN-NEXT: movl _i1@SECREL32(%eax), %eax
30 ; X32_WIN-NEXT: ret
31 ; X64_WIN-LABEL: f1:
32 ; X64_WIN:      movl _tls_index(%rip), %eax
33 ; X64_WIN-NEXT: movq %gs:88, %rcx
34 ; X64_WIN-NEXT: movq (%rcx,%rax,8), %rax
35 ; X64_WIN-NEXT: movl i1@SECREL32(%rax), %eax
36 ; X64_WIN-NEXT: ret
37 ; MINGW32-LABEL: _f1:
38 ; MINGW32: movl __tls_index, %eax
39 ; MINGW32-NEXT: movl %fs:44, %ecx
40 ; MINGW32-NEXT: movl (%ecx,%eax,4), %eax
41 ; MINGW32-NEXT: movl _i1@SECREL32(%eax), %eax
42 ; MINGW32-NEXT: retl
43
44 entry:
45         %tmp1 = load i32, i32* @i1
46         ret i32 %tmp1
47 }
48
49 define i32* @f2() {
50 ; X32_LINUX-LABEL: f2:
51 ; X32_LINUX:      movl %gs:0, %eax
52 ; X32_LINUX-NEXT: leal i1@NTPOFF(%eax), %eax
53 ; X32_LINUX-NEXT: ret
54 ; X64_LINUX-LABEL: f2:
55 ; X64_LINUX:      movq %fs:0, %rax
56 ; X64_LINUX-NEXT: leaq i1@TPOFF(%rax), %rax
57 ; X64_LINUX-NEXT: ret
58 ; X32_WIN-LABEL: f2:
59 ; X32_WIN:      movl __tls_index, %eax
60 ; X32_WIN-NEXT: movl %fs:__tls_array, %ecx
61 ; X32_WIN-NEXT: movl (%ecx,%eax,4), %eax
62 ; X32_WIN-NEXT: leal _i1@SECREL32(%eax), %eax
63 ; X32_WIN-NEXT: ret
64 ; X64_WIN-LABEL: f2:
65 ; X64_WIN:      movl _tls_index(%rip), %eax
66 ; X64_WIN-NEXT: movq %gs:88, %rcx
67 ; X64_WIN-NEXT: movq (%rcx,%rax,8), %rax
68 ; X64_WIN-NEXT: leaq i1@SECREL32(%rax), %rax
69 ; X64_WIN-NEXT: ret
70 ; MINGW32-LABEL: _f2:
71 ; MINGW32: movl __tls_index, %eax
72 ; MINGW32-NEXT: movl %fs:44, %ecx
73 ; MINGW32-NEXT: movl (%ecx,%eax,4), %eax
74 ; MINGW32-NEXT: leal _i1@SECREL32(%eax), %eax
75 ; MINGW32-NEXT: retl
76
77 entry:
78         ret i32* @i1
79 }
80
81 define i32 @f3() nounwind {
82 ; X32_LINUX-LABEL: f3:
83 ; X32_LINUX:      movl i2@INDNTPOFF, %eax
84 ; X32_LINUX-NEXT: movl %gs:(%eax), %eax
85 ; X32_LINUX-NEXT: ret
86 ; X64_LINUX-LABEL: f3:
87 ; X64_LINUX:      movq i2@GOTTPOFF(%rip), %rax
88 ; X64_LINUX-NEXT: movl %fs:(%rax), %eax
89 ; X64_LINUX-NEXT: ret
90 ; X32_WIN-LABEL: f3:
91 ; X32_WIN:      movl __tls_index, %eax
92 ; X32_WIN-NEXT: movl %fs:__tls_array, %ecx
93 ; X32_WIN-NEXT: movl (%ecx,%eax,4), %eax
94 ; X32_WIN-NEXT: movl _i2@SECREL32(%eax), %eax
95 ; X32_WIN-NEXT: ret
96 ; X64_WIN-LABEL: f3:
97 ; X64_WIN:      movl _tls_index(%rip), %eax
98 ; X64_WIN-NEXT: movq %gs:88, %rcx
99 ; X64_WIN-NEXT: movq (%rcx,%rax,8), %rax
100 ; X64_WIN-NEXT: movl i2@SECREL32(%rax), %eax
101 ; X64_WIN-NEXT: ret
102 ; MINGW32-LABEL: _f3:
103 ; MINGW32: movl __tls_index, %eax
104 ; MINGW32-NEXT: movl %fs:44, %ecx
105 ; MINGW32-NEXT: movl (%ecx,%eax,4), %eax
106 ; MINGW32-NEXT: movl _i2@SECREL32(%eax), %eax
107 ; MINGW32-NEXT: retl
108
109 entry:
110         %tmp1 = load i32, i32* @i2
111         ret i32 %tmp1
112 }
113
114 define i32* @f4() {
115 ; X32_LINUX-LABEL: f4:
116 ; X32_LINUX:      movl %gs:0, %eax
117 ; X32_LINUX-NEXT: addl i2@INDNTPOFF, %eax
118 ; X32_LINUX-NEXT: ret
119 ; X64_LINUX-LABEL: f4:
120 ; X64_LINUX:      movq %fs:0, %rax
121 ; X64_LINUX-NEXT: addq i2@GOTTPOFF(%rip), %rax
122 ; X64_LINUX-NEXT: ret
123 ; X32_WIN-LABEL: f4:
124 ; X32_WIN:      movl __tls_index, %eax
125 ; X32_WIN-NEXT: movl %fs:__tls_array, %ecx
126 ; X32_WIN-NEXT: movl (%ecx,%eax,4), %eax
127 ; X32_WIN-NEXT: leal _i2@SECREL32(%eax), %eax
128 ; X32_WIN-NEXT: ret
129 ; X64_WIN-LABEL: f4:
130 ; X64_WIN:      movl _tls_index(%rip), %eax
131 ; X64_WIN-NEXT: movq %gs:88, %rcx
132 ; X64_WIN-NEXT: movq (%rcx,%rax,8), %rax
133 ; X64_WIN-NEXT: leaq i2@SECREL32(%rax), %rax
134 ; X64_WIN-NEXT: ret
135 ; MINGW32-LABEL: _f4:
136 ; MINGW32: movl __tls_index, %eax
137 ; MINGW32-NEXT: movl %fs:44, %ecx
138 ; MINGW32-NEXT: movl (%ecx,%eax,4), %eax
139 ; MINGW32-NEXT: leal _i2@SECREL32(%eax), %eax
140 ; MINGW32-NEXT: retl
141
142 entry:
143         ret i32* @i2
144 }
145
146 define i32 @f5() nounwind {
147 ; X32_LINUX-LABEL: f5:
148 ; X32_LINUX:      movl %gs:i3@NTPOFF, %eax
149 ; X32_LINUX-NEXT: ret
150 ; X64_LINUX-LABEL: f5:
151 ; X64_LINUX:      movl %fs:i3@TPOFF, %eax
152 ; X64_LINUX-NEXT: ret
153 ; X32_WIN-LABEL: f5:
154 ; X32_WIN:      movl __tls_index, %eax
155 ; X32_WIN-NEXT: movl %fs:__tls_array, %ecx
156 ; X32_WIN-NEXT: movl (%ecx,%eax,4), %eax
157 ; X32_WIN-NEXT: movl _i3@SECREL32(%eax), %eax
158 ; X32_WIN-NEXT: ret
159 ; X64_WIN-LABEL: f5:
160 ; X64_WIN:      movl _tls_index(%rip), %eax
161 ; X64_WIN-NEXT: movq %gs:88, %rcx
162 ; X64_WIN-NEXT: movq (%rcx,%rax,8), %rax
163 ; X64_WIN-NEXT: movl i3@SECREL32(%rax), %eax
164 ; X64_WIN-NEXT: ret
165 ; MINGW32-LABEL: _f5:
166 ; MINGW32: movl __tls_index, %eax
167 ; MINGW32-NEXT: movl %fs:44, %ecx
168 ; MINGW32-NEXT: movl (%ecx,%eax,4), %eax
169 ; MINGW32-NEXT: movl _i3@SECREL32(%eax), %eax
170 ; MINGW32-NEXT: retl
171
172 entry:
173         %tmp1 = load i32, i32* @i3
174         ret i32 %tmp1
175 }
176
177 define i32* @f6() {
178 ; X32_LINUX-LABEL: f6:
179 ; X32_LINUX:      movl %gs:0, %eax
180 ; X32_LINUX-NEXT: leal i3@NTPOFF(%eax), %eax
181 ; X32_LINUX-NEXT: ret
182 ; X64_LINUX-LABEL: f6:
183 ; X64_LINUX:      movq %fs:0, %rax
184 ; X64_LINUX-NEXT: leaq i3@TPOFF(%rax), %rax
185 ; X64_LINUX-NEXT: ret
186 ; X32_WIN-LABEL: f6:
187 ; X32_WIN:      movl __tls_index, %eax
188 ; X32_WIN-NEXT: movl %fs:__tls_array, %ecx
189 ; X32_WIN-NEXT: movl (%ecx,%eax,4), %eax
190 ; X32_WIN-NEXT: leal _i3@SECREL32(%eax), %eax
191 ; X32_WIN-NEXT: ret
192 ; X64_WIN-LABEL: f6:
193 ; X64_WIN:      movl _tls_index(%rip), %eax
194 ; X64_WIN-NEXT: movq %gs:88, %rcx
195 ; X64_WIN-NEXT: movq (%rcx,%rax,8), %rax
196 ; X64_WIN-NEXT: leaq i3@SECREL32(%rax), %rax
197 ; X64_WIN-NEXT: ret
198 ; MINGW32-LABEL: _f6:
199 ; MINGW32: movl __tls_index, %eax
200 ; MINGW32-NEXT: movl %fs:44, %ecx
201 ; MINGW32-NEXT: movl (%ecx,%eax,4), %eax
202 ; MINGW32-NEXT: leal _i3@SECREL32(%eax), %eax
203 ; MINGW32-NEXT: retl
204
205 entry:
206         ret i32* @i3
207 }
208
209 define i32 @f7() {
210 ; X32_LINUX-LABEL: f7:
211 ; X32_LINUX:      movl %gs:i4@NTPOFF, %eax
212 ; X32_LINUX-NEXT: ret
213 ; X64_LINUX-LABEL: f7:
214 ; X64_LINUX:      movl %fs:i4@TPOFF, %eax
215 ; X64_LINUX-NEXT: ret
216 ; MINGW32-LABEL: _f7:
217 ; MINGW32: movl __tls_index, %eax
218 ; MINGW32-NEXT: movl %fs:44, %ecx
219 ; MINGW32-NEXT: movl (%ecx,%eax,4), %eax
220 ; MINGW32-NEXT: movl _i4@SECREL32(%eax), %eax
221 ; MINGW32-NEXT: retl
222
223 entry:
224         %tmp1 = load i32, i32* @i4
225         ret i32 %tmp1
226 }
227
228 define i32* @f8() {
229 ; X32_LINUX-LABEL: f8:
230 ; X32_LINUX:      movl %gs:0, %eax
231 ; X32_LINUX-NEXT: leal i4@NTPOFF(%eax), %eax
232 ; X32_LINUX-NEXT: ret
233 ; X64_LINUX-LABEL: f8:
234 ; X64_LINUX:      movq %fs:0, %rax
235 ; X64_LINUX-NEXT: leaq i4@TPOFF(%rax), %rax
236 ; X64_LINUX-NEXT: ret
237 ; MINGW32-LABEL: _f8:
238 ; MINGW32: movl __tls_index, %eax
239 ; MINGW32-NEXT: movl %fs:44, %ecx
240 ; MINGW32-NEXT: movl (%ecx,%eax,4), %eax
241 ; MINGW32-NEXT: leal _i4@SECREL32(%eax), %eax
242 ; MINGW32-NEXT: retl
243
244 entry:
245         ret i32* @i4
246 }
247
248 define i32 @f9() {
249 ; X32_LINUX-LABEL: f9:
250 ; X32_LINUX:      movl %gs:i5@NTPOFF, %eax
251 ; X32_LINUX-NEXT: ret
252 ; X64_LINUX-LABEL: f9:
253 ; X64_LINUX:      movl %fs:i5@TPOFF, %eax
254 ; X64_LINUX-NEXT: ret
255 ; MINGW32-LABEL: _f9:
256 ; MINGW32: movl __tls_index, %eax
257 ; MINGW32-NEXT: movl %fs:44, %ecx
258 ; MINGW32-NEXT: movl (%ecx,%eax,4), %eax
259 ; MINGW32-NEXT: movl _i5@SECREL32(%eax), %eax
260 ; MINGW32-NEXT: retl
261
262 entry:
263         %tmp1 = load i32, i32* @i5
264         ret i32 %tmp1
265 }
266
267 define i32* @f10() {
268 ; X32_LINUX-LABEL: f10:
269 ; X32_LINUX:      movl %gs:0, %eax
270 ; X32_LINUX-NEXT: leal i5@NTPOFF(%eax), %eax
271 ; X32_LINUX-NEXT: ret
272 ; X64_LINUX-LABEL: f10:
273 ; X64_LINUX:      movq %fs:0, %rax
274 ; X64_LINUX-NEXT: leaq i5@TPOFF(%rax), %rax
275 ; X64_LINUX-NEXT: ret
276 ; MINGW32-LABEL: _f10:
277 ; MINGW32: movl __tls_index, %eax
278 ; MINGW32-NEXT: movl %fs:44, %ecx
279 ; MINGW32-NEXT: movl (%ecx,%eax,4), %eax
280 ; MINGW32-NEXT: leal _i5@SECREL32(%eax), %eax
281 ; MINGW32-NEXT: retl
282
283 entry:
284         ret i32* @i5
285 }
286
287 define i16 @f11() {
288 ; X32_LINUX-LABEL: f11:
289 ; X32_LINUX:      movzwl %gs:s1@NTPOFF, %eax
290 ; X32_LINUX:      ret
291 ; X64_LINUX-LABEL: f11:
292 ; X64_LINUX:      movzwl %fs:s1@TPOFF, %eax
293 ; X64_LINUX:      ret
294 ; X32_WIN-LABEL: f11:
295 ; X32_WIN:      movl __tls_index, %eax
296 ; X32_WIN-NEXT: movl %fs:__tls_array, %ecx
297 ; X32_WIN-NEXT: movl (%ecx,%eax,4), %eax
298 ; X32_WIN-NEXT: movzwl _s1@SECREL32(%eax), %eax
299 ; X32_WIN:      ret
300 ; X64_WIN-LABEL: f11:
301 ; X64_WIN:      movl _tls_index(%rip), %eax
302 ; X64_WIN-NEXT: movq %gs:88, %rcx
303 ; X64_WIN-NEXT: movq (%rcx,%rax,8), %rax
304 ; X64_WIN-NEXT: movzwl s1@SECREL32(%rax), %eax
305 ; X64_WIN:      ret
306 ; MINGW32-LABEL: _f11:
307 ; MINGW32: movl __tls_index, %eax
308 ; MINGW32-NEXT: movl %fs:44, %ecx
309 ; MINGW32-NEXT: movl (%ecx,%eax,4), %eax
310 ; MINGW32-NEXT: movzwl  _s1@SECREL32(%eax), %eax
311 ; MINGW32: retl
312
313 entry:
314         %tmp1 = load i16, i16* @s1
315         ret i16 %tmp1
316 }
317
318 define i32 @f12() {
319 ; X32_LINUX-LABEL: f12:
320 ; X32_LINUX:      movswl %gs:s1@NTPOFF, %eax
321 ; X32_LINUX-NEXT: ret
322 ; X64_LINUX-LABEL: f12:
323 ; X64_LINUX:      movswl %fs:s1@TPOFF, %eax
324 ; X64_LINUX-NEXT: ret
325 ; X32_WIN-LABEL: f12:
326 ; X32_WIN:      movl __tls_index, %eax
327 ; X32_WIN-NEXT: movl %fs:__tls_array, %ecx
328 ; X32_WIN-NEXT: movl (%ecx,%eax,4), %eax
329 ; X32_WIN-NEXT: movswl _s1@SECREL32(%eax), %eax
330 ; X32_WIN-NEXT: ret
331 ; X64_WIN-LABEL: f12:
332 ; X64_WIN:      movl _tls_index(%rip), %eax
333 ; X64_WIN-NEXT: movq %gs:88, %rcx
334 ; X64_WIN-NEXT: movq (%rcx,%rax,8), %rax
335 ; X64_WIN-NEXT: movswl s1@SECREL32(%rax), %eax
336 ; X64_WIN-NEXT: ret
337 ; MINGW32-LABEL: _f12:
338 ; MINGW32: movl __tls_index, %eax
339 ; MINGW32-NEXT: movl %fs:44, %ecx
340 ; MINGW32-NEXT: movl (%ecx,%eax,4), %eax
341 ; MINGW32-NEXT: movswl _s1@SECREL32(%eax), %eax
342 ; MINGW32-NEXT: retl
343
344
345 entry:
346         %tmp1 = load i16, i16* @s1
347   %tmp2 = sext i16 %tmp1 to i32
348         ret i32 %tmp2
349 }
350
351 define i8 @f13() {
352 ; X32_LINUX-LABEL: f13:
353 ; X32_LINUX:      movb %gs:b1@NTPOFF, %al
354 ; X32_LINUX-NEXT: ret
355 ; X64_LINUX-LABEL: f13:
356 ; X64_LINUX:      movb %fs:b1@TPOFF, %al
357 ; X64_LINUX-NEXT: ret
358 ; X32_WIN-LABEL: f13:
359 ; X32_WIN:      movl __tls_index, %eax
360 ; X32_WIN-NEXT: movl %fs:__tls_array, %ecx
361 ; X32_WIN-NEXT: movl (%ecx,%eax,4), %eax
362 ; X32_WIN-NEXT: movb _b1@SECREL32(%eax), %al
363 ; X32_WIN-NEXT: ret
364 ; X64_WIN-LABEL: f13:
365 ; X64_WIN:      movl _tls_index(%rip), %eax
366 ; X64_WIN-NEXT: movq %gs:88, %rcx
367 ; X64_WIN-NEXT: movq (%rcx,%rax,8), %rax
368 ; X64_WIN-NEXT: movb b1@SECREL32(%rax), %al
369 ; X64_WIN-NEXT: ret
370 ; MINGW32-LABEL: _f13:
371 ; MINGW32: movl __tls_index, %eax
372 ; MINGW32-NEXT: movl %fs:44, %ecx
373 ; MINGW32-NEXT: movl (%ecx,%eax,4), %eax
374 ; MINGW32-NEXT: movb _b1@SECREL32(%eax), %al
375 ; MINGW32-NEXT: retl
376
377 entry:
378         %tmp1 = load i8, i8* @b1
379         ret i8 %tmp1
380 }
381
382 define i32 @f14() {
383 ; X32_LINUX-LABEL: f14:
384 ; X32_LINUX:      movsbl %gs:b1@NTPOFF, %eax
385 ; X32_LINUX-NEXT: ret
386 ; X64_LINUX-LABEL: f14:
387 ; X64_LINUX:      movsbl %fs:b1@TPOFF, %eax
388 ; X64_LINUX-NEXT: ret
389 ; X32_WIN-LABEL: f14:
390 ; X32_WIN:      movl __tls_index, %eax
391 ; X32_WIN-NEXT: movl %fs:__tls_array, %ecx
392 ; X32_WIN-NEXT: movl (%ecx,%eax,4), %eax
393 ; X32_WIN-NEXT: movsbl _b1@SECREL32(%eax), %eax
394 ; X32_WIN-NEXT: ret
395 ; X64_WIN-LABEL: f14:
396 ; X64_WIN:      movl _tls_index(%rip), %eax
397 ; X64_WIN-NEXT: movq %gs:88, %rcx
398 ; X64_WIN-NEXT: movq (%rcx,%rax,8), %rax
399 ; X64_WIN-NEXT: movsbl b1@SECREL32(%rax), %eax
400 ; X64_WIN-NEXT: ret
401 ; MINGW32-LABEL: _f14:
402 ; MINGW32: movl __tls_index, %eax
403 ; MINGW32-NEXT: movl %fs:44, %ecx
404 ; MINGW32-NEXT: movl (%ecx,%eax,4), %eax
405 ; MINGW32-NEXT: movsbl  _b1@SECREL32(%eax), %eax
406 ; MINGW32-NEXT: retl
407
408 entry:
409         %tmp1 = load i8, i8* @b1
410   %tmp2 = sext i8 %tmp1 to i32
411         ret i32 %tmp2
412 }
413
414 define i8* @f15() {
415 ; X32_LINUX-LABEL: f15:
416 ; X32_LINUX:      movl %gs:0, %eax
417 ; X32_LINUX-NEXT: leal b2@NTPOFF(%eax), %eax
418 ; X32_LINUX-NEXT: ret
419 ; X64_LINUX-LABEL: f15:
420 ; X64_LINUX:      movq %fs:0, %rax
421 ; X64_LINUX-NEXT: leaq b2@TPOFF(%rax), %rax
422 ; X64_LINUX-NEXT: ret
423 ; X32_WIN-LABEL: f15:
424 ; X32_WIN:      movl %fs:__tls_array, %eax
425 ; X32_WIN-NEXT: movl (%eax), %eax
426 ; X32_WIN-NEXT: leal _b2@SECREL32(%eax), %eax
427 ; X32_WIN-NEXT: ret
428 ; X64_WIN-LABEL: f15:
429 ; X64_WIN:      movq %gs:88, %rax
430 ; X64_WIN-NEXT: movq (%rax), %rax
431 ; X64_WIN-NEXT: leaq b2@SECREL32(%rax), %rax
432 ; X64_WIN-NEXT: ret
433 ; MINGW32-LABEL: f15:
434 ; MINGW32:      movl %fs:44, %eax
435 ; MINGW32-NEXT: movl (%eax), %eax
436 ; MINGW32-NEXT: leal _b2@SECREL32(%eax), %eax
437 ; MINGW32-NEXT: ret
438 entry:
439         ret i8* @b2
440 }
441
442
443 define i32* @f16() {
444 ; X32_LINUX-LABEL: f16:
445 ; X32_LINUX:       movl %gs:0, %eax
446 ; X32_LINUX-NEXT:  leal i6@NTPOFF(%eax), %eax
447 ; X32_LINUX-NEXT:  ret
448
449 ; X64_LINUX-LABEL: f16:
450 ; X64_LINUX:       movq %fs:0, %rax
451 ; X64_LINUX-NEXT:  leaq i6@TPOFF(%rax), %rax
452 ; X64_LINUX-NEXT:  ret
453
454   ret i32* @i6
455 }