• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 bitcast (i32 (...)* @bar0 to i32 ()*)() #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 bitcast (i32 (...)* @bar1 to i32 (i32*)*)(i32* %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 bitcast (i32 (...)* @bar1 to i32 (i32*)*)(i32* %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  %t1 = getelementptr [16384 x i32], [16384 x i32]* %t0, i32 0, i32 0
72  %t2 = tail call i32 bitcast (i32 (...)* @bar1 to i32 (i32*)*)(i32* %t1) #0
73  ret i32 %t2
74}
75
76; Combinations.
77
78; CHECK-LABEL: test_ad:
79; CHECK-NOT: stw {{[0-9]+}}, -{{[0-9]+}}(1)
80; CHECK: stwux 1, 1, {{[0-9]+}}
81; CHECK: mr 1, {{[0-9]+}}
82; CHECK-NOT: lwz {{[0-9]+}}, -{{[0-9]+}}(1)
83define i32 @test_ad(i32 %p0) local_unnamed_addr #0 {
84  %t0 = alloca i32, align 128
85  %t1 = alloca i32, i32 %p0, align 4
86  %t2 = tail call i32 bitcast (i32 (...)* @bar1 to i32 (i32*)*)(i32* %t0) #0
87  %t3 = tail call i32 bitcast (i32 (...)* @bar1 to i32 (i32*)*)(i32* %t1) #0
88  %t4 = add i32 %t2, %t3
89  ret i32 %t4
90}
91
92; CHECK-LABEL: test_as:
93; CHECK-NOT: stw {{[0-9]+}}, -{{[0-9]+}}(1)
94; CHECK: stwux 1, 1, {{[0-9]+}}
95; CHECK: mr 1, {{[0-9]+}}
96; CHECK-NOT: lwz {{[0-9]+}}, -{{[0-9]+}}(1)
97define i32 @test_as() local_unnamed_addr #0 {
98  %t0 = alloca i32, align 128
99  %t1 = alloca [16384 x i32]
100  %t2 = tail call i32 bitcast (i32 (...)* @bar1 to i32 (i32*)*)(i32* %t0) #0
101  %t3 = getelementptr [16384 x i32], [16384 x i32]* %t1, i32 0, i32 0
102  %t4 = tail call i32 bitcast (i32 (...)* @bar1 to i32 (i32*)*)(i32* %t3) #0
103  %t5 = add i32 %t2, %t4
104  ret i32 %t5
105}
106
107; CHECK-LABEL: test_ds:
108; CHECK-NOT: stw {{[0-9]+}}, -{{[0-9]+}}(1)
109; CHECK: stwux 1, 1, {{[0-9]+}}
110; CHECK: mr 1, {{[0-9]+}}
111; CHECK-NOT: lwz {{[0-9]+}}, -{{[0-9]+}}(1)
112define i32 @test_ds(i32 %p0) local_unnamed_addr #0 {
113  %t0 = alloca i32, i32 %p0, align 4
114  %t1 = alloca [16384 x i32]
115  %t2 = tail call i32 bitcast (i32 (...)* @bar1 to i32 (i32*)*)(i32* %t0) #0
116  %t3 = getelementptr [16384 x i32], [16384 x i32]* %t1, i32 0, i32 0
117  %t4 = tail call i32 bitcast (i32 (...)* @bar1 to i32 (i32*)*)(i32* %t3) #0
118  %t5 = add i32 %t2, %t4
119  ret i32 %t5
120}
121
122; CHECK-LABEL: test_ads:
123; CHECK-NOT: stw {{[0-9]+}}, -{{[0-9]+}}(1)
124; CHECK: stwux 1, 1, {{[0-9]+}}
125; CHECK: mr 1, {{[0-9]+}}
126; CHECK-NOT: lwz {{[0-9]+}}, -{{[0-9]+}}(1)
127define i32 @test_ads(i32 %p0) local_unnamed_addr #0 {
128  %t0 = alloca i32, align 128
129  %t1 = alloca i32, i32 %p0, align 4
130  %t2 = alloca [16384 x i32]
131
132  %t3 = tail call i32 bitcast (i32 (...)* @bar1 to i32 (i32*)*)(i32* %t0) #0
133  %t4 = tail call i32 bitcast (i32 (...)* @bar1 to i32 (i32*)*)(i32* %t1) #0
134  %t5 = add i32 %t3, %t4
135
136  %t6 = getelementptr [16384 x i32], [16384 x i32]* %t2, i32 0, i32 0
137  %t7 = tail call i32 bitcast (i32 (...)* @bar1 to i32 (i32*)*)(i32* %t6) #0
138  %t8 = add i32 %t5, %t7
139  ret i32 %t7
140}
141
142
143declare i32 @bar0(...) local_unnamed_addr #0
144declare i32 @bar1(...) local_unnamed_addr #0
145
146attributes #0 = { nounwind }
147