• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
18define 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
44entry:
45	%tmp1 = load i32, i32* @i1
46	ret i32 %tmp1
47}
48
49define 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
77entry:
78	ret i32* @i1
79}
80
81define 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
109entry:
110	%tmp1 = load i32, i32* @i2
111	ret i32 %tmp1
112}
113
114define 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
142entry:
143	ret i32* @i2
144}
145
146define 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
172entry:
173	%tmp1 = load i32, i32* @i3
174	ret i32 %tmp1
175}
176
177define 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
205entry:
206	ret i32* @i3
207}
208
209define 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
223entry:
224	%tmp1 = load i32, i32* @i4
225	ret i32 %tmp1
226}
227
228define 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
244entry:
245	ret i32* @i4
246}
247
248define 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
262entry:
263	%tmp1 = load i32, i32* @i5
264	ret i32 %tmp1
265}
266
267define 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
283entry:
284	ret i32* @i5
285}
286
287define 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
313entry:
314	%tmp1 = load i16, i16* @s1
315	ret i16 %tmp1
316}
317
318define 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
345entry:
346	%tmp1 = load i16, i16* @s1
347  %tmp2 = sext i16 %tmp1 to i32
348	ret i32 %tmp2
349}
350
351define 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
377entry:
378	%tmp1 = load i8, i8* @b1
379	ret i8 %tmp1
380}
381
382define 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
408entry:
409	%tmp1 = load i8, i8* @b1
410  %tmp2 = sext i8 %tmp1 to i32
411	ret i32 %tmp2
412}
413
414define 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
438entry:
439	ret i8* @b2
440}
441
442
443define 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}
456