1 ; Test the saving and restoring of GPRs in large frames.
3 ; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
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
9 define void @f1(ptr %ptr, i64 %x) {
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...
26 ; CHECK: lmg %r6, %r15, 524280(%r15)
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
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
76 define void @f2(ptr %ptr, i64 %x) {
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...
85 ; CHECK: lmg %r14, %r15, 524280(%r15)
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
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
110 define void @f3(ptr %ptr, i64 %x) {
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)
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
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
176 define void @f4(ptr %ptr, i64 %x) {
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)
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
207 ; This is the largest frame size for which the preparatory increment for
208 ; "lmg %r14, %r15, ..." can be done using AGHI.
209 define void @f5(ptr %ptr, i64 %x) {
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)
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
240 ; This is the smallest frame size for which the preparatory increment for
241 ; "lmg %r14, %r15, ..." needs to be done using AGFI.
242 define void @f6(ptr %ptr, i64 %x) {
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)
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