1; RUN: llc -mtriple=powerpc64-unknown-linux-gnu -mcpu=pwr7 < %s | FileCheck %s
2; RUN: llc -mtriple=powerpc64-unknown-linux-gnu -mcpu=pwr7 -frame-pointer=all < %s | FileCheck -check-prefix=CHECK-FP %s
3; RUN: llc -mtriple=powerpc-unknown-linux-gnu -frame-pointer=all < %s | FileCheck -check-prefix=CHECK-32 %s
4; RUN: llc -mtriple=powerpc-unknown-linux-gnu -frame-pointer=all -relocation-model=pic < %s | FileCheck -check-prefix=CHECK-32-PIC %s
5target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-v128:128:128-n32:64"
6target triple = "powerpc64-unknown-linux-gnu"
7
8%struct.s = type { i32, i32 }
9
10declare void @bar(i32*)
11
12@barbaz = external global i32
13
14define void @goo(%struct.s* byval(%struct.s) nocapture readonly %a) {
15entry:
16  %x = alloca [2 x i32], align 32
17  %a1 = getelementptr inbounds %struct.s, %struct.s* %a, i64 0, i32 0
18  %0 = load i32, i32* %a1, align 4
19  %arrayidx = getelementptr inbounds [2 x i32], [2 x i32]* %x, i64 0, i64 0
20  store i32 %0, i32* %arrayidx, align 32
21  %b = getelementptr inbounds %struct.s, %struct.s* %a, i64 0, i32 1
22  %1 = load i32, i32* %b, align 4
23  %2 = load i32, i32* @barbaz, align 4
24  %arrayidx2 = getelementptr inbounds [2 x i32], [2 x i32]* %x, i64 0, i64 1
25  store i32 %2, i32* %arrayidx2, align 4
26  call void @bar(i32* %arrayidx)
27  ret void
28}
29
30; CHECK-LABEL: @goo
31
32; CHECK-DAG: mflr {{[0-9]+}}
33; CHECK-DAG: clrldi [[REG:[0-9]+]], 1, 59
34; CHECK-DAG: std 30, -16(1)
35; CHECK-DAG: mr 30, 1
36; CHECK-DAG: std 0, 16(1)
37; CHECK-DAG: subfic 0, [[REG]], -160
38; CHECK: stdux 1, 1, 0
39
40; CHECK: .cfi_def_cfa_register r30
41; CHECK: .cfi_offset r30, -16
42; CHECK: .cfi_offset lr, 16
43
44; CHECK: std 3, 48(30)
45
46; CHECK: mr 1, 30
47; CHECK-DAG: ld [[SR:[0-9]+]], 16(1)
48; CHECK-DAG: ld 30, -16(1)
49; CHECK-DAG: mtlr [[SR]]
50; CHECK: blr
51
52; CHECK-FP-LABEL: @goo
53
54; CHECK-FP-DAG: mflr {{[0-9]+}}
55; CHECK-FP-DAG: clrldi [[REG:[0-9]+]], 1, 59
56; CHECK-FP-DAG: std 31, -8(1)
57; CHECK-FP-DAG: std 30, -16(1)
58; CHECK-FP-DAG: mr 30, 1
59; CHECK-FP-DAG: std 0, 16(1)
60; CHECK-FP-DAG: subfic 0, [[REG]], -160
61; CHECK-FP: stdux 1, 1, 0
62
63; CHECK-FP: .cfi_def_cfa_register r30
64; CHECK-FP: .cfi_offset r31, -8
65; CHECK-FP: .cfi_offset r30, -16
66; CHECK-FP: .cfi_offset lr, 16
67
68; CHECK-FP: mr 31, 1
69
70; CHECK-FP: std 3, 48(30)
71
72; CHECK-FP: mr 1, 30
73; CHECK-FP-DAG: ld [[SR:[0-9]+]], 16(1)
74; CHECK-FP-DAG: ld 31, -8(1)
75; CHECK-FP-DAG: ld 30, -16(1)
76; CHECK-FP-DAG: mtlr [[SR]]
77; CHECK-FP: blr
78
79; CHECK-32-LABEL: @goo
80; CHECK-32-DAG: mflr [[LR:[0-9]+]]
81; CHECK-32-DAG: clrlwi [[REG:[0-9]+]], 1, 27
82; CHECK-32-DAG: stw [[LR]], 4(1)
83; CHECK-32-DAG: subfic 0, [[REG]], -64
84; CHECK-32: stwux 1, 1, 0
85; CHECK-32: sub 0, 1, 0
86; CHECK-32: addic 0, 0, -4
87; CHECK-32: stwx 31, 0, 0
88; CHECK-32: addic 0, 0, -4
89; CHECK-32: stwx 30, 0, 0
90; CHECK-32: addic 30, 0, 8
91
92; CHECK-32-PIC-LABEL: @goo
93; CHECK-32-PIC-DAG: mflr [[LR:[0-9]+]]
94; CHECK-32-PIC-DAG: clrlwi [[REG:[0-9]+]], 1, 27
95; CHECK-32-PIC-DAG: stw [[LR]], 4(1)
96; CHECK-32-PIC-DAG: subfic 0, [[REG]], -64
97; CHECK-32-PIC:     stwux 1, 1, 0
98; CHECK-32-PIC:     sub 0, 1, 0
99; CHECK-32-PIC:     addic 0, 0, -4
100; CHECK-32-PIC:     stwx 31, 0, 0
101; CHECK-32-PIC:     addic 0, 0, -4
102; CHECK-32-PIC:     stwx 30, 0, 0
103; CHECK-32-PIC:     addic 0, 0, -4
104; CHECK-32-PIC:     stwx 29, 0, 0
105; CHECK-32-PIC:     addic 29, 0, 12
106
107; The large-frame-size case.
108define void @hoo(%struct.s* byval(%struct.s) nocapture readonly %a) {
109entry:
110  %x = alloca [200000 x i32], align 32
111  %a1 = getelementptr inbounds %struct.s, %struct.s* %a, i64 0, i32 0
112  %0 = load i32, i32* %a1, align 4
113  %arrayidx = getelementptr inbounds [200000 x i32], [200000 x i32]* %x, i64 0, i64 0
114  store i32 %0, i32* %arrayidx, align 32
115  %b = getelementptr inbounds %struct.s, %struct.s* %a, i64 0, i32 1
116  %1 = load i32, i32* %b, align 4
117  %arrayidx2 = getelementptr inbounds [200000 x i32], [200000 x i32]* %x, i64 0, i64 1
118  store i32 %1, i32* %arrayidx2, align 4
119  call void @bar(i32* %arrayidx)
120  ret void
121}
122
123; CHECK-LABEL: @hoo
124
125; CHECK-DAG: lis [[REG1:[0-9]+]], -13
126; CHECK-DAG: clrldi [[REG3:[0-9]+]], 1, 59
127; CHECK-DAG: mflr {{[0-9]+}}
128; CHECK-DAG: ori [[REG2:[0-9]+]], [[REG1]], 51808
129; CHECK-DAG: std 30, -16(1)
130; CHECK-DAG: mr 30, 1
131; CHECK-DAG: std 0, 16(1)
132; CHECK-DAG: subc 0, [[REG2]], [[REG3]]
133; CHECK: stdux 1, 1, 0
134
135; CHECK: .cfi_def_cfa_register r30
136
137; CHECK: blr
138
139; CHECK-32-LABEL: @hoo
140
141; CHECK-32-DAG: lis [[REG1:[0-9]+]], -13
142; CHECK-32-DAG: clrlwi [[REG3:[0-9]+]], 1, 27
143; CHECK-32-DAG: mflr [[LR:[0-9]+]]
144; CHECK-32-DAG: ori [[REG2:[0-9]+]], [[REG1]], 51904
145; CHECK-32-DAG: stw [[LR]], 4(1)
146; CHECK-32-DAG: subc 0, [[REG2]], [[REG3]]
147; CHECK-32:     stwux 1, 1, 0
148; CHECK-32:     sub 0, 1, 0
149; CHECK-32:     addic 0, 0, -4
150; CHECK-32:     stwx 31, 0, 0
151; CHECK-32:     addic 0, 0, -4
152; CHECK-32:     stwx 30, 0, 0
153; CHECK-32:     addic 30, 0, 8
154
155; CHECK-32: blr
156
157; CHECK-32-PIC-LABEL: @hoo
158
159; CHECK-32-PIC-DAG: lis [[REG1:[0-9]+]], -13
160; CHECK-32-PIC-DAG: clrlwi [[REG3:[0-9]+]], 1, 27
161; CHECK-32-PIC-DAG: mflr {{[0-9]+}}
162; CHECK-32-PIC-DAG: ori [[REG2:[0-9]+]], [[REG1]], 51904
163; CHECK-32-PIC-DAG: stw 0, 4(1)
164; CHECK-32-PIC-DAG: subc 0, [[REG2]], [[REG3]]
165; CHECK-32-PIC:     stwux 1, 1, 0
166; CHECK-32-PIC:     sub 0, 1, 0
167; CHECK-32-PIC:     addic 0, 0, -4
168; CHECK-32-PIC:     stwx 31, 0, 0
169; CHECK-32-PIC:     addic 0, 0, -8
170; CHECK-32-PIC:     stwx 29, 0, 0
171; CHECK-32-PIC:     addic 29, 0, 12
172
173; CHECK-32: blr
174
175; Make sure that the FP save area is still allocated correctly relative to
176; where r30 is saved.
177define void @loo(%struct.s* byval(%struct.s) nocapture readonly %a) {
178entry:
179  %x = alloca [2 x i32], align 32
180  %a1 = getelementptr inbounds %struct.s, %struct.s* %a, i64 0, i32 0
181  %0 = load i32, i32* %a1, align 4
182  %arrayidx = getelementptr inbounds [2 x i32], [2 x i32]* %x, i64 0, i64 0
183  store i32 %0, i32* %arrayidx, align 32
184  %b = getelementptr inbounds %struct.s, %struct.s* %a, i64 0, i32 1
185  %1 = load i32, i32* %b, align 4
186  %arrayidx2 = getelementptr inbounds [2 x i32], [2 x i32]* %x, i64 0, i64 1
187  store i32 %1, i32* %arrayidx2, align 4
188  call void @bar(i32* %arrayidx)
189  call void asm sideeffect "", "~{f30}"() nounwind
190  ret void
191}
192
193; CHECK-LABEL: @loo
194
195; CHECK-DAG: mflr {{[0-9]+}}
196; CHECK-DAG: clrldi [[REG:[0-9]+]], 1, 59
197; CHECK-DAG: std 30, -32(1)
198; CHECK-DAG: mr 30, 1
199; CHECK-DAG: std 0, 16(1)
200; CHECK-DAG: subfic 0, [[REG]], -192
201; CHECK: stdux 1, 1, 0
202
203; CHECK: .cfi_def_cfa_register r30
204
205; CHECK: stfd 30, -16(30)
206
207; CHECK: blr
208
209; CHECK-FP-LABEL: @loo
210
211; CHECK-FP-DAG: mflr {{[0-9]+}}
212; CHECK-FP-DAG: clrldi [[REG:[0-9]+]], 1, 59
213; CHECK-FP-DAG: std 31, -24(1)
214; CHECK-FP-DAG: std 30, -32(1)
215; CHECK-FP-DAG: mr 30, 1
216; CHECK-FP-DAG: std 0, 16(1)
217; CHECK-FP-DAG: subfic 0, [[REG]], -192
218; CHECK-FP: stdux 1, 1, 0
219
220; CHECK-FP: .cfi_def_cfa_register r30
221
222; CHECK-FP: stfd 30, -16(30)
223
224; CHECK-FP: blr
225