Move the segmented stack switch to a function attribute
[oota-llvm.git] / test / CodeGen / X86 / segmented-stacks.ll
1 ; RUN: llc < %s -mcpu=generic -mtriple=i686-linux -verify-machineinstrs | FileCheck %s -check-prefix=X32-Linux
2 ; RUN: llc < %s -mcpu=generic -mtriple=x86_64-linux  -verify-machineinstrs | FileCheck %s -check-prefix=X64-Linux
3 ; RUN: llc < %s -mcpu=generic -mtriple=i686-darwin -verify-machineinstrs | FileCheck %s -check-prefix=X32-Darwin
4 ; RUN: llc < %s -mcpu=generic -mtriple=x86_64-darwin -verify-machineinstrs | FileCheck %s -check-prefix=X64-Darwin
5 ; RUN: llc < %s -mcpu=generic -mtriple=i686-mingw32 -verify-machineinstrs | FileCheck %s -check-prefix=X32-MinGW
6 ; RUN: llc < %s -mcpu=generic -mtriple=x86_64-freebsd -verify-machineinstrs | FileCheck %s -check-prefix=X64-FreeBSD
7 ; RUN: llc < %s -mcpu=generic -mtriple=x86_64-mingw32 -verify-machineinstrs | FileCheck %s -check-prefix=X64-MinGW
8
9 ; We used to crash with filetype=obj
10 ; RUN: llc < %s -mcpu=generic -mtriple=i686-linux -filetype=obj
11 ; RUN: llc < %s -mcpu=generic -mtriple=x86_64-linux -filetype=obj
12 ; RUN: llc < %s -mcpu=generic -mtriple=i686-darwin -filetype=obj
13 ; RUN: llc < %s -mcpu=generic -mtriple=x86_64-darwin -filetype=obj
14 ; RUN: llc < %s -mcpu=generic -mtriple=i686-mingw32 -filetype=obj
15 ; RUN: llc < %s -mcpu=generic -mtriple=x86_64-freebsd -filetype=obj
16 ; RUN: llc < %s -mcpu=generic -mtriple=x86_64-mingw32 -filetype=obj
17
18 ; RUN: not llc < %s -mcpu=generic -mtriple=x86_64-solaris 2> %t.log
19 ; RUN: FileCheck %s -input-file=%t.log -check-prefix=X64-Solaris
20 ; RUN: not llc < %s -mcpu=generic -mtriple=i686-freebsd 2> %t.log
21 ; RUN: FileCheck %s -input-file=%t.log -check-prefix=X32-FreeBSD
22
23 ; X64-Solaris: Segmented stacks not supported on this platform
24 ; X32-FreeBSD: Segmented stacks not supported on FreeBSD i386
25
26 ; Just to prevent the alloca from being optimized away
27 declare void @dummy_use(i32*, i32)
28
29 define void @test_basic() #0 {
30         %mem = alloca i32, i32 10
31         call void @dummy_use (i32* %mem, i32 10)
32         ret void
33
34 ; X32-Linux-LABEL:       test_basic:
35
36 ; X32-Linux:       cmpl %gs:48, %esp
37 ; X32-Linux-NEXT:  ja      .LBB0_2
38
39 ; X32-Linux:       pushl $0
40 ; X32-Linux-NEXT:  pushl $60
41 ; X32-Linux-NEXT:  calll __morestack
42 ; X32-Linux-NEXT:  ret
43
44 ; X64-Linux-LABEL:       test_basic:
45
46 ; X64-Linux:       cmpq %fs:112, %rsp
47 ; X64-Linux-NEXT:  ja      .LBB0_2
48
49 ; X64-Linux:       movabsq $40, %r10
50 ; X64-Linux-NEXT:  movabsq $0, %r11
51 ; X64-Linux-NEXT:  callq __morestack
52 ; X64-Linux-NEXT:  ret
53
54 ; X32-Darwin-LABEL:      test_basic:
55
56 ; X32-Darwin:      movl $432, %ecx
57 ; X32-Darwin-NEXT: cmpl %gs:(%ecx), %esp
58 ; X32-Darwin-NEXT: ja      LBB0_2
59
60 ; X32-Darwin:      pushl $0
61 ; X32-Darwin-NEXT: pushl $60
62 ; X32-Darwin-NEXT: calll ___morestack
63 ; X32-Darwin-NEXT: ret
64
65 ; X64-Darwin-LABEL:      test_basic:
66
67 ; X64-Darwin:      cmpq %gs:816, %rsp
68 ; X64-Darwin-NEXT: ja      LBB0_2
69
70 ; X64-Darwin:      movabsq $40, %r10
71 ; X64-Darwin-NEXT: movabsq $0, %r11
72 ; X64-Darwin-NEXT: callq ___morestack
73 ; X64-Darwin-NEXT: ret
74
75 ; X32-MinGW-LABEL:       test_basic:
76
77 ; X32-MinGW:       cmpl %fs:20, %esp
78 ; X32-MinGW-NEXT:  ja      LBB0_2
79
80 ; X32-MinGW:       pushl $0
81 ; X32-MinGW-NEXT:  pushl $48
82 ; X32-MinGW-NEXT:  calll ___morestack
83 ; X32-MinGW-NEXT:  ret
84
85 ; X64-MinGW-LABEL:       test_basic:
86
87 ; X64-MinGW:       cmpq %gs:40, %rsp
88 ; X64-MinGW-NEXT:  ja      .LBB0_2
89
90 ; X64-MinGW:       movabsq $72, %r10
91 ; X64-MinGW-NEXT:  movabsq $32, %r11
92 ; X64-MinGW-NEXT:  callq __morestack
93 ; X64-MinGW-NEXT:  retq
94
95 ; X64-FreeBSD-LABEL:       test_basic:
96
97 ; X64-FreeBSD:       cmpq %fs:24, %rsp
98 ; X64-FreeBSD-NEXT:  ja      .LBB0_2
99
100 ; X64-FreeBSD:       movabsq $40, %r10
101 ; X64-FreeBSD-NEXT:  movabsq $0, %r11
102 ; X64-FreeBSD-NEXT:  callq __morestack
103 ; X64-FreeBSD-NEXT:  ret
104
105 }
106
107 define i32 @test_nested(i32 * nest %closure, i32 %other) #0 {
108        %addend = load i32 * %closure
109        %result = add i32 %other, %addend
110        ret i32 %result
111
112 ; X32-Linux:       cmpl %gs:48, %esp
113 ; X32-Linux-NEXT:  ja      .LBB1_2
114
115 ; X32-Linux:       pushl $4
116 ; X32-Linux-NEXT:  pushl $0
117 ; X32-Linux-NEXT:  calll __morestack
118 ; X32-Linux-NEXT:  ret
119
120 ; X64-Linux:       cmpq %fs:112, %rsp
121 ; X64-Linux-NEXT:  ja      .LBB1_2
122
123 ; X64-Linux:       movq %r10, %rax
124 ; X64-Linux-NEXT:  movabsq $0, %r10
125 ; X64-Linux-NEXT:  movabsq $0, %r11
126 ; X64-Linux-NEXT:  callq __morestack
127 ; X64-Linux-NEXT:  ret
128 ; X64-Linux-NEXT:  movq %rax, %r10
129
130 ; X32-Darwin:      movl $432, %edx
131 ; X32-Darwin-NEXT: cmpl %gs:(%edx), %esp
132 ; X32-Darwin-NEXT: ja      LBB1_2
133
134 ; X32-Darwin:      pushl $4
135 ; X32-Darwin-NEXT: pushl $0
136 ; X32-Darwin-NEXT: calll ___morestack
137 ; X32-Darwin-NEXT: ret
138
139 ; X64-Darwin:      cmpq %gs:816, %rsp
140 ; X64-Darwin-NEXT: ja      LBB1_2
141
142 ; X64-Darwin:      movq %r10, %rax
143 ; X64-Darwin-NEXT: movabsq $0, %r10
144 ; X64-Darwin-NEXT: movabsq $0, %r11
145 ; X64-Darwin-NEXT: callq ___morestack
146 ; X64-Darwin-NEXT: ret
147 ; X64-Darwin-NEXT: movq %rax, %r10
148
149 ; X32-MinGW:       cmpl %fs:20, %esp
150 ; X32-MinGW-NEXT:  ja      LBB1_2
151
152 ; X32-MinGW:       pushl $4
153 ; X32-MinGW-NEXT:  pushl $0
154 ; X32-MinGW-NEXT:  calll ___morestack
155 ; X32-MinGW-NEXT:  ret
156
157 ; X64-MinGW-LABEL: test_nested:
158 ; X64-MinGW:       cmpq %gs:40, %rsp
159 ; X64-MinGW-NEXT:  ja      .LBB1_2
160
161 ; X64-MinGW:       movq %r10, %rax
162 ; X64-MinGW-NEXT:  movabsq $0, %r10
163 ; X64-MinGW-NEXT:  movabsq $32, %r11
164 ; X64-MinGW-NEXT:  callq __morestack
165 ; X64-MinGW-NEXT:  retq
166 ; X64-MinGW-NEXT:  movq %rax, %r10
167
168 ; X64-FreeBSD:       cmpq %fs:24, %rsp
169 ; X64-FreeBSD-NEXT:  ja      .LBB1_2
170
171 ; X64-FreeBSD:       movq %r10, %rax
172 ; X64-FreeBSD-NEXT:  movabsq $0, %r10
173 ; X64-FreeBSD-NEXT:  movabsq $0, %r11
174 ; X64-FreeBSD-NEXT:  callq __morestack
175 ; X64-FreeBSD-NEXT:  ret
176 ; X64-FreeBSD-NEXT:  movq %rax, %r10
177
178 }
179
180 define void @test_large() #0 {
181         %mem = alloca i32, i32 10000
182         call void @dummy_use (i32* %mem, i32 0)
183         ret void
184
185 ; X32-Linux:       leal -40012(%esp), %ecx
186 ; X32-Linux-NEXT:  cmpl %gs:48, %ecx
187 ; X32-Linux-NEXT:  ja      .LBB2_2
188
189 ; X32-Linux:       pushl $0
190 ; X32-Linux-NEXT:  pushl $40012
191 ; X32-Linux-NEXT:  calll __morestack
192 ; X32-Linux-NEXT:  ret
193
194 ; X64-Linux:       leaq -40008(%rsp), %r11
195 ; X64-Linux-NEXT:  cmpq %fs:112, %r11
196 ; X64-Linux-NEXT:  ja      .LBB2_2
197
198 ; X64-Linux:       movabsq $40008, %r10
199 ; X64-Linux-NEXT:  movabsq $0, %r11
200 ; X64-Linux-NEXT:  callq __morestack
201 ; X64-Linux-NEXT:  ret
202
203 ; X32-Darwin:      leal -40012(%esp), %ecx
204 ; X32-Darwin-NEXT: movl $432, %eax
205 ; X32-Darwin-NEXT: cmpl %gs:(%eax), %ecx
206 ; X32-Darwin-NEXT: ja      LBB2_2
207
208 ; X32-Darwin:      pushl $0
209 ; X32-Darwin-NEXT: pushl $40012
210 ; X32-Darwin-NEXT: calll ___morestack
211 ; X32-Darwin-NEXT: ret
212
213 ; X64-Darwin:      leaq -40008(%rsp), %r11
214 ; X64-Darwin-NEXT: cmpq %gs:816, %r11
215 ; X64-Darwin-NEXT: ja      LBB2_2
216
217 ; X64-Darwin:      movabsq $40008, %r10
218 ; X64-Darwin-NEXT: movabsq $0, %r11
219 ; X64-Darwin-NEXT: callq ___morestack
220 ; X64-Darwin-NEXT: ret
221
222 ; X32-MinGW:       leal -40008(%esp), %ecx
223 ; X32-MinGW-NEXT:  cmpl %fs:20, %ecx
224 ; X32-MinGW-NEXT:  ja      LBB2_2
225
226 ; X32-MinGW:       pushl $0
227 ; X32-MinGW-NEXT:  pushl $40008
228 ; X32-MinGW-NEXT:  calll ___morestack
229 ; X32-MinGW-NEXT:  ret
230
231 ; X64-MinGW-LABEL: test_large:
232 ; X64-MinGW:       leaq -40040(%rsp), %r11
233 ; X64-MinGW-NEXT:  cmpq %gs:40, %r11
234 ; X64-MinGW-NEXT:  ja      .LBB2_2
235
236 ; X64-MinGW:       movabsq $40040, %r10
237 ; X64-MinGW-NEXT:  movabsq $32, %r11
238 ; X64-MinGW-NEXT:  callq __morestack
239 ; X64-MinGW-NEXT:  retq
240
241 ; X64-FreeBSD:       leaq -40008(%rsp), %r11
242 ; X64-FreeBSD-NEXT:  cmpq %fs:24, %r11
243 ; X64-FreeBSD-NEXT:  ja      .LBB2_2
244
245 ; X64-FreeBSD:       movabsq $40008, %r10
246 ; X64-FreeBSD-NEXT:  movabsq $0, %r11
247 ; X64-FreeBSD-NEXT:  callq __morestack
248 ; X64-FreeBSD-NEXT:  ret
249
250 }
251
252 define fastcc void @test_fastcc() #0 {
253         %mem = alloca i32, i32 10
254         call void @dummy_use (i32* %mem, i32 10)
255         ret void
256
257 ; X32-Linux-LABEL:       test_fastcc:
258
259 ; X32-Linux:       cmpl %gs:48, %esp
260 ; X32-Linux-NEXT:  ja      .LBB3_2
261
262 ; X32-Linux:       pushl $0
263 ; X32-Linux-NEXT:  pushl $60
264 ; X32-Linux-NEXT:  calll __morestack
265 ; X32-Linux-NEXT:  ret
266
267 ; X64-Linux-LABEL:       test_fastcc:
268
269 ; X64-Linux:       cmpq %fs:112, %rsp
270 ; X64-Linux-NEXT:  ja      .LBB3_2
271
272 ; X64-Linux:       movabsq $40, %r10
273 ; X64-Linux-NEXT:  movabsq $0, %r11
274 ; X64-Linux-NEXT:  callq __morestack
275 ; X64-Linux-NEXT:  ret
276
277 ; X32-Darwin-LABEL:      test_fastcc:
278
279 ; X32-Darwin:      movl $432, %eax
280 ; X32-Darwin-NEXT: cmpl %gs:(%eax), %esp
281 ; X32-Darwin-NEXT: ja      LBB3_2
282
283 ; X32-Darwin:      pushl $0
284 ; X32-Darwin-NEXT: pushl $60
285 ; X32-Darwin-NEXT: calll ___morestack
286 ; X32-Darwin-NEXT: ret
287
288 ; X64-Darwin-LABEL:      test_fastcc:
289
290 ; X64-Darwin:      cmpq %gs:816, %rsp
291 ; X64-Darwin-NEXT: ja      LBB3_2
292
293 ; X64-Darwin:      movabsq $40, %r10
294 ; X64-Darwin-NEXT: movabsq $0, %r11
295 ; X64-Darwin-NEXT: callq ___morestack
296 ; X64-Darwin-NEXT: ret
297
298 ; X32-MinGW-LABEL:       test_fastcc:
299
300 ; X32-MinGW:       cmpl %fs:20, %esp
301 ; X32-MinGW-NEXT:  ja      LBB3_2
302
303 ; X32-MinGW:       pushl $0
304 ; X32-MinGW-NEXT:  pushl $48
305 ; X32-MinGW-NEXT:  calll ___morestack
306 ; X32-MinGW-NEXT:  ret
307
308 ; X64-MinGW-LABEL:       test_fastcc:
309
310 ; X64-MinGW:       cmpq %gs:40, %rsp
311 ; X64-MinGW-NEXT:  ja      .LBB3_2
312
313 ; X64-MinGW:       movabsq $72, %r10
314 ; X64-MinGW-NEXT:  movabsq $32, %r11
315 ; X64-MinGW-NEXT:  callq __morestack
316 ; X64-MinGW-NEXT:  retq
317
318 ; X64-FreeBSD-LABEL:       test_fastcc:
319
320 ; X64-FreeBSD:       cmpq %fs:24, %rsp
321 ; X64-FreeBSD-NEXT:  ja      .LBB3_2
322
323 ; X64-FreeBSD:       movabsq $40, %r10
324 ; X64-FreeBSD-NEXT:  movabsq $0, %r11
325 ; X64-FreeBSD-NEXT:  callq __morestack
326 ; X64-FreeBSD-NEXT:  ret
327
328 }
329
330 define fastcc void @test_fastcc_large() #0 {
331         %mem = alloca i32, i32 10000
332         call void @dummy_use (i32* %mem, i32 0)
333         ret void
334
335 ; X32-Linux-LABEL:       test_fastcc_large:
336
337 ; X32-Linux:       leal -40012(%esp), %eax
338 ; X32-Linux-NEXT:  cmpl %gs:48, %eax
339 ; X32-Linux-NEXT:  ja      .LBB4_2
340
341 ; X32-Linux:       pushl $0
342 ; X32-Linux-NEXT:  pushl $40012
343 ; X32-Linux-NEXT:  calll __morestack
344 ; X32-Linux-NEXT:  ret
345
346 ; X64-Linux-LABEL:       test_fastcc_large:
347
348 ; X64-Linux:       leaq -40008(%rsp), %r11
349 ; X64-Linux-NEXT:  cmpq %fs:112, %r11
350 ; X64-Linux-NEXT:  ja      .LBB4_2
351
352 ; X64-Linux:       movabsq $40008, %r10
353 ; X64-Linux-NEXT:  movabsq $0, %r11
354 ; X64-Linux-NEXT:  callq __morestack
355 ; X64-Linux-NEXT:  ret
356
357 ; X32-Darwin-LABEL:      test_fastcc_large:
358
359 ; X32-Darwin:      leal -40012(%esp), %eax
360 ; X32-Darwin-NEXT: movl $432, %ecx
361 ; X32-Darwin-NEXT: cmpl %gs:(%ecx), %eax
362 ; X32-Darwin-NEXT: ja      LBB4_2
363
364 ; X32-Darwin:      pushl $0
365 ; X32-Darwin-NEXT: pushl $40012
366 ; X32-Darwin-NEXT: calll ___morestack
367 ; X32-Darwin-NEXT: ret
368
369 ; X64-Darwin-LABEL:      test_fastcc_large:
370
371 ; X64-Darwin:      leaq -40008(%rsp), %r11
372 ; X64-Darwin-NEXT: cmpq %gs:816, %r11
373 ; X64-Darwin-NEXT: ja      LBB4_2
374
375 ; X64-Darwin:      movabsq $40008, %r10
376 ; X64-Darwin-NEXT: movabsq $0, %r11
377 ; X64-Darwin-NEXT: callq ___morestack
378 ; X64-Darwin-NEXT: ret
379
380 ; X32-MinGW-LABEL:       test_fastcc_large:
381
382 ; X32-MinGW:       leal -40008(%esp), %eax
383 ; X32-MinGW-NEXT:  cmpl %fs:20, %eax
384 ; X32-MinGW-NEXT:  ja      LBB4_2
385
386 ; X32-MinGW:       pushl $0
387 ; X32-MinGW-NEXT:  pushl $40008
388 ; X32-MinGW-NEXT:  calll ___morestack
389 ; X32-MinGW-NEXT:  ret
390
391 ; X64-MinGW-LABEL:       test_fastcc_large:
392
393 ; X64-MinGW:       leaq -40040(%rsp), %r11
394 ; X64-MinGW-NEXT:  cmpq %gs:40, %r11
395 ; X64-MinGW-NEXT:  ja      .LBB4_2
396
397 ; X64-MinGW:       movabsq $40040, %r10
398 ; X64-MinGW-NEXT:  movabsq $32, %r11
399 ; X64-MinGW-NEXT:  callq __morestack
400 ; X64-MinGW-NEXT:  retq
401
402 ; X64-FreeBSD-LABEL:       test_fastcc_large:
403
404 ; X64-FreeBSD:       leaq -40008(%rsp), %r11
405 ; X64-FreeBSD-NEXT:  cmpq %fs:24, %r11
406 ; X64-FreeBSD-NEXT:  ja      .LBB4_2
407
408 ; X64-FreeBSD:       movabsq $40008, %r10
409 ; X64-FreeBSD-NEXT:  movabsq $0, %r11
410 ; X64-FreeBSD-NEXT:  callq __morestack
411 ; X64-FreeBSD-NEXT:  ret
412
413 }
414
415 define fastcc void @test_fastcc_large_with_ecx_arg(i32 %a) #0 {
416         %mem = alloca i32, i32 10000
417         call void @dummy_use (i32* %mem, i32 %a)
418         ret void
419
420 ; This is testing that the Mac implementation preserves ecx
421
422 ; X32-Darwin-LABEL:      test_fastcc_large_with_ecx_arg:
423
424 ; X32-Darwin:      leal -40012(%esp), %eax
425 ; X32-Darwin-NEXT: pushl %ecx
426 ; X32-Darwin-NEXT: movl $432, %ecx
427 ; X32-Darwin-NEXT: cmpl %gs:(%ecx), %eax
428 ; X32-Darwin-NEXT: popl %ecx
429 ; X32-Darwin-NEXT: ja      LBB5_2
430
431 ; X32-Darwin:      pushl $0
432 ; X32-Darwin-NEXT: pushl $40012
433 ; X32-Darwin-NEXT: calll ___morestack
434 ; X32-Darwin-NEXT: ret
435
436 }
437
438 attributes #0 = { "split-stack" }