xref: /llvm-project/llvm/test/CodeGen/ARM/segmented-stacks.ll (revision 1d0ccebcd725309399262af346494242b064e2ed)
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(ptr, i32)
11
12define void @test_basic() #0 {
13        %mem = alloca i32, i32 10
14        call void @dummy_use (ptr %mem, i32 10)
15	ret void
16
17; ARM-linux-LABEL: 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: bls     .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-LABEL: 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: bls     .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(ptr nest %closure, i32 %other) #0 {
58       %addend = load i32 , ptr %closure
59       %result = add i32 %other, %addend
60       %mem = alloca i32, i32 10
61       call void @dummy_use (ptr %mem, i32 10)
62       ret i32 %result
63
64; ARM-linux-LABEL: 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: bls     .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-LABEL: 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: bls     .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 (ptr %mem, i32 0)
107        ret void
108
109; ARM-linux-LABEL: test_large:
110
111; ARM-linux:      push    {r4, r5}
112; ARM-linux-NEXT: ldr     r4, .LCPI2_0
113; ARM-linux-NEXT: sub     r5, sp, r4
114; ARM-linux-NEXT: mrc     p15, #0, r4, c13, c0, #3
115; ARM-linux-NEXT: ldr     r4, [r4, #4]
116; ARM-linux-NEXT: cmp     r4, r5
117; ARM-linux-NEXT: bls     .LBB2_2
118
119; ARM-linux:      ldr     r4, .LCPI2_0
120; ARM-linux-NEXT: mov     r5, #0
121; ARM-linux-NEXT: stmdb   sp!, {lr}
122; ARM-linux-NEXT: bl      __morestack
123; ARM-linux-NEXT: ldm     sp!, {lr}
124; ARM-linux-NEXT: pop     {r4, r5}
125; ARM-linux-NEXT: bx      lr
126
127; ARM-linux:      pop     {r4, r5}
128
129; ARM-linux:      .LCPI2_0:
130; ARM-linux-NEXT: .long   40192
131
132; ARM-android-LABEL: test_large:
133
134; ARM-android:      push    {r4, r5}
135; ARM-android-NEXT: ldr     r4, .LCPI2_0
136; ARM-android-NEXT: sub     r5, sp, r4
137; ARM-android-NEXT: mrc     p15, #0, r4, c13, c0, #3
138; ARM-android-NEXT: ldr     r4, [r4, #252]
139; ARM-android-NEXT: cmp     r4, r5
140; ARM-android-NEXT: bls     .LBB2_2
141
142; ARM-android:      ldr     r4, .LCPI2_0
143; ARM-android-NEXT: mov     r5, #0
144; ARM-android-NEXT: stmdb   sp!, {lr}
145; ARM-android-NEXT: bl      __morestack
146; ARM-android-NEXT: ldm     sp!, {lr}
147; ARM-android-NEXT: pop     {r4, r5}
148; ARM-android-NEXT: bx      lr
149
150; ARM-android:      pop     {r4, r5}
151
152; ARM-android:      .LCPI2_0:
153; ARM-android-NEXT: .long   40192
154
155}
156
157define fastcc void @test_fastcc() #0 {
158        %mem = alloca i32, i32 10
159        call void @dummy_use (ptr %mem, i32 10)
160        ret void
161
162; ARM-linux-LABEL: test_fastcc:
163
164; ARM-linux:      push    {r4, r5}
165; ARM-linux-NEXT: mrc     p15, #0, r4, c13, c0, #3
166; ARM-linux-NEXT: mov     r5, sp
167; ARM-linux-NEXT: ldr     r4, [r4, #4]
168; ARM-linux-NEXT: cmp     r4, r5
169; ARM-linux-NEXT: bls     .LBB3_2
170
171; ARM-linux:      mov     r4, #48
172; ARM-linux-NEXT: mov     r5, #0
173; ARM-linux-NEXT: stmdb   sp!, {lr}
174; ARM-linux-NEXT: bl      __morestack
175; ARM-linux-NEXT: ldm     sp!, {lr}
176; ARM-linux-NEXT: pop     {r4, r5}
177; ARM-linux-NEXT: bx      lr
178
179; ARM-linux:      pop     {r4, r5}
180
181; ARM-android-LABEL: test_fastcc:
182
183; ARM-android:      push    {r4, r5}
184; ARM-android-NEXT: mrc     p15, #0, r4, c13, c0, #3
185; ARM-android-NEXT: mov     r5, sp
186; ARM-android-NEXT: ldr     r4, [r4, #252]
187; ARM-android-NEXT: cmp     r4, r5
188; ARM-android-NEXT: bls     .LBB3_2
189
190; ARM-android:      mov     r4, #48
191; ARM-android-NEXT: mov     r5, #0
192; ARM-android-NEXT: stmdb   sp!, {lr}
193; ARM-android-NEXT: bl      __morestack
194; ARM-android-NEXT: ldm     sp!, {lr}
195; ARM-android-NEXT: pop     {r4, r5}
196; ARM-android-NEXT: bx      lr
197
198; ARM-android:      pop     {r4, r5}
199
200}
201
202define fastcc void @test_fastcc_large() #0 {
203        %mem = alloca i32, i32 10000
204        call void @dummy_use (ptr %mem, i32 0)
205        ret void
206
207; ARM-linux-LABEL: test_fastcc_large:
208
209; ARM-linux:      push    {r4, r5}
210; ARM-linux-NEXT: ldr     r4, .LCPI4_0
211; ARM-linux-NEXT: sub     r5, sp, r4
212; ARM-linux-NEXT: mrc     p15, #0, r4, c13, c0, #3
213; ARM-linux-NEXT: ldr     r4, [r4, #4]
214; ARM-linux-NEXT: cmp     r4, r5
215; ARM-linux-NEXT: bls     .LBB4_2
216
217; ARM-linux:      ldr     r4, .LCPI4_0
218; ARM-linux-NEXT: mov     r5, #0
219; ARM-linux-NEXT: stmdb   sp!, {lr}
220; ARM-linux-NEXT: bl      __morestack
221; ARM-linux-NEXT: ldm     sp!, {lr}
222; ARM-linux-NEXT: pop     {r4, r5}
223; ARM-linux-NEXT: bx      lr
224
225; ARM-linux:      pop     {r4, r5}
226
227; ARM-linux:      .LCPI4_0:
228; ARM-linux-NEXT: .long   40192
229
230; ARM-android-LABEL: test_fastcc_large:
231
232; ARM-android:      push    {r4, r5}
233; ARM-android-NEXT: ldr     r4, .LCPI4_0
234; ARM-android-NEXT: sub     r5, sp, r4
235; ARM-android-NEXT: mrc     p15, #0, r4, c13, c0, #3
236; ARM-android-NEXT: ldr     r4, [r4, #252]
237; ARM-android-NEXT: cmp     r4, r5
238; ARM-android-NEXT: bls     .LBB4_2
239
240; ARM-android:      ldr     r4, .LCPI4_0
241; ARM-android-NEXT: mov     r5, #0
242; ARM-android-NEXT: stmdb   sp!, {lr}
243; ARM-android-NEXT: bl      __morestack
244; ARM-android-NEXT: ldm     sp!, {lr}
245; ARM-android-NEXT: pop     {r4, r5}
246; ARM-android-NEXT: bx      lr
247
248; ARM-android:      pop     {r4, r5}
249
250; ARM-android:      .LCPI4_0:
251; ARM-android-NEXT: .long   40192
252
253}
254
255define void @test_nostack() #0 {
256	ret void
257
258; ARM-linux-LABEL: test_nostack:
259; ARM-linux-NOT:   bl __morestack
260
261; ARM-android-LABEL: test_nostack:
262; ARM-android-NOT:   bl __morestack
263}
264
265; Test to make sure that a morestack call is generated if there is a
266; sibling call, even if the function in question has no stack frame
267; (PR37807).
268
269declare i32 @callee(i32)
270
271define i32 @test_sibling_call_empty_frame(i32 %x) #0 {
272  %call = tail call i32 @callee(i32 %x) #0
273  ret i32 %call
274
275; ARM-linux-LABEL: test_sibling_call_empty_frame:
276; ARM-linux:      bl      __morestack
277
278; ARM-android-LABEL: test_sibling_call_empty_frame:
279; ARM-android:      bl      __morestack
280
281}
282
283
284declare void @panic() unnamed_addr
285
286; We used to crash while compiling the following function.
287; ARM-linux-LABEL: build_should_not_segfault:
288; ARM-android-LABEL: build_should_not_segfault:
289define void @build_should_not_segfault(i8 %x) unnamed_addr #0 {
290start:
291  %_0 = icmp ult i8 %x, 16
292  %or.cond = select i1 undef, i1 true, i1 %_0
293  br i1 %or.cond, label %bb1, label %bb2
294
295bb1:
296  ret void
297
298bb2:
299  call void @panic()
300  unreachable
301}
302
303attributes #0 = { "split-stack" }
304