1; RUN: llc < %s -mtriple=arm-linux-androideabi -mattr=+v4t -verify-machineinstrs | FileCheck %s -check-prefix=ARM-android
2; RUN: llc < %s -mtriple=arm-linux-unknown-gnueabi -mattr=+v4t  -verify-machineinstrs | FileCheck %s -check-prefix=ARM-linux
3
4; We used to crash with filetype=obj
5; RUN: llc < %s -mtriple=arm-linux-androideabi -filetype=obj
6; RUN: llc < %s -mtriple=arm-linux-unknown-gnueabi -filetype=obj
7
8
9; Just to prevent the alloca from being optimized away
10declare void @dummy_use(i32*, i32)
11
12define void @test_basic() #0 {
13        %mem = alloca i32, i32 10
14        call void @dummy_use (i32* %mem, i32 10)
15	ret void
16
17; ARM-linux:      test_basic:
18
19; ARM-linux:      push    {r4, r5}
20; ARM-linux-NEXT: mrc     p15, #0, r4, c13, c0, #3
21; ARM-linux-NEXT: mov     r5, sp
22; ARM-linux-NEXT: ldr     r4, [r4, #4]
23; ARM-linux-NEXT: cmp     r4, r5
24; ARM-linux-NEXT: blo     .LBB0_2
25
26; ARM-linux:      mov     r4, #48
27; ARM-linux-NEXT: mov     r5, #0
28; ARM-linux-NEXT: stmdb   sp!, {lr}
29; ARM-linux-NEXT: bl      __morestack
30; ARM-linux-NEXT: ldm     sp!, {lr}
31; ARM-linux-NEXT: pop     {r4, r5}
32; ARM-linux-NEXT: bx      lr
33
34; ARM-linux:      pop     {r4, r5}
35
36; ARM-android:      test_basic:
37
38; ARM-android:      push    {r4, r5}
39; ARM-android-NEXT: mrc     p15, #0, r4, c13, c0, #3
40; ARM-android-NEXT: mov     r5, sp
41; ARM-android-NEXT: ldr     r4, [r4, #252]
42; ARM-android-NEXT: cmp     r4, r5
43; ARM-android-NEXT: blo     .LBB0_2
44
45; ARM-android:      mov     r4, #48
46; ARM-android-NEXT: mov     r5, #0
47; ARM-android-NEXT: stmdb   sp!, {lr}
48; ARM-android-NEXT: bl      __morestack
49; ARM-android-NEXT: ldm     sp!, {lr}
50; ARM-android-NEXT: pop     {r4, r5}
51; ARM-android-NEXT: bx      lr
52
53; ARM-android:      pop     {r4, r5}
54
55}
56
57define i32 @test_nested(i32 * nest %closure, i32 %other) #0 {
58       %addend = load i32 , i32 * %closure
59       %result = add i32 %other, %addend
60       %mem = alloca i32, i32 10
61       call void @dummy_use (i32* %mem, i32 10)
62       ret i32 %result
63
64; ARM-linux:      test_nested:
65
66; ARM-linux:      push    {r4, r5}
67; ARM-linux-NEXT: mrc     p15, #0, r4, c13, c0, #3
68; ARM-linux-NEXT: mov     r5, sp
69; ARM-linux-NEXT: ldr     r4, [r4, #4]
70; ARM-linux-NEXT: cmp     r4, r5
71; ARM-linux-NEXT: blo     .LBB1_2
72
73; ARM-linux:      mov     r4, #56
74; ARM-linux-NEXT: mov     r5, #0
75; ARM-linux-NEXT: stmdb   sp!, {lr}
76; ARM-linux-NEXT: bl      __morestack
77; ARM-linux-NEXT: ldm     sp!, {lr}
78; ARM-linux-NEXT: pop     {r4, r5}
79; ARM-linux-NEXT: bx      lr
80
81; ARM-linux:      pop     {r4, r5}
82
83; ARM-android:      test_nested:
84
85; ARM-android:      push    {r4, r5}
86; ARM-android-NEXT: mrc     p15, #0, r4, c13, c0, #3
87; ARM-android-NEXT: mov     r5, sp
88; ARM-android-NEXT: ldr     r4, [r4, #252]
89; ARM-android-NEXT: cmp     r4, r5
90; ARM-android-NEXT: blo     .LBB1_2
91
92; ARM-android:      mov     r4, #56
93; ARM-android-NEXT: mov     r5, #0
94; ARM-android-NEXT: stmdb   sp!, {lr}
95; ARM-android-NEXT: bl      __morestack
96; ARM-android-NEXT: ldm     sp!, {lr}
97; ARM-android-NEXT: pop     {r4, r5}
98; ARM-android-NEXT: bx      lr
99
100; ARM-android:      pop     {r4, r5}
101
102}
103
104define void @test_large() #0 {
105        %mem = alloca i32, i32 10000
106        call void @dummy_use (i32* %mem, i32 0)
107        ret void
108
109; ARM-linux:      test_large:
110
111; ARM-linux:      push    {r4, r5}
112; ARM-linux-NEXT: mrc     p15, #0, r4, c13, c0, #3
113; ARM-linux-NEXT: sub     r5, sp, #40192
114; ARM-linux-NEXT: ldr     r4, [r4, #4]
115; ARM-linux-NEXT: cmp     r4, r5
116; ARM-linux-NEXT: blo     .LBB2_2
117
118; ARM-linux:      mov     r4, #40192
119; ARM-linux-NEXT: mov     r5, #0
120; ARM-linux-NEXT: stmdb   sp!, {lr}
121; ARM-linux-NEXT: bl      __morestack
122; ARM-linux-NEXT: ldm     sp!, {lr}
123; ARM-linux-NEXT: pop     {r4, r5}
124; ARM-linux-NEXT: bx      lr
125
126; ARM-linux:      pop     {r4, r5}
127
128; ARM-android:      test_large:
129
130; ARM-android:      push    {r4, r5}
131; ARM-android-NEXT: mrc     p15, #0, r4, c13, c0, #3
132; ARM-android-NEXT: sub     r5, sp, #40192
133; ARM-android-NEXT: ldr     r4, [r4, #252]
134; ARM-android-NEXT: cmp     r4, r5
135; ARM-android-NEXT: blo     .LBB2_2
136
137; ARM-android:      mov     r4, #40192
138; ARM-android-NEXT: mov     r5, #0
139; ARM-android-NEXT: stmdb   sp!, {lr}
140; ARM-android-NEXT: bl      __morestack
141; ARM-android-NEXT: ldm     sp!, {lr}
142; ARM-android-NEXT: pop     {r4, r5}
143; ARM-android-NEXT: bx      lr
144
145; ARM-android:      pop     {r4, r5}
146
147}
148
149define fastcc void @test_fastcc() #0 {
150        %mem = alloca i32, i32 10
151        call void @dummy_use (i32* %mem, i32 10)
152        ret void
153
154; ARM-linux:      test_fastcc:
155
156; ARM-linux:      push    {r4, r5}
157; ARM-linux-NEXT: mrc     p15, #0, r4, c13, c0, #3
158; ARM-linux-NEXT: mov     r5, sp
159; ARM-linux-NEXT: ldr     r4, [r4, #4]
160; ARM-linux-NEXT: cmp     r4, r5
161; ARM-linux-NEXT: blo     .LBB3_2
162
163; ARM-linux:      mov     r4, #48
164; ARM-linux-NEXT: mov     r5, #0
165; ARM-linux-NEXT: stmdb   sp!, {lr}
166; ARM-linux-NEXT: bl      __morestack
167; ARM-linux-NEXT: ldm     sp!, {lr}
168; ARM-linux-NEXT: pop     {r4, r5}
169; ARM-linux-NEXT: bx      lr
170
171; ARM-linux:      pop     {r4, r5}
172
173; ARM-android:      test_fastcc:
174
175; ARM-android:      push    {r4, r5}
176; ARM-android-NEXT: mrc     p15, #0, r4, c13, c0, #3
177; ARM-android-NEXT: mov     r5, sp
178; ARM-android-NEXT: ldr     r4, [r4, #252]
179; ARM-android-NEXT: cmp     r4, r5
180; ARM-android-NEXT: blo     .LBB3_2
181
182; ARM-android:      mov     r4, #48
183; ARM-android-NEXT: mov     r5, #0
184; ARM-android-NEXT: stmdb   sp!, {lr}
185; ARM-android-NEXT: bl      __morestack
186; ARM-android-NEXT: ldm     sp!, {lr}
187; ARM-android-NEXT: pop     {r4, r5}
188; ARM-android-NEXT: bx      lr
189
190; ARM-android:      pop     {r4, r5}
191
192}
193
194define fastcc void @test_fastcc_large() #0 {
195        %mem = alloca i32, i32 10000
196        call void @dummy_use (i32* %mem, i32 0)
197        ret void
198
199; ARM-linux:      test_fastcc_large:
200
201; ARM-linux:      push    {r4, r5}
202; ARM-linux-NEXT: mrc     p15, #0, r4, c13, c0, #3
203; ARM-linux-NEXT: sub     r5, sp, #40192
204; ARM-linux-NEXT: ldr     r4, [r4, #4]
205; ARM-linux-NEXT: cmp     r4, r5
206; ARM-linux-NEXT: blo     .LBB4_2
207
208; ARM-linux:      mov     r4, #40192
209; ARM-linux-NEXT: mov     r5, #0
210; ARM-linux-NEXT: stmdb   sp!, {lr}
211; ARM-linux-NEXT: bl      __morestack
212; ARM-linux-NEXT: ldm     sp!, {lr}
213; ARM-linux-NEXT: pop     {r4, r5}
214; ARM-linux-NEXT: bx      lr
215
216; ARM-linux:      pop     {r4, r5}
217
218; ARM-android:      test_fastcc_large:
219
220; ARM-android:      push    {r4, r5}
221; ARM-android-NEXT: mrc     p15, #0, r4, c13, c0, #3
222; ARM-android-NEXT: sub     r5, sp, #40192
223; ARM-android-NEXT: ldr     r4, [r4, #252]
224; ARM-android-NEXT: cmp     r4, r5
225; ARM-android-NEXT: blo     .LBB4_2
226
227; ARM-android:      mov     r4, #40192
228; ARM-android-NEXT: mov     r5, #0
229; ARM-android-NEXT: stmdb   sp!, {lr}
230; ARM-android-NEXT: bl      __morestack
231; ARM-android-NEXT: ldm     sp!, {lr}
232; ARM-android-NEXT: pop     {r4, r5}
233; ARM-android-NEXT: bx      lr
234
235; ARM-android:      pop     {r4, r5}
236
237}
238
239define void @test_nostack() #0 {
240	ret void
241
242; ARM-linux-LABEL: test_nostack:
243; ARM-linux-NOT:   bl __morestack
244
245; ARM-android-LABEL: test_nostack:
246; ARM-android-NOT:   bl __morestack
247}
248
249; Test to make sure that a morestack call is generated if there is a
250; sibling call, even if the function in question has no stack frame
251; (PR37807).
252
253declare i32 @callee(i32)
254
255define i32 @test_sibling_call_empty_frame(i32 %x) #0 {
256  %call = tail call i32 @callee(i32 %x) #0
257  ret i32 %call
258
259; ARM-linux:      test_sibling_call_empty_frame:
260; ARM-linux:      bl      __morestack
261
262; ARM-android:      test_sibling_call_empty_frame:
263; ARM-android:      bl      __morestack
264
265}
266
267attributes #0 = { "split-stack" }
268