Fold 15 tiny test cases into a single file that implements the
[oota-llvm.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
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
13
14 define i32 @f1() {
15 ; X32_LINUX: f1:
16 ; X32_LINUX:      movl %gs:i1@NTPOFF, %eax
17 ; X32_LINUX-NEXT: ret
18 ; X64_LINUX: f1:
19 ; X64_LINUX:      movl %fs:i1@TPOFF, %eax
20 ; X64_LINUX-NEXT: ret
21 ; X32_WIN: f1:
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
26 ; X32_WIN-NEXT: ret
27 ; X64_WIN: f1:
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
33 ; X64_WIN-NEXT: ret
34
35 entry:
36         %tmp1 = load i32* @i1
37         ret i32 %tmp1
38 }
39
40 define i32* @f2() {
41 ; X32_LINUX: f2:
42 ; X32_LINUX:      movl %gs:0, %eax
43 ; X32_LINUX-NEXT: leal i1@NTPOFF(%eax), %eax
44 ; X32_LINUX-NEXT: ret
45 ; X64_LINUX: f2:
46 ; X64_LINUX:      movq %fs:0, %rax
47 ; X64_LINUX-NEXT: leaq i1@TPOFF(%rax), %rax
48 ; X64_LINUX-NEXT: ret
49 ; X32_WIN: f2:
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
54 ; X32_WIN-NEXT: ret
55 ; X64_WIN: f2:
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
60 ; X64_WIN-NEXT: ret
61
62 entry:
63         ret i32* @i1
64 }
65
66 define i32 @f3() nounwind {
67 ; X32_LINUX: f3:
68 ; X32_LINUX:      movl i2@INDNTPOFF, %eax
69 ; X32_LINUX-NEXT: movl %gs:(%eax), %eax
70 ; X32_LINUX-NEXT: ret
71 ; X64_LINUX: f3:
72 ; X64_LINUX:      movq i2@GOTTPOFF(%rip), %rax
73 ; X64_LINUX-NEXT: movl %fs:(%rax), %eax
74 ; X64_LINUX-NEXT: ret
75 ; X32_WIN: f3:
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
80 ; X32_WIN-NEXT: ret
81 ; X64_WIN: f3:
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
87 ; X64_WIN-NEXT: ret
88
89 entry:
90         %tmp1 = load i32* @i2
91         ret i32 %tmp1
92 }
93
94 define i32* @f4() {
95 ; X32_LINUX: f4:
96 ; X32_LINUX:      movl %gs:0, %eax
97 ; X32_LINUX-NEXT: addl i2@INDNTPOFF, %eax
98 ; X32_LINUX-NEXT: ret
99 ; X64_LINUX: f4:
100 ; X64_LINUX:      movq %fs:0, %rax
101 ; X64_LINUX-NEXT: addq i2@GOTTPOFF(%rip), %rax
102 ; X64_LINUX-NEXT: ret
103 ; X32_WIN: f4:
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
108 ; X32_WIN-NEXT: ret
109 ; X64_WIN: f4:
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
114 ; X64_WIN-NEXT: ret
115
116 entry:
117         ret i32* @i2
118 }
119
120 define i32 @f5() nounwind {
121 ; X32_LINUX: f5:
122 ; X32_LINUX:      movl %gs:i3@NTPOFF, %eax
123 ; X32_LINUX-NEXT: ret
124 ; X64_LINUX: f5:
125 ; X64_LINUX:      movl %fs:i3@TPOFF, %eax
126 ; X64_LINUX-NEXT: ret
127 ; X32_WIN: f5:
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
132 ; X32_WIN-NEXT: ret
133 ; X64_WIN: f5:
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
139 ; X64_WIN-NEXT: ret
140
141 entry:
142         %tmp1 = load i32* @i3
143         ret i32 %tmp1
144 }
145
146 define i32* @f6() {
147 ; X32_LINUX: f6:
148 ; X32_LINUX:      movl %gs:0, %eax
149 ; X32_LINUX-NEXT: leal i3@NTPOFF(%eax), %eax
150 ; X32_LINUX-NEXT: ret
151 ; X64_LINUX: f6:
152 ; X64_LINUX:      movq %fs:0, %rax
153 ; X64_LINUX-NEXT: leaq i3@TPOFF(%rax), %rax
154 ; X64_LINUX-NEXT: ret
155 ; X32_WIN: f6:
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
160 ; X32_WIN-NEXT: ret
161 ; X64_WIN: f6:
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
166 ; X64_WIN-NEXT: ret
167
168 entry:
169         ret i32* @i3
170 }
171
172 define i32 @f7() {
173 ; X32_LINUX: f7:
174 ; X32_LINUX:      movl %gs:i4@NTPOFF, %eax
175 ; X32_LINUX-NEXT: ret
176 ; X64_LINUX: f7:
177 ; X64_LINUX:      movl %fs:i4@TPOFF, %eax
178 ; X64_LINUX-NEXT: ret
179
180 entry:
181         %tmp1 = load i32* @i4
182         ret i32 %tmp1
183 }
184
185 define i32* @f8() {
186 ; X32_LINUX: f8:
187 ; X32_LINUX:      movl %gs:0, %eax
188 ; X32_LINUX-NEXT: leal i4@NTPOFF(%eax), %eax
189 ; X32_LINUX-NEXT: ret
190 ; X64_LINUX: f8:
191 ; X64_LINUX:      movq %fs:0, %rax
192 ; X64_LINUX-NEXT: leaq i4@TPOFF(%rax), %rax
193 ; X64_LINUX-NEXT: ret
194
195 entry:
196         ret i32* @i4
197 }
198
199 define i32 @f9() {
200 ; X32_LINUX: f9:
201 ; X32_LINUX:      movl %gs:i5@NTPOFF, %eax
202 ; X32_LINUX-NEXT: ret
203 ; X64_LINUX: f9:
204 ; X64_LINUX:      movl %fs:i5@TPOFF, %eax
205 ; X64_LINUX-NEXT: ret
206
207 entry:
208         %tmp1 = load i32* @i5
209         ret i32 %tmp1
210 }
211
212 define i32* @f10() {
213 ; X32_LINUX: f10:
214 ; X32_LINUX:      movl %gs:0, %eax
215 ; X32_LINUX-NEXT: leal i5@NTPOFF(%eax), %eax
216 ; X32_LINUX-NEXT: ret
217 ; X64_LINUX: f10:
218 ; X64_LINUX:      movq %fs:0, %rax
219 ; X64_LINUX-NEXT: leaq i5@TPOFF(%rax), %rax
220 ; X64_LINUX-NEXT: ret
221
222 entry:
223         ret i32* @i5
224 }
225
226 define i16 @f11() {
227 ; X32_LINUX: f11:
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
232 ; X64_LINUX: f11:
233 ; X64_LINUX:      movzwl %fs:s1@TPOFF, %eax
234 ; X64_LINUX-NEXT: # kill
235 ; X64_LINUX-NEXT: ret
236 ; X32_WIN: f11:
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
242 ; X32_WIN-NEXT: ret
243 ; X64_WIN: f11:
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
250 ; X64_WIN-NEXT: ret
251
252 entry:
253         %tmp1 = load i16* @s1
254         ret i16 %tmp1
255 }
256
257 define i32 @f12() {
258 ; X32_LINUX: f12:
259 ; X32_LINUX:      movswl %gs:s1@NTPOFF, %eax
260 ; X32_LINUX-NEXT: ret
261 ; X64_LINUX: f12:
262 ; X64_LINUX:      movswl %fs:s1@TPOFF, %eax
263 ; X64_LINUX-NEXT: ret
264 ; X32_WIN: f12:
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
269 ; X32_WIN-NEXT: ret
270 ; X64_WIN: f12:
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
276 ; X64_WIN-NEXT: ret
277
278 entry:
279         %tmp1 = load i16* @s1
280   %tmp2 = sext i16 %tmp1 to i32
281         ret i32 %tmp2
282 }
283
284 define i8 @f13() {
285 ; X32_LINUX: f13:
286 ; X32_LINUX:      movb %gs:b1@NTPOFF, %al
287 ; X32_LINUX-NEXT: ret
288 ; X64_LINUX: f13:
289 ; X64_LINUX:      movb %fs:b1@TPOFF, %al
290 ; X64_LINUX-NEXT: ret
291 ; X32_WIN: f13:
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
296 ; X32_WIN-NEXT: ret
297 ; X64_WIN: f13:
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
303 ; X64_WIN-NEXT: ret
304
305 entry:
306         %tmp1 = load i8* @b1
307         ret i8 %tmp1
308 }
309
310 define i32 @f14() {
311 ; X32_LINUX: f14:
312 ; X32_LINUX:      movsbl %gs:b1@NTPOFF, %eax
313 ; X32_LINUX-NEXT: ret
314 ; X64_LINUX: f14:
315 ; X64_LINUX:      movsbl %fs:b1@TPOFF, %eax
316 ; X64_LINUX-NEXT: ret
317 ; X32_WIN: f14:
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
322 ; X32_WIN-NEXT: ret
323 ; X64_WIN: f14:
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
329 ; X64_WIN-NEXT: ret
330
331 entry:
332         %tmp1 = load i8* @b1
333   %tmp2 = sext i8 %tmp1 to i32
334         ret i32 %tmp2
335 }
336