ARM: fix folding stack adjustment (again again again...)
[oota-llvm.git] / test / CodeGen / ARM / emutls.ll
1 ; RUN: llc -emulated-tls -mtriple=arm-linux-android \
2 ; RUN:     -relocation-model=pic < %s | FileCheck -check-prefix=ARM32 %s
3
4 ; Copied from X86/emutls.ll
5
6 ; Use my_emutls_get_address like __emutls_get_address.
7 @my_emutls_v_xyz = external global i8*, align 4
8 declare i8* @my_emutls_get_address(i8*)
9
10 define i32 @my_get_xyz() {
11 ; ARM32-LABEL: my_get_xyz:
12 ; ARM32:        ldr r0,
13 ; ARM32-NEXT:   ldr r1,
14 ; ARM32:        add r0, pc, r0
15 ; ARM32-NEXT:   ldr r0, [r1, r0]
16 ; ARM32-NEXT:   bl my_emutls_get_address(PLT)
17 ; ARM32-NEXT:   ldr r0, [r0]
18
19 entry:
20   %call = call i8* @my_emutls_get_address(i8* bitcast (i8** @my_emutls_v_xyz to i8*))
21   %0 = bitcast i8* %call to i32*
22   %1 = load i32, i32* %0, align 4
23   ret i32 %1
24 }
25
26 @i1 = thread_local global i32 15
27 @i2 = external thread_local global i32
28 @i3 = internal thread_local global i32 15
29 @i4 = hidden thread_local global i32 15
30 @i5 = external hidden thread_local global i32
31 @s1 = thread_local global i16 15
32 @b1 = thread_local global i8 0
33
34 define i32 @f1() {
35 ; ARM32-LABEL: f1:
36 ; ARM32:        ldr r0,
37 ; ARM32-NEXT:   ldr r1,
38 ; ARM32:        add r0, pc, r0
39 ; ARM32-NEXT:   ldr r0, [r1, r0]
40 ; ARM32-NEXT:   bl __emutls_get_address(PLT)
41 ; ARM32-NEXT:   ldr r0, [r0]
42
43 entry:
44   %tmp1 = load i32, i32* @i1
45   ret i32 %tmp1
46 }
47
48 define i32* @f2() {
49 ; ARM32-LABEL: f2:
50 ; ARM32:        ldr r0,
51 ; ARM32-NEXT:   ldr r1,
52 ; ARM32:        add r0, pc, r0
53 ; ARM32-NEXT:   ldr r0, [r1, r0]
54 ; ARM32-NEXT:   bl __emutls_get_address(PLT)
55 ; ARM32-NEXT:   pop
56
57 entry:
58   ret i32* @i1
59 }
60
61 define i32 @f3() nounwind {
62 ; ARM32-LABEL: f3:
63 ; ARM32:        ldr r0,
64 ; ARM32-NEXT:   ldr r1,
65 ; ARM32:        add r0, pc, r0
66 ; ARM32-NEXT:   ldr r0, [r1, r0]
67 ; ARM32-NEXT:   bl __emutls_get_address(PLT)
68 ; ARM32-NEXT:   ldr r0, [r0]
69
70 entry:
71   %tmp1 = load i32, i32* @i2
72   ret i32 %tmp1
73 }
74
75 define i32* @f4() {
76 ; ARM32-LABEL: f4:
77 ; ARM32:        ldr r0,
78 ; ARM32-NEXT:   ldr r1,
79 ; ARM32:        add r0, pc, r0
80 ; ARM32-NEXT:   ldr r0, [r1, r0]
81 ; ARM32-NEXT:   bl __emutls_get_address(PLT)
82 ; ARM32-NEXT:   pop
83
84 entry:
85   ret i32* @i2
86 }
87
88 define i32 @f5() nounwind {
89 ; ARM32-LABEL: f5:
90 ; ARM32:        ldr r0,
91 ; ARM32-NEXT:   ldr r1,
92 ; ARM32:        add r0, pc, r0
93 ; ARM32-NEXT:   ldr r0, [r1, r0]
94 ; ARM32-NEXT:   bl __emutls_get_address(PLT)
95 ; ARM32-NEXT:   ldr r0, [r0]
96
97 entry:
98   %tmp1 = load i32, i32* @i3
99   ret i32 %tmp1
100 }
101
102 define i32* @f6() {
103 ; ARM32-LABEL: f6:
104 ; ARM32:        ldr r0,
105 ; ARM32-NEXT:   ldr r1,
106 ; ARM32:        add r0, pc, r0
107 ; ARM32-NEXT:   ldr r0, [r1, r0]
108 ; ARM32-NEXT:   bl __emutls_get_address(PLT)
109 ; ARM32-NEXT:   pop
110
111 entry:
112   ret i32* @i3
113 }
114
115 define i32 @f7() {
116 ; ARM32-LABEL: f7:
117 ; ARM32:        ldr r0,
118 ; ARM32-NEXT:   ldr r1,
119 ; ARM32:        add r0, pc, r0
120 ; ARM32-NEXT:   ldr r0, [r1, r0]
121 ; ARM32-NEXT:   bl __emutls_get_address(PLT)
122 ; ARM32-NEXT:   ldr r0, [r0]
123
124 entry:
125   %tmp1 = load i32, i32* @i4
126   ret i32 %tmp1
127 }
128
129 define i32* @f8() {
130 ; ARM32-LABEL: f8:
131 ; ARM32:        ldr r0,
132 ; ARM32-NEXT:   ldr r1,
133 ; ARM32:        add r0, pc, r0
134 ; ARM32-NEXT:   ldr r0, [r1, r0]
135 ; ARM32-NEXT:   bl __emutls_get_address(PLT)
136 ; ARM32-NEXT:   pop
137
138 entry:
139   ret i32* @i4
140 }
141
142 define i32 @f9() {
143 ; ARM32-LABEL: f9:
144 ; ARM32:        ldr r0,
145 ; ARM32-NEXT:   ldr r1,
146 ; ARM32:        add r0, pc, r0
147 ; ARM32-NEXT:   ldr r0, [r1, r0]
148 ; ARM32-NEXT:   bl __emutls_get_address(PLT)
149 ; ARM32-NEXT:   ldr r0, [r0]
150
151 entry:
152   %tmp1 = load i32, i32* @i5
153   ret i32 %tmp1
154 }
155
156 define i32* @f10() {
157 ; ARM32-LABEL: f10:
158 ; ARM32:        ldr r0,
159 ; ARM32-NEXT:   ldr r1,
160 ; ARM32:        add r0, pc, r0
161 ; ARM32-NEXT:   ldr r0, [r1, r0]
162 ; ARM32-NEXT:   bl __emutls_get_address(PLT)
163 ; ARM32-NEXT:   pop
164
165 entry:
166   ret i32* @i5
167 }
168
169 define i16 @f11() {
170 ; ARM32-LABEL: f11:
171 ; ARM32:        ldr r0,
172 ; ARM32-NEXT:   ldr r1,
173 ; ARM32:        add r0, pc, r0
174 ; ARM32-NEXT:   ldr r0, [r1, r0]
175 ; ARM32-NEXT:   bl __emutls_get_address(PLT)
176 ; ARM32-NEXT:   ldrh r0, [r0]
177
178 entry:
179   %tmp1 = load i16, i16* @s1
180   ret i16 %tmp1
181 }
182
183 define i32 @f12() {
184 ; ARM32-LABEL: f12:
185 ; ARM32:        ldr r0,
186 ; ARM32-NEXT:   ldr r1,
187 ; ARM32:        add r0, pc, r0
188 ; ARM32-NEXT:   ldr r0, [r1, r0]
189 ; ARM32-NEXT:   bl __emutls_get_address(PLT)
190 ; ARM32-NEXT:   ldrsh r0, [r0]
191
192 entry:
193   %tmp1 = load i16, i16* @s1
194   %tmp2 = sext i16 %tmp1 to i32
195   ret i32 %tmp2
196 }
197
198 define i8 @f13() {
199 ; ARM32-LABEL: f13:
200 ; ARM32:        ldr r0,
201 ; ARM32-NEXT:   ldr r1,
202 ; ARM32:        add r0, pc, r0
203 ; ARM32-NEXT:   ldr r0, [r1, r0]
204 ; ARM32-NEXT:   bl __emutls_get_address(PLT)
205 ; ARM32-NEXT:   ldrb r0, [r0]
206 ; ARM32-NEXT: pop
207
208 entry:
209   %tmp1 = load i8, i8* @b1
210   ret i8 %tmp1
211 }
212
213 define i32 @f14() {
214 ; ARM32-LABEL: f14:
215 ; ARM32:        ldr r0,
216 ; ARM32-NEXT:   ldr r1,
217 ; ARM32:        add r0, pc, r0
218 ; ARM32-NEXT:   ldr r0, [r1, r0]
219 ; ARM32-NEXT:   bl __emutls_get_address(PLT)
220 ; ARM32-NEXT:   ldrsb r0, [r0]
221 ; ARM32-NEXT: pop
222
223 entry:
224   %tmp1 = load i8, i8* @b1
225   %tmp2 = sext i8 %tmp1 to i32
226   ret i32 %tmp2
227 }
228
229 ;;;;;;;;;;;;;; 32-bit __emutls_v. and __emutls_t.
230
231 ; ARM32       .section .data.rel.local,
232 ; ARM32-LABEL: __emutls_v.i1:
233 ; ARM32-NEXT: .long 4
234 ; ARM32-NEXT: .long 4
235 ; ARM32-NEXT: .long 0
236 ; ARM32-NEXT: .long __emutls_t.i1
237
238 ; ARM32       .section .rodata,
239 ; ARM32-LABEL: __emutls_t.i1:
240 ; ARM32-NEXT: .long 15
241
242 ; ARM32-NOT:   __emutls_v.i2
243
244 ; ARM32       .section .data.rel.local,
245 ; ARM32-LABEL: __emutls_v.i3:
246 ; ARM32-NEXT: .long 4
247 ; ARM32-NEXT: .long 4
248 ; ARM32-NEXT: .long 0
249 ; ARM32-NEXT: .long __emutls_t.i3
250
251 ; ARM32       .section .rodata,
252 ; ARM32-LABEL: __emutls_t.i3:
253 ; ARM32-NEXT: .long 15
254
255 ; ARM32       .section .data.rel.local,
256 ; ARM32-LABEL: __emutls_v.i4:
257 ; ARM32-NEXT: .long 4
258 ; ARM32-NEXT: .long 4
259 ; ARM32-NEXT: .long 0
260 ; ARM32-NEXT: .long __emutls_t.i4
261
262 ; ARM32       .section .rodata,
263 ; ARM32-LABEL: __emutls_t.i4:
264 ; ARM32-NEXT: .long 15
265
266 ; ARM32-NOT:   __emutls_v.i5:
267 ; ARM32       .hidden __emutls_v.i5
268 ; ARM32-NOT:   __emutls_v.i5:
269
270 ; ARM32 .section .data.rel.local,
271 ; ARM32-LABEL: __emutls_v.s1:
272 ; ARM32-NEXT: .long 2
273 ; ARM32-NEXT: .long 2
274 ; ARM32-NEXT: .long 0
275 ; ARM32-NEXT: .long __emutls_t.s1
276
277 ; ARM32 .section .rodata,
278 ; ARM32-LABEL: __emutls_t.s1:
279 ; ARM32-NEXT: .short 15
280
281 ; ARM32 .section .data.rel.local,
282 ; ARM32-LABEL: __emutls_v.b1:
283 ; ARM32-NEXT: .long 1
284 ; ARM32-NEXT: .long 1
285 ; ARM32-NEXT: .long 0
286 ; ARM32-NEXT: .long 0
287
288 ; ARM32-NOT:   __emutls_t.b1