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
6 @i1 = thread_local global i32 15
7 @i2 = external thread_local global i32
8 @i3 = internal thread_local global i32 15
9 @i4 = hidden thread_local global i32 15
10 @i5 = external hidden thread_local global i32
11 @s1 = thread_local global i16 15
12 @b1 = thread_local global i8 0
16 ; X32_LINUX: movl %gs:i1@NTPOFF, %eax
19 ; X64_LINUX: movl %fs:i1@TPOFF, %eax
22 ; X32_WIN: movl __tls_index, %eax
23 ; X32_WIN-NEXT: movl %fs:__tls_array, %ecx
24 ; X32_WIN-NEXT: movl (%ecx,%eax,4), %eax
25 ; X32_WIN-NEXT: movl _i1@SECREL(%eax), %eax
28 ; X64_WIN: movl _tls_index(%rip), %eax
29 ; X64_WIN-NEXT: movq %gs:88, %rcx
30 ; X64_WIN-NEXT: movq (%rcx,%rax,8), %rax
31 ; X64_WIN-NEXT: movabsq $i1@SECREL, %rcx
32 ; X64_WIN-NEXT: movl (%rax,%rcx), %eax
42 ; X32_LINUX: movl %gs:0, %eax
43 ; X32_LINUX-NEXT: leal i1@NTPOFF(%eax), %eax
46 ; X64_LINUX: movq %fs:0, %rax
47 ; X64_LINUX-NEXT: leaq i1@TPOFF(%rax), %rax
50 ; X32_WIN: movl __tls_index, %eax
51 ; X32_WIN-NEXT: movl %fs:__tls_array, %ecx
52 ; X32_WIN-NEXT: movl (%ecx,%eax,4), %eax
53 ; X32_WIN-NEXT: leal _i1@SECREL(%eax), %eax
56 ; X64_WIN: movl _tls_index(%rip), %eax
57 ; X64_WIN-NEXT: movq %gs:88, %rcx
58 ; X64_WIN-NEXT: movq (%rcx,%rax,8), %rax
59 ; X64_WIN-NEXT: addq $i1@SECREL, %rax
66 define i32 @f3() nounwind {
68 ; X32_LINUX: movl i2@INDNTPOFF, %eax
69 ; X32_LINUX-NEXT: movl %gs:(%eax), %eax
72 ; X64_LINUX: movq i2@GOTTPOFF(%rip), %rax
73 ; X64_LINUX-NEXT: movl %fs:(%rax), %eax
76 ; X32_WIN: movl __tls_index, %eax
77 ; X32_WIN-NEXT: movl %fs:__tls_array, %ecx
78 ; X32_WIN-NEXT: movl (%ecx,%eax,4), %eax
79 ; X32_WIN-NEXT: movl _i2@SECREL(%eax), %eax
82 ; X64_WIN: movl _tls_index(%rip), %eax
83 ; X64_WIN-NEXT: movq %gs:88, %rcx
84 ; X64_WIN-NEXT: movq (%rcx,%rax,8), %rax
85 ; X64_WIN-NEXT: movabsq $i2@SECREL, %rcx
86 ; X64_WIN-NEXT: movl (%rax,%rcx), %eax
96 ; X32_LINUX: movl %gs:0, %eax
97 ; X32_LINUX-NEXT: addl i2@INDNTPOFF, %eax
100 ; X64_LINUX: movq %fs:0, %rax
101 ; X64_LINUX-NEXT: addq i2@GOTTPOFF(%rip), %rax
102 ; X64_LINUX-NEXT: ret
104 ; X32_WIN: movl __tls_index, %eax
105 ; X32_WIN-NEXT: movl %fs:__tls_array, %ecx
106 ; X32_WIN-NEXT: movl (%ecx,%eax,4), %eax
107 ; X32_WIN-NEXT: leal _i2@SECREL(%eax), %eax
110 ; X64_WIN: movl _tls_index(%rip), %eax
111 ; X64_WIN-NEXT: movq %gs:88, %rcx
112 ; X64_WIN-NEXT: movq (%rcx,%rax,8), %rax
113 ; X64_WIN-NEXT: addq $i2@SECREL, %rax
120 define i32 @f5() nounwind {
122 ; X32_LINUX: movl %gs:i3@NTPOFF, %eax
123 ; X32_LINUX-NEXT: ret
125 ; X64_LINUX: movl %fs:i3@TPOFF, %eax
126 ; X64_LINUX-NEXT: ret
128 ; X32_WIN: movl __tls_index, %eax
129 ; X32_WIN-NEXT: movl %fs:__tls_array, %ecx
130 ; X32_WIN-NEXT: movl (%ecx,%eax,4), %eax
131 ; X32_WIN-NEXT: movl _i3@SECREL(%eax), %eax
134 ; X64_WIN: movl _tls_index(%rip), %eax
135 ; X64_WIN-NEXT: movq %gs:88, %rcx
136 ; X64_WIN-NEXT: movq (%rcx,%rax,8), %rax
137 ; X64_WIN-NEXT: movabsq $i3@SECREL, %rcx
138 ; X64_WIN-NEXT: movl (%rax,%rcx), %eax
142 %tmp1 = load i32* @i3
148 ; X32_LINUX: movl %gs:0, %eax
149 ; X32_LINUX-NEXT: leal i3@NTPOFF(%eax), %eax
150 ; X32_LINUX-NEXT: ret
152 ; X64_LINUX: movq %fs:0, %rax
153 ; X64_LINUX-NEXT: leaq i3@TPOFF(%rax), %rax
154 ; X64_LINUX-NEXT: ret
156 ; X32_WIN: movl __tls_index, %eax
157 ; X32_WIN-NEXT: movl %fs:__tls_array, %ecx
158 ; X32_WIN-NEXT: movl (%ecx,%eax,4), %eax
159 ; X32_WIN-NEXT: leal _i3@SECREL(%eax), %eax
162 ; X64_WIN: movl _tls_index(%rip), %eax
163 ; X64_WIN-NEXT: movq %gs:88, %rcx
164 ; X64_WIN-NEXT: movq (%rcx,%rax,8), %rax
165 ; X64_WIN-NEXT: addq $i3@SECREL, %rax
174 ; X32_LINUX: movl %gs:i4@NTPOFF, %eax
175 ; X32_LINUX-NEXT: ret
177 ; X64_LINUX: movl %fs:i4@TPOFF, %eax
178 ; X64_LINUX-NEXT: ret
181 %tmp1 = load i32* @i4
187 ; X32_LINUX: movl %gs:0, %eax
188 ; X32_LINUX-NEXT: leal i4@NTPOFF(%eax), %eax
189 ; X32_LINUX-NEXT: ret
191 ; X64_LINUX: movq %fs:0, %rax
192 ; X64_LINUX-NEXT: leaq i4@TPOFF(%rax), %rax
193 ; X64_LINUX-NEXT: ret
201 ; X32_LINUX: movl %gs:i5@NTPOFF, %eax
202 ; X32_LINUX-NEXT: ret
204 ; X64_LINUX: movl %fs:i5@TPOFF, %eax
205 ; X64_LINUX-NEXT: ret
208 %tmp1 = load i32* @i5
214 ; X32_LINUX: movl %gs:0, %eax
215 ; X32_LINUX-NEXT: leal i5@NTPOFF(%eax), %eax
216 ; X32_LINUX-NEXT: ret
218 ; X64_LINUX: movq %fs:0, %rax
219 ; X64_LINUX-NEXT: leaq i5@TPOFF(%rax), %rax
220 ; X64_LINUX-NEXT: ret
228 ; X32_LINUX: movzwl %gs:s1@NTPOFF, %eax
229 ; Why is this kill line here, but no where else?
230 ; X32_LINUX-NEXT: # kill
231 ; X32_LINUX-NEXT: ret
233 ; X64_LINUX: movzwl %fs:s1@TPOFF, %eax
234 ; X64_LINUX-NEXT: # kill
235 ; X64_LINUX-NEXT: ret
237 ; X32_WIN: movl __tls_index, %eax
238 ; X32_WIN-NEXT: movl %fs:__tls_array, %ecx
239 ; X32_WIN-NEXT: movl (%ecx,%eax,4), %eax
240 ; X32_WIN-NEXT: movzwl _s1@SECREL(%eax), %eax
241 ; X32_WIN-NEXT: # kill
244 ; X64_WIN: movl _tls_index(%rip), %eax
245 ; X64_WIN-NEXT: movq %gs:88, %rcx
246 ; X64_WIN-NEXT: movq (%rcx,%rax,8), %rax
247 ; X64_WIN-NEXT: movabsq $s1@SECREL, %rcx
248 ; X64_WIN-NEXT: movzwl (%rax,%rcx), %eax
249 ; X64_WIN-NEXT: # kill
253 %tmp1 = load i16* @s1
259 ; X32_LINUX: movswl %gs:s1@NTPOFF, %eax
260 ; X32_LINUX-NEXT: ret
262 ; X64_LINUX: movswl %fs:s1@TPOFF, %eax
263 ; X64_LINUX-NEXT: ret
265 ; X32_WIN: movl __tls_index, %eax
266 ; X32_WIN-NEXT: movl %fs:__tls_array, %ecx
267 ; X32_WIN-NEXT: movl (%ecx,%eax,4), %eax
268 ; X32_WIN-NEXT: movswl _s1@SECREL(%eax), %eax
271 ; X64_WIN: movl _tls_index(%rip), %eax
272 ; X64_WIN-NEXT: movq %gs:88, %rcx
273 ; X64_WIN-NEXT: movq (%rcx,%rax,8), %rax
274 ; X64_WIN-NEXT: movabsq $s1@SECREL, %rcx
275 ; X64_WIN-NEXT: movswl (%rax,%rcx), %eax
279 %tmp1 = load i16* @s1
280 %tmp2 = sext i16 %tmp1 to i32
286 ; X32_LINUX: movb %gs:b1@NTPOFF, %al
287 ; X32_LINUX-NEXT: ret
289 ; X64_LINUX: movb %fs:b1@TPOFF, %al
290 ; X64_LINUX-NEXT: ret
292 ; X32_WIN: movl __tls_index, %eax
293 ; X32_WIN-NEXT: movl %fs:__tls_array, %ecx
294 ; X32_WIN-NEXT: movl (%ecx,%eax,4), %eax
295 ; X32_WIN-NEXT: movb _b1@SECREL(%eax), %al
298 ; X64_WIN: movl _tls_index(%rip), %eax
299 ; X64_WIN-NEXT: movq %gs:88, %rcx
300 ; X64_WIN-NEXT: movq (%rcx,%rax,8), %rax
301 ; X64_WIN-NEXT: movabsq $b1@SECREL, %rcx
302 ; X64_WIN-NEXT: movb (%rax,%rcx), %al
312 ; X32_LINUX: movsbl %gs:b1@NTPOFF, %eax
313 ; X32_LINUX-NEXT: ret
315 ; X64_LINUX: movsbl %fs:b1@TPOFF, %eax
316 ; X64_LINUX-NEXT: ret
318 ; X32_WIN: movl __tls_index, %eax
319 ; X32_WIN-NEXT: movl %fs:__tls_array, %ecx
320 ; X32_WIN-NEXT: movl (%ecx,%eax,4), %eax
321 ; X32_WIN-NEXT: movsbl _b1@SECREL(%eax), %eax
324 ; X64_WIN: movl _tls_index(%rip), %eax
325 ; X64_WIN-NEXT: movq %gs:88, %rcx
326 ; X64_WIN-NEXT: movq (%rcx,%rax,8), %rax
327 ; X64_WIN-NEXT: movabsq $b1@SECREL, %rcx
328 ; X64_WIN-NEXT: movsbl (%rax,%rcx), %eax
333 %tmp2 = sext i8 %tmp1 to i32