1 ; Test saving and restoring of call-saved GPRs.
3 ; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
5 ; This function should require all GPRs, but no other spill slots. The caller
6 ; allocates room for the GPR save slots, so we shouldn't need to allocate any
9 ; The function only modifies the low 32 bits of each register, which in
10 ; itself would allow STM and LM to be used instead of STMG and LMG.
11 ; However, the ABI defines the offset of each register, so we always
12 ; use the 64-bit form.
14 ; Use a different address for the final store, so that we can check that
15 ; %r15 isn't referenced again until after that.
16 define void @f1(ptr %ptr) {
18 ; CHECK: stmg %r6, %r15, 48(%r15)
20 ; CHECK: .cfi_offset %r6, -112
21 ; CHECK: .cfi_offset %r7, -104
22 ; CHECK: .cfi_offset %r8, -96
23 ; CHECK: .cfi_offset %r9, -88
24 ; CHECK: .cfi_offset %r10, -80
25 ; CHECK: .cfi_offset %r11, -72
26 ; CHECK: .cfi_offset %r12, -64
27 ; CHECK: .cfi_offset %r13, -56
28 ; CHECK: .cfi_offset %r14, -48
29 ; CHECK: .cfi_offset %r15, -40
30 ; ...main function body...
32 ; CHECK: st {{.*}}, 4(%r2)
33 ; CHECK: lmg %r6, %r15, 48(%r15)
35 %l0 = load volatile i32, ptr %ptr
36 %l1 = load volatile i32, ptr %ptr
37 %l3 = load volatile i32, ptr %ptr
38 %l4 = load volatile i32, ptr %ptr
39 %l5 = load volatile i32, ptr %ptr
40 %l6 = load volatile i32, ptr %ptr
41 %l7 = load volatile i32, ptr %ptr
42 %l8 = load volatile i32, ptr %ptr
43 %l9 = load volatile i32, ptr %ptr
44 %l10 = load volatile i32, ptr %ptr
45 %l11 = load volatile i32, ptr %ptr
46 %l12 = load volatile i32, ptr %ptr
47 %l13 = load volatile i32, ptr %ptr
48 %l14 = load volatile i32, ptr %ptr
49 %add0 = add i32 %l0, %l0
50 %add1 = add i32 %l1, %add0
51 %add3 = add i32 %l3, %add1
52 %add4 = add i32 %l4, %add3
53 %add5 = add i32 %l5, %add4
54 %add6 = add i32 %l6, %add5
55 %add7 = add i32 %l7, %add6
56 %add8 = add i32 %l8, %add7
57 %add9 = add i32 %l9, %add8
58 %add10 = add i32 %l10, %add9
59 %add11 = add i32 %l11, %add10
60 %add12 = add i32 %l12, %add11
61 %add13 = add i32 %l13, %add12
62 %add14 = add i32 %l14, %add13
63 store volatile i32 %add0, ptr %ptr
64 store volatile i32 %add1, ptr %ptr
65 store volatile i32 %add3, ptr %ptr
66 store volatile i32 %add4, ptr %ptr
67 store volatile i32 %add5, ptr %ptr
68 store volatile i32 %add6, ptr %ptr
69 store volatile i32 %add7, ptr %ptr
70 store volatile i32 %add8, ptr %ptr
71 store volatile i32 %add9, ptr %ptr
72 store volatile i32 %add10, ptr %ptr
73 store volatile i32 %add11, ptr %ptr
74 store volatile i32 %add12, ptr %ptr
75 store volatile i32 %add13, ptr %ptr
76 %final = getelementptr i32, ptr %ptr, i32 1
77 store volatile i32 %add14, ptr %final
81 ; Like f1, but requires one fewer GPR. We allocate the call-saved GPRs
82 ; from %r14 down, so that the STMG/LMG sequences aren't any longer than
84 define void @f2(ptr %ptr) {
86 ; CHECK: stmg %r7, %r15, 56(%r15)
88 ; CHECK: .cfi_offset %r7, -104
89 ; CHECK: .cfi_offset %r8, -96
90 ; CHECK: .cfi_offset %r9, -88
91 ; CHECK: .cfi_offset %r10, -80
92 ; CHECK: .cfi_offset %r11, -72
93 ; CHECK: .cfi_offset %r12, -64
94 ; CHECK: .cfi_offset %r13, -56
95 ; CHECK: .cfi_offset %r14, -48
96 ; CHECK: .cfi_offset %r15, -40
97 ; ...main function body...
100 ; CHECK: st {{.*}}, 4(%r2)
101 ; CHECK: lmg %r7, %r15, 56(%r15)
103 %l0 = load volatile i32, ptr %ptr
104 %l1 = load volatile i32, ptr %ptr
105 %l3 = load volatile i32, ptr %ptr
106 %l4 = load volatile i32, ptr %ptr
107 %l5 = load volatile i32, ptr %ptr
108 %l7 = load volatile i32, ptr %ptr
109 %l8 = load volatile i32, ptr %ptr
110 %l9 = load volatile i32, ptr %ptr
111 %l10 = load volatile i32, ptr %ptr
112 %l11 = load volatile i32, ptr %ptr
113 %l12 = load volatile i32, ptr %ptr
114 %l13 = load volatile i32, ptr %ptr
115 %l14 = load volatile i32, ptr %ptr
116 %add0 = add i32 %l0, %l0
117 %add1 = add i32 %l1, %add0
118 %add3 = add i32 %l3, %add1
119 %add4 = add i32 %l4, %add3
120 %add5 = add i32 %l5, %add4
121 %add7 = add i32 %l7, %add5
122 %add8 = add i32 %l8, %add7
123 %add9 = add i32 %l9, %add8
124 %add10 = add i32 %l10, %add9
125 %add11 = add i32 %l11, %add10
126 %add12 = add i32 %l12, %add11
127 %add13 = add i32 %l13, %add12
128 %add14 = add i32 %l14, %add13
129 store volatile i32 %add0, ptr %ptr
130 store volatile i32 %add1, ptr %ptr
131 store volatile i32 %add3, ptr %ptr
132 store volatile i32 %add4, ptr %ptr
133 store volatile i32 %add5, ptr %ptr
134 store volatile i32 %add7, ptr %ptr
135 store volatile i32 %add8, ptr %ptr
136 store volatile i32 %add9, ptr %ptr
137 store volatile i32 %add10, ptr %ptr
138 store volatile i32 %add11, ptr %ptr
139 store volatile i32 %add12, ptr %ptr
140 store volatile i32 %add13, ptr %ptr
141 %final = getelementptr i32, ptr %ptr, i32 1
142 store volatile i32 %add14, ptr %final
146 ; Like f1, but only needs one call-saved GPR, which ought to be %r14.
147 define void @f3(ptr %ptr) {
149 ; CHECK: stmg %r14, %r15, 112(%r15)
151 ; CHECK: .cfi_offset %r14, -48
152 ; CHECK: .cfi_offset %r15, -40
153 ; ...main function body...
163 ; CHECK: st {{.*}}, 4(%r2)
164 ; CHECK: lmg %r14, %r15, 112(%r15)
166 %l0 = load volatile i32, ptr %ptr
167 %l1 = load volatile i32, ptr %ptr
168 %l3 = load volatile i32, ptr %ptr
169 %l4 = load volatile i32, ptr %ptr
170 %l5 = load volatile i32, ptr %ptr
171 %l14 = load volatile i32, ptr %ptr
172 %add0 = add i32 %l0, %l0
173 %add1 = add i32 %l1, %add0
174 %add3 = add i32 %l3, %add1
175 %add4 = add i32 %l4, %add3
176 %add5 = add i32 %l5, %add4
177 %add14 = add i32 %l14, %add5
178 store volatile i32 %add0, ptr %ptr
179 store volatile i32 %add1, ptr %ptr
180 store volatile i32 %add3, ptr %ptr
181 store volatile i32 %add4, ptr %ptr
182 store volatile i32 %add5, ptr %ptr
183 %final = getelementptr i32, ptr %ptr, i32 1
184 store volatile i32 %add14, ptr %final
188 ; This function should use all call-clobbered GPRs but no call-saved ones.
189 ; It shouldn't need to touch the stack at all.
190 define void @f4(ptr %ptr) {
202 %l0 = load volatile i32, ptr %ptr
203 %l1 = load volatile i32, ptr %ptr
204 %l3 = load volatile i32, ptr %ptr
205 %l4 = load volatile i32, ptr %ptr
206 %l5 = load volatile i32, ptr %ptr
207 %add0 = add i32 %l0, %l0
208 %add1 = add i32 %l1, %add0
209 %add3 = add i32 %l3, %add1
210 %add4 = add i32 %l4, %add3
211 %add5 = add i32 %l5, %add4
212 store volatile i32 %add0, ptr %ptr
213 store volatile i32 %add1, ptr %ptr
214 store volatile i32 %add3, ptr %ptr
215 store volatile i32 %add4, ptr %ptr
216 %final = getelementptr i32, ptr %ptr, i32 1
217 store volatile i32 %add5, ptr %final