1; RUN: llc < %s -emulated-tls -mcpu=generic -mtriple=i386-linux-gnu -relocation-model=pic \
2; RUN:   | FileCheck -check-prefix=X86 %s
3; RUN: llc < %s -emulated-tls -mcpu=generic -mtriple=x86_64-linux-gnu -relocation-model=pic \
4; RUN:   | FileCheck -check-prefix=X64 %s
5; RUN: llc < %s -emulated-tls -mcpu=generic -mtriple=i386-linux-android -relocation-model=pic \
6; RUN:   | FileCheck -check-prefix=X86 %s
7; RUN: llc < %s -emulated-tls -mcpu=generic -mtriple=x86_64-linux-android -relocation-model=pic \
8; RUN:   | FileCheck -check-prefix=X64 %s
9
10; RUN: llc < %s -mcpu=generic -mtriple=i386-linux-gnu -relocation-model=pic \
11; RUN:   | FileCheck -check-prefix=NoEMU %s
12; RUN: llc < %s -mcpu=generic -mtriple=x86_64-linux-gnu -relocation-model=pic \
13; RUN:   | FileCheck -check-prefix=NoEMU %s
14; RUN: llc < %s -mcpu=generic -mtriple=i386-linux-android -relocation-model=pic \
15; RUN:   | FileCheck -check-prefix=X86 %s
16; RUN: llc < %s -mcpu=generic -mtriple=x86_64-linux-android -relocation-model=pic \
17; RUN:   | FileCheck -check-prefix=X64 %s
18
19; NoEMU-NOT: __emutls
20
21; Use my_emutls_get_address like __emutls_get_address.
22@my_emutls_v_xyz = external global i8*, align 4
23declare i8* @my_emutls_get_address(i8*)
24
25define dso_local i32 @my_get_xyz() {
26; X86-LABEL: my_get_xyz:
27; X86:      movl my_emutls_v_xyz@GOT(%ebx), %eax
28; X86-NEXT: movl %eax, (%esp)
29; X86-NEXT: calll my_emutls_get_address@PLT
30; X86-NEXT: movl (%eax), %eax
31; X86-NEXT: addl $8, %esp
32; X86-NEXT: .cfi_def_cfa_offset 8
33; X86-NEXT: popl %ebx
34; X86-NEXT: .cfi_def_cfa_offset 4
35; X86-NEXT: retl
36; X64-LABEL: my_get_xyz:
37; X64:      movq my_emutls_v_xyz@GOTPCREL(%rip), %rdi
38; X64-NEXT: callq my_emutls_get_address@PLT
39; X64-NEXT: movl (%rax), %eax
40; X64-NEXT: popq %rcx
41; X64-NEXT: .cfi_def_cfa_offset 8
42; X64-NEXT: retq
43
44entry:
45  %call = call i8* @my_emutls_get_address(i8* bitcast (i8** @my_emutls_v_xyz to i8*))
46  %0 = bitcast i8* %call to i32*
47  %1 = load i32, i32* %0, align 4
48  ret i32 %1
49}
50
51@i = dso_local thread_local global i32 15
52@i2 = external thread_local global i32
53
54define dso_local i32 @f1() {
55; X86-LABEL: f1:
56; X86:      leal __emutls_v.i@GOTOFF(%ebx), %eax
57; X86-NEXT: movl %eax, (%esp)
58; X86-NEXT: calll __emutls_get_address@PLT
59; X86-NEXT: movl (%eax), %eax
60; X86-NEXT: addl $8, %esp
61; X86-NEXT: .cfi_def_cfa_offset 8
62; X86-NEXT: popl %ebx
63; X86-NEXT: .cfi_def_cfa_offset 4
64; X86-NEXT: retl
65; X64-LABEL: f1:
66; X64:      leaq __emutls_v.i(%rip), %rdi
67; X64-NEXT: callq __emutls_get_address@PLT
68; X64-NEXT: movl (%rax), %eax
69; X64-NEXT: popq %rcx
70; X64-NEXT: .cfi_def_cfa_offset 8
71; X64-NEXT: retq
72
73entry:
74  %tmp1 = load i32, i32* @i
75  ret i32 %tmp1
76}
77
78define dso_local i32* @f2() {
79; X86-LABEL: f2:
80; X86:      leal __emutls_v.i@GOTOFF(%ebx), %eax
81; X86-NEXT: movl %eax, (%esp)
82; X86-NEXT: calll __emutls_get_address@PLT
83; X64-LABEL: f2:
84; X64:      leaq __emutls_v.i(%rip), %rdi
85; X64-NEXT: callq __emutls_get_address@PLT
86
87entry:
88  ret i32* @i
89}
90
91define dso_local i32 @f3() {
92; X86-LABEL: f3:
93; X86:      movl __emutls_v.i2@GOT(%ebx), %eax
94; X86-NEXT: movl %eax, (%esp)
95; X86-NEXT: calll __emutls_get_address@PLT
96; X64-LABEL: f3:
97; X64:      movq __emutls_v.i2@GOTPCREL(%rip), %rdi
98; X64-NEXT: callq __emutls_get_address@PLT
99
100entry:
101  %tmp1 = load i32, i32* @i2
102  ret i32 %tmp1
103}
104
105define dso_local i32* @f4() {
106; X86-LABEL: f4:
107; X86:      movl __emutls_v.i2@GOT(%ebx), %eax
108; X86-NEXT: movl %eax, (%esp)
109; X86-NEXT: calll __emutls_get_address@PLT
110; X64-LABEL: f4:
111; X64:      movq __emutls_v.i2@GOTPCREL(%rip), %rdi
112; X64-NEXT: callq __emutls_get_address@PLT
113
114entry:
115  ret i32* @i2
116}
117
118;;;;; 32-bit targets
119
120; X86:      .data
121; X86-LABEL: __emutls_v.i:
122; X86-NEXT: .long 4
123; X86-NEXT: .long 4
124; X86-NEXT: .long 0
125; X86-NEXT: .long __emutls_t.i
126
127; X86:      .section .rodata,
128; X86-LABEL: __emutls_t.i:
129; X86-NEXT: .long 15
130
131; X86-NOT:   __emutls_v.i2
132; X86-NOT:   __emutls_t.i2
133
134;;;;; 64-bit targets
135
136; X64:      .data
137; X64-LABEL: __emutls_v.i:
138; X64-NEXT: .quad 4
139; X64-NEXT: .quad 4
140; X64-NEXT: .quad 0
141; X64-NEXT: .quad __emutls_t.i
142
143; X64:      .section .rodata,
144; X64-LABEL: __emutls_t.i:
145; X64-NEXT: .long 15
146
147; X64-NOT:   __emutls_v.i2
148; X64-NOT:   __emutls_t.i2
149
150
151!llvm.module.flags = !{!0, !1}
152!0 = !{i32 1, !"PIC Level", i32 1}
153!1 = !{i32 1, !"PIE Level", i32 1}
154