xref: /llvm-project/llvm/test/CodeGen/PowerPC/stack-no-redzone.ll (revision 5403c59c608c08c8ecd4303763f08eb046eb5e4d)
1; Test that accesses of the stack remain within the range defined by R1,
2; i.e. that loads and stores only access the allocated stack. This does not
3; have to be the case when red zone is present.
4
5; Make sure that there is no red zone, i.e. ppc32 and SVR4 ABI.
6; RUN: llc -mtriple=powerpc--freebsd-elf < %s | FileCheck %s
7
8; There are two ways that the stack pointer can be adjusted in the prologue:
9; - by adding an immediate value:
10;     stwu r1, -imm(r1)
11; - by adding another register:
12;     stwux r1, rx, r1
13;
14; The restoring of the stack pointer can be done:
15; - by adding an immediate value to it:
16;     addi r1, r1, imm
17; - by copying the value from another register:
18;     mr r1, rx
19
20
21; Nothing (no special features).
22;
23; CHECK-LABEL: test_n:
24; CHECK-NOT: stw {{[0-9]+}}, -{{[0-9]+}}(1)
25; CHECK: stwu 1, -[[SIZE:[0-9]+]](1)
26; CHECK: addi 1, 1, [[SIZE]]
27; CHECK-NOT: lwz {{[0-9]+}}, -{{[0-9]+}}(1)
28define i32 @test_n() local_unnamed_addr #0 {
29entry:
30  %t0 = tail call i32 @bar0() #0
31  ret i32 %t0
32}
33
34; Aligned object on the stack.
35;
36; CHECK-LABEL: test_a:
37; CHECK-NOT: stw {{[0-9]+}}, -{{[0-9]+}}(1)
38; CHECK: stwux 1, 1, {{[0-9]+}}
39; CHECK: mr 1, {{[0-9]+}}
40; CHECK-NOT: lwz {{[0-9]+}}, -{{[0-9]+}}(1)
41
42define i32 @test_a() local_unnamed_addr #0 {
43entry:
44  %t0 = alloca i32, align 128
45  %t1 = tail call i32 @bar1(ptr %t0) #0
46  ret i32 %t1
47}
48
49; Dynamic allocation on the stack.
50;
51; CHECK-LABEL: test_d:
52; CHECK-NOT: stw {{[0-9]+}}, -{{[0-9]+}}(1)
53; CHECK: stwu 1, -[[SIZE:[0-9]+]](1)
54; CHECK: mr 1, {{[0-9]+}}
55; CHECK-NOT: lwz {{[0-9]+}}, -{{[0-9]+}}(1)
56define i32 @test_d(i32 %p0) local_unnamed_addr #0 {
57  %t0 = alloca i32, i32 %p0, align 4
58  %t1 = tail call i32 @bar1(ptr %t0) #0
59  ret i32 %t1
60}
61
62; Large stack (exceeds size of D-field).
63; CHECK-LABEL: test_s:
64; CHECK-NOT: stw {{[0-9]+}}, -{{[0-9]+}}(1)
65; CHECK: stwux 1, 1, {{[0-9]+}}
66; CHECK: mr 1, {{[0-9]+}}
67; CHECK-NOT: lwz {{[0-9]+}}, -{{[0-9]+}}(1)
68define i32 @test_s(i32 %p0) local_unnamed_addr #0 {
69entry:
70  %t0 = alloca [16384 x i32]
71  %t2 = tail call i32 @bar1(ptr %t0) #0
72  ret i32 %t2
73}
74
75; Combinations.
76
77; CHECK-LABEL: test_ad:
78; CHECK-NOT: stw {{[0-9]+}}, -{{[0-9]+}}(1)
79; CHECK: stwux 1, 1, {{[0-9]+}}
80; CHECK: mr 1, {{[0-9]+}}
81; CHECK-NOT: lwz {{[0-9]+}}, -{{[0-9]+}}(1)
82define i32 @test_ad(i32 %p0) local_unnamed_addr #0 {
83  %t0 = alloca i32, align 128
84  %t1 = alloca i32, i32 %p0, align 4
85  %t2 = tail call i32 @bar1(ptr %t0) #0
86  %t3 = tail call i32 @bar1(ptr %t1) #0
87  %t4 = add i32 %t2, %t3
88  ret i32 %t4
89}
90
91; CHECK-LABEL: test_as:
92; CHECK-NOT: stw {{[0-9]+}}, -{{[0-9]+}}(1)
93; CHECK: stwux 1, 1, {{[0-9]+}}
94; CHECK: mr 1, {{[0-9]+}}
95; CHECK-NOT: lwz {{[0-9]+}}, -{{[0-9]+}}(1)
96define i32 @test_as() local_unnamed_addr #0 {
97  %t0 = alloca i32, align 128
98  %t1 = alloca [16384 x i32]
99  %t2 = tail call i32 @bar1(ptr %t0) #0
100  %t4 = tail call i32 @bar1(ptr %t1) #0
101  %t5 = add i32 %t2, %t4
102  ret i32 %t5
103}
104
105; CHECK-LABEL: test_ds:
106; CHECK-NOT: stw {{[0-9]+}}, -{{[0-9]+}}(1)
107; CHECK: stwux 1, 1, {{[0-9]+}}
108; CHECK: mr 1, {{[0-9]+}}
109; CHECK-NOT: lwz {{[0-9]+}}, -{{[0-9]+}}(1)
110define i32 @test_ds(i32 %p0) local_unnamed_addr #0 {
111  %t0 = alloca i32, i32 %p0, align 4
112  %t1 = alloca [16384 x i32]
113  %t2 = tail call i32 @bar1(ptr %t0) #0
114  %t4 = tail call i32 @bar1(ptr %t1) #0
115  %t5 = add i32 %t2, %t4
116  ret i32 %t5
117}
118
119; CHECK-LABEL: test_ads:
120; CHECK-NOT: stw {{[0-9]+}}, -{{[0-9]+}}(1)
121; CHECK: stwux 1, 1, {{[0-9]+}}
122; CHECK: mr 1, {{[0-9]+}}
123; CHECK-NOT: lwz {{[0-9]+}}, -{{[0-9]+}}(1)
124define i32 @test_ads(i32 %p0) local_unnamed_addr #0 {
125  %t0 = alloca i32, align 128
126  %t1 = alloca i32, i32 %p0, align 4
127  %t2 = alloca [16384 x i32]
128
129  %t3 = tail call i32 @bar1(ptr %t0) #0
130  %t4 = tail call i32 @bar1(ptr %t1) #0
131  %t5 = add i32 %t3, %t4
132
133  %t7 = tail call i32 @bar1(ptr %t2) #0
134  %t8 = add i32 %t5, %t7
135  ret i32 %t7
136}
137
138
139declare i32 @bar0(...) local_unnamed_addr #0
140declare i32 @bar1(...) local_unnamed_addr #0
141
142attributes #0 = { nounwind }
143