xref: /llvm-project/llvm/test/CodeGen/SystemZ/frame-08.ll (revision a1710eb3cd5823c5d14899112ca3086acbdbe9cb)
1; Test the saving and restoring of GPRs in large frames.
2;
3; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
4
5; This is the largest frame size that can use a plain LMG for %r6 and above.
6; It is big enough to require two emergency spill slots at 160(%r15),
7; so get a frame of size 524232 by allocating (524232 - 176) / 8 = 65507
8; extra doublewords.
9define void @f1(ptr %ptr, i64 %x) {
10; CHECK-LABEL: f1:
11; CHECK: stmg %r6, %r15, 48(%r15)
12; CHECK: .cfi_offset %r6, -112
13; CHECK: .cfi_offset %r7, -104
14; CHECK: .cfi_offset %r8, -96
15; CHECK: .cfi_offset %r9, -88
16; CHECK: .cfi_offset %r10, -80
17; CHECK: .cfi_offset %r11, -72
18; CHECK: .cfi_offset %r12, -64
19; CHECK: .cfi_offset %r13, -56
20; CHECK: .cfi_offset %r14, -48
21; CHECK: .cfi_offset %r15, -40
22; CHECK: agfi %r15, -524232
23; CHECK: .cfi_def_cfa_offset 524392
24; ...main function body...
25; CHECK-NOT: ag
26; CHECK: lmg %r6, %r15, 524280(%r15)
27; CHECK: br %r14
28  %l0 = load volatile i32, ptr %ptr
29  %l1 = load volatile i32, ptr %ptr
30  %l4 = load volatile i32, ptr %ptr
31  %l5 = load volatile i32, ptr %ptr
32  %l6 = load volatile i32, ptr %ptr
33  %l7 = load volatile i32, ptr %ptr
34  %l8 = load volatile i32, ptr %ptr
35  %l9 = load volatile i32, ptr %ptr
36  %l10 = load volatile i32, ptr %ptr
37  %l11 = load volatile i32, ptr %ptr
38  %l12 = load volatile i32, ptr %ptr
39  %l13 = load volatile i32, ptr %ptr
40  %l14 = load volatile i32, ptr %ptr
41  %add0 = add i32 %l0, %l0
42  %add1 = add i32 %l1, %add0
43  %add4 = add i32 %l4, %add1
44  %add5 = add i32 %l5, %add4
45  %add6 = add i32 %l6, %add5
46  %add7 = add i32 %l7, %add6
47  %add8 = add i32 %l8, %add7
48  %add9 = add i32 %l9, %add8
49  %add10 = add i32 %l10, %add9
50  %add11 = add i32 %l11, %add10
51  %add12 = add i32 %l12, %add11
52  %add13 = add i32 %l13, %add12
53  %add14 = add i32 %l14, %add13
54  store volatile i32 %add0, ptr %ptr
55  store volatile i32 %add1, ptr %ptr
56  store volatile i32 %add4, ptr %ptr
57  store volatile i32 %add5, ptr %ptr
58  store volatile i32 %add6, ptr %ptr
59  store volatile i32 %add7, ptr %ptr
60  store volatile i32 %add8, ptr %ptr
61  store volatile i32 %add9, ptr %ptr
62  store volatile i32 %add10, ptr %ptr
63  store volatile i32 %add11, ptr %ptr
64  store volatile i32 %add12, ptr %ptr
65  store volatile i32 %add13, ptr %ptr
66  store volatile i32 %add14, ptr %ptr
67  %y = alloca [65507 x i64], align 8
68  store volatile i64 %x, ptr %y
69  ret void
70}
71
72; This is the largest frame size that can use a plain LMG for %r14 and above
73; It is big enough to require two emergency spill slots at 160(%r15),
74; so get a frame of size 524168 by allocating (524168 - 176) / 8 = 65499
75; extra doublewords.
76define void @f2(ptr %ptr, i64 %x) {
77; CHECK-LABEL: f2:
78; CHECK: stmg %r14, %r15, 112(%r15)
79; CHECK: .cfi_offset %r14, -48
80; CHECK: .cfi_offset %r15, -40
81; CHECK: agfi %r15, -524168
82; CHECK: .cfi_def_cfa_offset 524328
83; ...main function body...
84; CHECK-NOT: ag
85; CHECK: lmg %r14, %r15, 524280(%r15)
86; CHECK: br %r14
87  %l0 = load volatile i32, ptr %ptr
88  %l1 = load volatile i32, ptr %ptr
89  %l4 = load volatile i32, ptr %ptr
90  %l5 = load volatile i32, ptr %ptr
91  %l14 = load volatile i32, ptr %ptr
92  %add0 = add i32 %l0, %l0
93  %add1 = add i32 %l1, %add0
94  %add4 = add i32 %l4, %add1
95  %add5 = add i32 %l5, %add4
96  %add14 = add i32 %l14, %add5
97  store volatile i32 %add0, ptr %ptr
98  store volatile i32 %add1, ptr %ptr
99  store volatile i32 %add4, ptr %ptr
100  store volatile i32 %add5, ptr %ptr
101  store volatile i32 %add14, ptr %ptr
102  %y = alloca [65499 x i64], align 8
103  store volatile i64 %x, ptr %y
104  ret void
105}
106
107; Like f1 but with a frame that is 8 bytes bigger.  This is the smallest
108; frame size that needs two instructions to perform the final LMG for
109; %r6 and above.
110define void @f3(ptr %ptr, i64 %x) {
111; CHECK-LABEL: f3:
112; CHECK: stmg %r6, %r15, 48(%r15)
113; CHECK: .cfi_offset %r6, -112
114; CHECK: .cfi_offset %r7, -104
115; CHECK: .cfi_offset %r8, -96
116; CHECK: .cfi_offset %r9, -88
117; CHECK: .cfi_offset %r10, -80
118; CHECK: .cfi_offset %r11, -72
119; CHECK: .cfi_offset %r12, -64
120; CHECK: .cfi_offset %r13, -56
121; CHECK: .cfi_offset %r14, -48
122; CHECK: .cfi_offset %r15, -40
123; CHECK: agfi %r15, -524240
124; CHECK: .cfi_def_cfa_offset 524400
125; ...main function body...
126; CHECK: aghi %r15, 8
127; CHECK: lmg %r6, %r15, 524280(%r15)
128; CHECK: br %r14
129  %l0 = load volatile i32, ptr %ptr
130  %l1 = load volatile i32, ptr %ptr
131  %l4 = load volatile i32, ptr %ptr
132  %l5 = load volatile i32, ptr %ptr
133  %l6 = load volatile i32, ptr %ptr
134  %l7 = load volatile i32, ptr %ptr
135  %l8 = load volatile i32, ptr %ptr
136  %l9 = load volatile i32, ptr %ptr
137  %l10 = load volatile i32, ptr %ptr
138  %l11 = load volatile i32, ptr %ptr
139  %l12 = load volatile i32, ptr %ptr
140  %l13 = load volatile i32, ptr %ptr
141  %l14 = load volatile i32, ptr %ptr
142  %add0 = add i32 %l0, %l0
143  %add1 = add i32 %l1, %add0
144  %add4 = add i32 %l4, %add1
145  %add5 = add i32 %l5, %add4
146  %add6 = add i32 %l6, %add5
147  %add7 = add i32 %l7, %add6
148  %add8 = add i32 %l8, %add7
149  %add9 = add i32 %l9, %add8
150  %add10 = add i32 %l10, %add9
151  %add11 = add i32 %l11, %add10
152  %add12 = add i32 %l12, %add11
153  %add13 = add i32 %l13, %add12
154  %add14 = add i32 %l14, %add13
155  store volatile i32 %add0, ptr %ptr
156  store volatile i32 %add1, ptr %ptr
157  store volatile i32 %add4, ptr %ptr
158  store volatile i32 %add5, ptr %ptr
159  store volatile i32 %add6, ptr %ptr
160  store volatile i32 %add7, ptr %ptr
161  store volatile i32 %add8, ptr %ptr
162  store volatile i32 %add9, ptr %ptr
163  store volatile i32 %add10, ptr %ptr
164  store volatile i32 %add11, ptr %ptr
165  store volatile i32 %add12, ptr %ptr
166  store volatile i32 %add13, ptr %ptr
167  store volatile i32 %add14, ptr %ptr
168  %y = alloca [65508 x i64], align 8
169  store volatile i64 %x, ptr %y
170  ret void
171}
172
173; Like f2 but with a frame that is 8 bytes bigger.  This is the smallest
174; frame size that needs two instructions to perform the final LMG for
175; %r14 and %r15.
176define void @f4(ptr %ptr, i64 %x) {
177; CHECK-LABEL: f4:
178; CHECK: stmg %r14, %r15, 112(%r15)
179; CHECK: .cfi_offset %r14, -48
180; CHECK: .cfi_offset %r15, -40
181; CHECK: agfi %r15, -524176
182; CHECK: .cfi_def_cfa_offset 524336
183; ...main function body...
184; CHECK: aghi %r15, 8
185; CHECK: lmg %r14, %r15, 524280(%r15)
186; CHECK: br %r14
187  %l0 = load volatile i32, ptr %ptr
188  %l1 = load volatile i32, ptr %ptr
189  %l4 = load volatile i32, ptr %ptr
190  %l5 = load volatile i32, ptr %ptr
191  %l14 = load volatile i32, ptr %ptr
192  %add0 = add i32 %l0, %l0
193  %add1 = add i32 %l1, %add0
194  %add4 = add i32 %l4, %add1
195  %add5 = add i32 %l5, %add4
196  %add14 = add i32 %l14, %add5
197  store volatile i32 %add0, ptr %ptr
198  store volatile i32 %add1, ptr %ptr
199  store volatile i32 %add4, ptr %ptr
200  store volatile i32 %add5, ptr %ptr
201  store volatile i32 %add14, ptr %ptr
202  %y = alloca [65500 x i64], align 8
203  store volatile i64 %x, ptr %y
204  ret void
205}
206
207; This is the largest frame size for which the preparatory increment for
208; "lmg %r14, %r15, ..." can be done using AGHI.
209define void @f5(ptr %ptr, i64 %x) {
210; CHECK-LABEL: f5:
211; CHECK: stmg %r14, %r15, 112(%r15)
212; CHECK: .cfi_offset %r14, -48
213; CHECK: .cfi_offset %r15, -40
214; CHECK: agfi %r15, -556928
215; CHECK: .cfi_def_cfa_offset 557088
216; ...main function body...
217; CHECK: aghi %r15, 32760
218; CHECK: lmg %r14, %r15, 524280(%r15)
219; CHECK: br %r14
220  %l0 = load volatile i32, ptr %ptr
221  %l1 = load volatile i32, ptr %ptr
222  %l4 = load volatile i32, ptr %ptr
223  %l5 = load volatile i32, ptr %ptr
224  %l14 = load volatile i32, ptr %ptr
225  %add0 = add i32 %l0, %l0
226  %add1 = add i32 %l1, %add0
227  %add4 = add i32 %l4, %add1
228  %add5 = add i32 %l5, %add4
229  %add14 = add i32 %l14, %add5
230  store volatile i32 %add0, ptr %ptr
231  store volatile i32 %add1, ptr %ptr
232  store volatile i32 %add4, ptr %ptr
233  store volatile i32 %add5, ptr %ptr
234  store volatile i32 %add14, ptr %ptr
235  %y = alloca [69594 x i64], align 8
236  store volatile i64 %x, ptr %y
237  ret void
238}
239
240; This is the smallest frame size for which the preparatory increment for
241; "lmg %r14, %r15, ..." needs to be done using AGFI.
242define void @f6(ptr %ptr, i64 %x) {
243; CHECK-LABEL: f6:
244; CHECK: stmg %r14, %r15, 112(%r15)
245; CHECK: .cfi_offset %r14, -48
246; CHECK: .cfi_offset %r15, -40
247; CHECK: agfi %r15, -556936
248; CHECK: .cfi_def_cfa_offset 557096
249; ...main function body...
250; CHECK: agfi %r15, 32768
251; CHECK: lmg %r14, %r15, 524280(%r15)
252; CHECK: br %r14
253  %l0 = load volatile i32, ptr %ptr
254  %l1 = load volatile i32, ptr %ptr
255  %l4 = load volatile i32, ptr %ptr
256  %l5 = load volatile i32, ptr %ptr
257  %l14 = load volatile i32, ptr %ptr
258  %add0 = add i32 %l0, %l0
259  %add1 = add i32 %l1, %add0
260  %add4 = add i32 %l4, %add1
261  %add5 = add i32 %l5, %add4
262  %add14 = add i32 %l14, %add5
263  store volatile i32 %add0, ptr %ptr
264  store volatile i32 %add1, ptr %ptr
265  store volatile i32 %add4, ptr %ptr
266  store volatile i32 %add5, ptr %ptr
267  store volatile i32 %add14, ptr %ptr
268  %y = alloca [69595 x i64], align 8
269  store volatile i64 %x, ptr %y
270  ret void
271}
272