1; RUN: llc -mtriple=thumbv7s-apple-ios7.0 -o - -fast-isel %s | FileCheck %s --check-prefix=T2-MOVT-PIC
2; RUN: llc -mtriple=thumbv7s-apple-ios7.0 -o - %s -mattr=+no-movt | FileCheck %s --check-prefix=T2-LIT-PIC
3; RUN: llc -mtriple=thumbv7s-apple-ios7.0 -o - %s -relocation-model=static | FileCheck %s --check-prefix=T2-MOVT-STATIC
4; RUN: llc -mtriple=thumbv7s-apple-ios7.0 -o - %s -mattr=+no-movt -relocation-model=static | FileCheck %s --check-prefix=T2-LIT-STATIC
5; RUN: llc -mtriple=armv7s-apple-ios7.0 -o - %s | FileCheck %s --check-prefix=ARM-MOVT-PIC
6; RUN: llc -mtriple=armv7s-apple-ios7.0 -o - %s -mattr=+no-movt | FileCheck %s --check-prefix=ARM-LIT-PIC
7; RUN: llc -mtriple=armv7s-apple-ios7.0 -o - %s -relocation-model=static | FileCheck %s --check-prefix=ARM-MOVT-STATIC
8; RUN: llc -mtriple=armv7s-apple-ios7.0 -o - %s -mattr=+no-movt -relocation-model=static | FileCheck %s --check-prefix=ARM-LIT-STATIC
9
10
11@local_tls_var = thread_local global i32 0
12@external_tls_var = external thread_local global i32
13@hidden_external_tls_var = external hidden thread_local global i32
14
15
16define i32 @test_local_tls() {
17; T2-MOVT-PIC-LABEL: test_local_tls:
18; T2-MOVT-PIC: movw r0, :lower16:(_local_tls_var-([[PCREL_LOC:LPC[0-9]+_[0-9]+]]+4))
19; T2-MOVT-PIC: movt r0, :upper16:(_local_tls_var-([[PCREL_LOC]]+4))
20; T2-MOVT-PIC: [[PCREL_LOC]]:
21; T2-MOVT-PIC-NEXT: add r0, pc
22; T2-MOVT-PIC: ldr [[TLV_GET_ADDR:r[0-9]+]], [r0]
23; T2-MOVT-PIC: blx [[TLV_GET_ADDR]]
24; T2-MOVT-PIC: ldr r0, [r0]
25
26; T2-LIT-PIC-LABEL: test_local_tls:
27; T2-LIT-PIC: ldr r0, [[LOCAL_VAR_ADDR:LCPI[0-9]+_[0-9]+]]
28; T2-LIT-PIC: [[PCREL_LOC:LPC[0-9]+_[0-9]+]]:
29; T2-LIT-PIC-NEXT: add r0, pc
30; T2-LIT-PIC: ldr [[TLV_GET_ADDR:r[0-9]+]], [r0]
31; T2-LIT-PIC: blx [[TLV_GET_ADDR]]
32; T2-LIT-PIC: ldr r0, [r0]
33; T2-LIT-PIC: [[LOCAL_VAR_ADDR]]:
34; T2-LIT-PIC-NEXT: .long _local_tls_var-([[PCREL_LOC]]+4)
35
36; T2-MOVT-STATIC-LABEL: test_local_tls:
37; T2-MOVT-STATIC: movw r0, :lower16:_local_tls_var
38; T2-MOVT-STATIC: movt r0, :upper16:_local_tls_var
39; T2-MOVT-STATIC: ldr [[TLV_GET_ADDR:r[0-9]+]], [r0]
40; T2-MOVT-STATIC: blx [[TLV_GET_ADDR]]
41; T2-MOVT-STATIC: ldr r0, [r0]
42
43; T2-LIT-STATIC-LABEL: test_local_tls:
44; T2-LIT-STATIC: ldr r0, [[LOCAL_VAR_ADDR:LCPI[0-9]+_[0-9]+]]
45; T2-LIT-STATIC: ldr [[TLV_GET_ADDR:r[0-9]+]], [r0]
46; T2-LIT-STATIC: blx [[TLV_GET_ADDR]]
47; T2-LIT-STATIC: ldr r0, [r0]
48; T2-LIT-STATIC: [[LOCAL_VAR_ADDR]]:
49; T2-LIT-STATIC-NEXT: .long _local_tls_var
50
51; ARM-MOVT-PIC-LABEL: test_local_tls:
52; ARM-MOVT-PIC: movw [[VARPC1:r[0-9]+]], :lower16:(_local_tls_var-([[PCREL_LOC1:LPC[0-9]+_[0-9]+]]+8))
53; ARM-MOVT-PIC: movt [[VARPC1]], :upper16:(_local_tls_var-([[PCREL_LOC1]]+8))
54; ARM-MOVT-PIC: [[PCREL_LOC1]]:
55; ARM-MOVT-PIC: add r0, pc, [[VARPC1]]
56; ARM-MOVT-PIC: movw [[VARPC2:r[0-9]+]], :lower16:(_local_tls_var-([[PCREL_LOC2:LPC[0-9]+_[0-9]+]]+8))
57; ARM-MOVT-PIC: movt [[VARPC2]], :upper16:(_local_tls_var-([[PCREL_LOC2]]+8))
58; ARM-MOVT-PIC: [[PCREL_LOC2]]:
59; ARM-MOVT-PIC-NEXT: ldr [[TLV_GET_ADDR:r[0-9]+]], [pc, [[VARPC2]]]
60; ARM-MOVT-PIC: blx [[TLV_GET_ADDR]]
61; ARM-MOVT-PIC: ldr r0, [r0]
62
63; ARM-LIT-PIC-LABEL: test_local_tls:
64; ARM-LIT-PIC: ldr r0, [[LOCAL_VAR_ADDR:LCPI[0-9]+_[0-9]+]]
65; ARM-LIT-PIC: [[PCREL_LOC:LPC[0-9]+_[0-9]+]]:
66; ARM-LIT-PIC-NEXT: add r0, pc
67; ARM-LIT-PIC: ldr [[TLV_GET_ADDR:r[0-9]+]], [r0]
68; ARM-LIT-PIC: blx [[TLV_GET_ADDR]]
69; ARM-LIT-PIC: ldr r0, [r0]
70; ARM-LIT-PIC: [[LOCAL_VAR_ADDR]]:
71; ARM-LIT-PIC-NEXT: .long _local_tls_var-([[PCREL_LOC]]+8)
72
73; ARM-MOVT-STATIC-LABEL: test_local_tls:
74; ARM-MOVT-STATIC: movw r0, :lower16:_local_tls_var
75; ARM-MOVT-STATIC: movt r0, :upper16:_local_tls_var
76; ARM-MOVT-STATIC: ldr [[TLV_GET_ADDR:r[0-9]+]], [r0]
77; ARM-MOVT-STATIC: blx [[TLV_GET_ADDR]]
78; ARM-MOVT-STATIC: ldr r0, [r0]
79
80; ARM-LIT-STATIC-LABEL: test_local_tls:
81; ARM-LIT-STATIC: ldr r0, [[LOCAL_VAR_ADDR:LCPI[0-9]+_[0-9]+]]
82; ARM-LIT-STATIC: ldr [[TLV_GET_ADDR:r[0-9]+]], [r0]
83; ARM-LIT-STATIC: blx [[TLV_GET_ADDR]]
84; ARM-LIT-STATIC: ldr r0, [r0]
85; ARM-LIT-STATIC: [[LOCAL_VAR_ADDR]]:
86; ARM-LIT-STATIC-NEXT: .long _local_tls_var
87
88
89  %val = load i32, i32* @local_tls_var, align 4
90  ret i32 %val
91}
92
93define i32 @test_external_tls() {
94; T2-MOVT-PIC-LABEL: test_external_tls:
95; T2-MOVT-PIC: movw r[[EXTGOT:[0-9]+]], :lower16:(L_external_tls_var$non_lazy_ptr-([[PCREL_LOC:LPC[0-9]+_[0-9]+]]+4))
96; T2-MOVT-PIC: movt r[[EXTGOT]], :upper16:(L_external_tls_var$non_lazy_ptr-([[PCREL_LOC]]+4))
97; T2-MOVT-PIC: [[PCREL_LOC]]:
98; T2-MOVT-PIC-NEXT: add r[[EXTGOT]], pc
99; T2-MOVT-PIC: ldr r0, [r[[EXTGOT]]]
100; T2-MOVT-PIC: ldr [[TLV_GET_ADDR:r[0-9]+]], [r0]
101; T2-MOVT-PIC: blx [[TLV_GET_ADDR]]
102; T2-MOVT-PIC: ldr r0, [r0]
103
104; T2-LIT-PIC-LABEL: test_external_tls:
105; T2-LIT-PIC: ldr r[[EXTGOT:[0-9]+]], [[EXTERNAL_VAR_ADDR:LCPI[0-9]+_[0-9]+]]
106; T2-LIT-PIC: [[PCREL_LOC:LPC[0-9]+_[0-9]+]]:
107; T2-LIT-PIC-NEXT: add r[[EXTGOT]], pc
108; T2-LIT-PIC: ldr r0, [r[[EXTGOT]]]
109; T2-LIT-PIC: ldr [[TLV_GET_ADDR:r[0-9]+]], [r0]
110; T2-LIT-PIC: blx [[TLV_GET_ADDR]]
111; T2-LIT-PIC: ldr r0, [r0]
112; T2-LIT-PIC: [[EXTERNAL_VAR_ADDR]]:
113; T2-LIT-PIC-NEXT: .long L_external_tls_var$non_lazy_ptr-([[PCREL_LOC]]+4)
114
115; T2-MOVT-STATIC-LABEL: test_external_tls:
116; T2-MOVT-STATIC: movw r0, :lower16:_external_tls_var
117; T2-MOVT-STATIC: movt r0, :upper16:_external_tls_var
118; T2-MOVT-STATIC: ldr [[TLV_GET_ADDR:r[0-9]+]], [r0]
119; T2-MOVT-STATIC: blx [[TLV_GET_ADDR]]
120; T2-MOVT-STATIC: ldr r0, [r0]
121
122; T2-LIT-STATIC-LABEL: test_external_tls:
123; T2-LIT-STATIC: ldr r0, [[EXTERNAL_VAR_ADDR:LCPI[0-9]+_[0-9]+]]
124; T2-LIT-STATIC: ldr [[TLV_GET_ADDR:r[0-9]+]], [r0]
125; T2-LIT-STATIC: blx [[TLV_GET_ADDR]]
126; T2-LIT-STATIC: ldr r0, [r0]
127; T2-LIT-STATIC: [[EXTERNAL_VAR_ADDR]]:
128; T2-LIT-STATIC-NEXT: .long _external_tls_var
129
130; ARM-MOVT-PIC-LABEL: test_external_tls:
131; ARM-MOVT-PIC: movw r[[EXTGOT:[0-9]+]], :lower16:(L_external_tls_var$non_lazy_ptr-([[PCREL_LOC:LPC[0-9]+_[0-9]+]]+8))
132; ARM-MOVT-PIC: movt r[[EXTGOT]], :upper16:(L_external_tls_var$non_lazy_ptr-([[PCREL_LOC]]+8))
133; ARM-MOVT-PIC: [[PCREL_LOC]]:
134; ARM-MOVT-PIC-NEXT: ldr r0, [pc, r[[EXTGOT]]]
135; ARM-MOVT-PIC: ldr [[TLV_GET_ADDR:r[0-9]+]], [r0]
136; ARM-MOVT-PIC: blx [[TLV_GET_ADDR]]
137; ARM-MOVT-PIC: ldr r0, [r0]
138
139; ARM-LIT-PIC-LABEL: test_external_tls:
140; ARM-LIT-PIC: ldr r[[EXTGOT:[0-9]+]], [[EXTERNAL_VAR_ADDR:LCPI[0-9]+_[0-9]+]]
141; ARM-LIT-PIC: [[PCREL_LOC:LPC[0-9]+_[0-9]+]]:
142; ARM-LIT-PIC-NEXT: add r[[EXTGOT]], pc
143; ARM-LIT-PIC: ldr r0, [r[[EXTGOT]]]
144; ARM-LIT-PIC: ldr [[TLV_GET_ADDR:r[0-9]+]], [r0]
145; ARM-LIT-PIC: blx [[TLV_GET_ADDR]]
146; ARM-LIT-PIC: ldr r0, [r0]
147; ARM-LIT-PIC: [[EXTERNAL_VAR_ADDR]]:
148; ARM-LIT-PIC-NEXT: .long L_external_tls_var$non_lazy_ptr-([[PCREL_LOC]]+8)
149
150; ARM-MOVT-STATIC-LABEL: test_external_tls:
151; ARM-MOVT-STATIC: movw r0, :lower16:_external_tls_var
152; ARM-MOVT-STATIC: movt r0, :upper16:_external_tls_var
153; ARM-MOVT-STATIC: ldr [[TLV_GET_ADDR:r[0-9]+]], [r0]
154; ARM-MOVT-STATIC: blx [[TLV_GET_ADDR]]
155; ARM-MOVT-STATIC: ldr r0, [r0]
156
157; ARM-LIT-STATIC-LABEL: test_external_tls:
158; ARM-LIT-STATIC: ldr r0, [[EXTERNAL_VAR_ADDR:LCPI[0-9]+_[0-9]+]]
159; ARM-LIT-STATIC: ldr [[TLV_GET_ADDR:r[0-9]+]], [r0]
160; ARM-LIT-STATIC: blx [[TLV_GET_ADDR]]
161; ARM-LIT-STATIC: ldr r0, [r0]
162; ARM-LIT-STATIC: [[EXTERNAL_VAR_ADDR]]:
163; ARM-LIT-STATIC-NEXT: .long _external_tls_var
164
165  %val = load i32, i32* @external_tls_var, align 4
166  ret i32 %val
167}
168
169; Just need something to trigger an indirect reference to the var.
170define i32 @use_hidden_external_tls() {
171  %val = load i32, i32* @hidden_external_tls_var, align 4
172  ret i32 %val
173}
174
175; T2-MOVT-PIC: .section __DATA,__thread_ptr,thread_local_variable_pointers
176; T2-MOVT-PIC: .p2align 2
177; T2-MOVT-PIC: L_external_tls_var$non_lazy_ptr:
178; T2-MOVT-PIC:     .indirect_symbol _external_tls_var
179; T2-MOVT-PIC:     .long 0
180; T2-MOVT-PIC: L_hidden_external_tls_var$non_lazy_ptr:
181; T2-MOVT-PIC:     .indirect_symbol _hidden_external_tls_var
182; T2-MOVT-PIC:     .long 0
183