xref: /llvm-project/llvm/test/CodeGen/Thumb/large-stack.ll (revision 2d9c6e699a09d1363e435e6692508dd290984a00)
1; RUN: llc < %s -mtriple=thumb-apple-ios | FileCheck %s --check-prefix=CHECK
2; RUN: llc < %s -mtriple=thumb-none-eabi | FileCheck %s --check-prefix=CHECK
3; RUN: llc < %s -o %t -filetype=obj -mtriple=thumbv6-apple-ios
4; RUN: llvm-objdump --no-print-imm-hex --triple=thumbv6-apple-ios -d %t | FileCheck %s --check-prefix=CHECK
5; RUN: llc < %s -o %t -filetype=obj -mtriple=thumbv6-none-eabi
6; RUN: llvm-objdump --no-print-imm-hex --triple=thumbv6-none-eabi -d %t | FileCheck %s --check-prefix=CHECK
7
8; Largest stack for which a single tADDspi/tSUBspi is enough
9define void @test1() {
10; CHECK-LABEL: test1{{>?}}:
11; CHECK: sub sp, #508
12; CHECK: add sp, #508
13    %tmp = alloca [ 508 x i8 ] , align 4
14    ret void
15}
16
17; Largest stack for which three tADDspi/tSUBspis are enough
18define void @test100() {
19; CHECK-LABEL: test100{{>?}}:
20; CHECK: sub sp, #508
21; CHECK: sub sp, #508
22; CHECK: sub sp, #508
23; CHECK: add sp, #508
24; CHECK: add sp, #508
25; CHECK: add sp, #508
26    %tmp = alloca [ 1524 x i8 ] , align 4
27    ret void
28}
29
30; Largest stack for which three tADDspi/tSUBspis are enough
31define void @test100_nofpelim() "frame-pointer"="all" {
32; CHECK-LABEL: test100_nofpelim{{>?}}:
33; CHECK: sub sp, #508
34; CHECK: sub sp, #508
35; CHECK: sub sp, #508
36; CHECK: subs [[SCRATCH:r[0-7]]], r7, #7
37; CHECK: subs [[SCRATCH]], #1
38; CHECK: mov sp, [[SCRATCH]]
39; CHECK: pop
40; CHECK-SAME: [[SCRATCH]]
41    %tmp = alloca [ 1524 x i8 ] , align 4
42    ret void
43}
44
45; Smallest stack for which we use a constant pool
46define void @test2() {
47; CHECK-LABEL: test2{{>?}}:
48; CHECK: ldr [[TEMP:r[0-7]]],
49; CHECK: add sp, [[TEMP]]
50; CHECK: ldr [[TEMP:r[0-7]]],
51; CHECK: add sp, [[TEMP]]
52    %tmp = alloca [ 1528 x i8 ] , align 4
53    ret void
54}
55
56; Smallest stack for which we use a constant pool
57define void @test2_nofpelim() "frame-pointer"="all" {
58; CHECK-LABEL: test2_nofpelim{{>?}}:
59; CHECK: ldr [[TEMP:r[0-7]]],
60; CHECK: add sp, [[TEMP]]
61; CHECK: subs [[SCRATCH:r[0-7]]], r7, #7
62; CHECK: subs [[SCRATCH]], #1
63; CHECK: mov sp, [[SCRATCH]]
64; CHECK: pop
65; CHECK-SAME: [[SCRATCH]]
66    %tmp = alloca [ 1528 x i8 ] , align 4
67    ret void
68}
69
70define i32 @test3() {
71; CHECK-LABEL: test3{{>?}}:
72; CHECK: ldr [[TEMP:r[0-7]]],
73; CHECK: add sp, [[TEMP]]
74; CHECK: ldr [[TEMP2:r[0-7]]],
75; CHECK: add [[TEMP2]], sp
76; CHECK: ldr [[TEMP3:r[0-7]]],
77; CHECK: add sp, [[TEMP3]]
78    %retval = alloca i32, align 4
79    %tmp = alloca i32, align 4
80    %a = alloca [805306369 x i8], align 4
81    store i32 0, ptr %tmp
82    %tmp1 = load i32, ptr %tmp
83    ret i32 %tmp1
84}
85
86define i32 @test3_nofpelim() "frame-pointer"="all" {
87; CHECK-LABEL: test3_nofpelim{{>?}}:
88; CHECK: ldr [[TEMP:r[0-7]]],
89; CHECK: add sp, [[TEMP]]
90; CHECK: ldr [[TEMP2:r[0-7]]],
91; CHECK: add [[TEMP2]], sp
92; CHECK: subs [[SCRATCH:r[0-7]]], r7,
93; CHECK: mov sp, [[SCRATCH]]
94; CHECK: pop
95; CHECK-SAME: [[SCRATCH]]
96    %retval = alloca i32, align 4
97    %tmp = alloca i32, align 4
98    %a = alloca [805306369 x i8], align 8
99    store i32 0, ptr %tmp
100    %tmp1 = load i32, ptr %tmp
101    ret i32 %tmp1
102}
103
104; Here, the adds get optimized out because they are dead, but the calculation
105; of the address of stack_a is dead but not optimized out. When the address
106; calculation gets expanded to two instructions, we need to avoid reading a
107; dead register.
108; No CHECK lines (just test for crashes), as we hope this will be optimised
109; better in future.
110define i32 @test4() {
111entry:
112  %stack_a = alloca i8, align 1
113  %stack_b = alloca [256 x ptr], align 4
114  %int = ptrtoint ptr %stack_a to i32
115  %add = add i32 %int, 1
116  br label %block2
117
118block2:
119  %add2 = add i32 %add, 1
120  ret i32 0
121}
122