Fix double renaming bug in stack coloring pass
[oota-llvm.git] / test / CodeGen / SystemZ / spill-01.ll
1 ; Test spilling using MVC.
2 ;
3 ; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
4
5 declare void @foo()
6
7 @g0 = global i32 0
8 @g1 = global i32 1
9 @g2 = global i32 2
10 @g3 = global i32 3
11 @g4 = global i32 4
12 @g5 = global i32 5
13 @g6 = global i32 6
14 @g7 = global i32 7
15 @g8 = global i32 8
16 @g9 = global i32 9
17
18 @h0 = global i64 0
19 @h1 = global i64 1
20 @h2 = global i64 2
21 @h3 = global i64 3
22 @h4 = global i64 4
23 @h5 = global i64 5
24 @h6 = global i64 6
25 @h7 = global i64 7
26 @h8 = global i64 8
27 @h9 = global i64 9
28
29 ; This function shouldn't spill anything
30 define void @f1(i32 *%ptr0) {
31 ; CHECK: f1:
32 ; CHECK: stmg
33 ; CHECK: aghi %r15, -160
34 ; CHECK-NOT: %r15
35 ; CHECK: brasl %r14, foo@PLT
36 ; CHECK-NOT: %r15
37 ; CHECK: lmg
38 ; CHECK: br %r14
39   %ptr1 = getelementptr i32 *%ptr0, i32 2
40   %ptr2 = getelementptr i32 *%ptr0, i32 4
41   %ptr3 = getelementptr i32 *%ptr0, i32 6
42   %ptr4 = getelementptr i32 *%ptr0, i32 8
43   %ptr5 = getelementptr i32 *%ptr0, i32 10
44   %ptr6 = getelementptr i32 *%ptr0, i32 12
45
46   %val0 = load i32 *%ptr0
47   %val1 = load i32 *%ptr1
48   %val2 = load i32 *%ptr2
49   %val3 = load i32 *%ptr3
50   %val4 = load i32 *%ptr4
51   %val5 = load i32 *%ptr5
52   %val6 = load i32 *%ptr6
53
54   call void @foo()
55
56   store i32 %val0, i32 *%ptr0
57   store i32 %val1, i32 *%ptr1
58   store i32 %val2, i32 *%ptr2
59   store i32 %val3, i32 *%ptr3
60   store i32 %val4, i32 *%ptr4
61   store i32 %val5, i32 *%ptr5
62   store i32 %val6, i32 *%ptr6
63
64   ret void
65 }
66
67 ; Test a case where at least one i32 load and at least one i32 store
68 ; need spills.
69 define void @f2(i32 *%ptr0) {
70 ; CHECK: f2:
71 ; CHECK: mvc [[OFFSET1:16[04]]](4,%r15), [[OFFSET2:[0-9]+]]({{%r[0-9]+}})
72 ; CHECK: brasl %r14, foo@PLT
73 ; CHECK: mvc [[OFFSET2]](4,{{%r[0-9]+}}), [[OFFSET1]](%r15)
74 ; CHECK: br %r14
75   %ptr1 = getelementptr i32 *%ptr0, i64 2
76   %ptr2 = getelementptr i32 *%ptr0, i64 4
77   %ptr3 = getelementptr i32 *%ptr0, i64 6
78   %ptr4 = getelementptr i32 *%ptr0, i64 8
79   %ptr5 = getelementptr i32 *%ptr0, i64 10
80   %ptr6 = getelementptr i32 *%ptr0, i64 12
81   %ptr7 = getelementptr i32 *%ptr0, i64 14
82   %ptr8 = getelementptr i32 *%ptr0, i64 16
83
84   %val0 = load i32 *%ptr0
85   %val1 = load i32 *%ptr1
86   %val2 = load i32 *%ptr2
87   %val3 = load i32 *%ptr3
88   %val4 = load i32 *%ptr4
89   %val5 = load i32 *%ptr5
90   %val6 = load i32 *%ptr6
91   %val7 = load i32 *%ptr7
92   %val8 = load i32 *%ptr8
93
94   call void @foo()
95
96   store i32 %val0, i32 *%ptr0
97   store i32 %val1, i32 *%ptr1
98   store i32 %val2, i32 *%ptr2
99   store i32 %val3, i32 *%ptr3
100   store i32 %val4, i32 *%ptr4
101   store i32 %val5, i32 *%ptr5
102   store i32 %val6, i32 *%ptr6
103   store i32 %val7, i32 *%ptr7
104   store i32 %val8, i32 *%ptr8
105
106   ret void
107 }
108
109 ; Test a case where at least one i64 load and at least one i64 store
110 ; need spills.
111 define void @f3(i64 *%ptr0) {
112 ; CHECK: f3:
113 ; CHECK: mvc 160(8,%r15), [[OFFSET:[0-9]+]]({{%r[0-9]+}})
114 ; CHECK: brasl %r14, foo@PLT
115 ; CHECK: mvc [[OFFSET]](8,{{%r[0-9]+}}), 160(%r15)
116 ; CHECK: br %r14
117   %ptr1 = getelementptr i64 *%ptr0, i64 2
118   %ptr2 = getelementptr i64 *%ptr0, i64 4
119   %ptr3 = getelementptr i64 *%ptr0, i64 6
120   %ptr4 = getelementptr i64 *%ptr0, i64 8
121   %ptr5 = getelementptr i64 *%ptr0, i64 10
122   %ptr6 = getelementptr i64 *%ptr0, i64 12
123   %ptr7 = getelementptr i64 *%ptr0, i64 14
124   %ptr8 = getelementptr i64 *%ptr0, i64 16
125
126   %val0 = load i64 *%ptr0
127   %val1 = load i64 *%ptr1
128   %val2 = load i64 *%ptr2
129   %val3 = load i64 *%ptr3
130   %val4 = load i64 *%ptr4
131   %val5 = load i64 *%ptr5
132   %val6 = load i64 *%ptr6
133   %val7 = load i64 *%ptr7
134   %val8 = load i64 *%ptr8
135
136   call void @foo()
137
138   store i64 %val0, i64 *%ptr0
139   store i64 %val1, i64 *%ptr1
140   store i64 %val2, i64 *%ptr2
141   store i64 %val3, i64 *%ptr3
142   store i64 %val4, i64 *%ptr4
143   store i64 %val5, i64 *%ptr5
144   store i64 %val6, i64 *%ptr6
145   store i64 %val7, i64 *%ptr7
146   store i64 %val8, i64 *%ptr8
147
148   ret void
149 }
150
151
152 ; Test a case where at least at least one f32 load and at least one f32 store
153 ; need spills.  The 8 call-saved FPRs could be used for 8 of the %vals
154 ; (and are at the time of writing), but it would really be better to use
155 ; MVC for all 10.
156 define void @f4(float *%ptr0) {
157 ; CHECK: f4:
158 ; CHECK: mvc [[OFFSET1:16[04]]](4,%r15), [[OFFSET2:[0-9]+]]({{%r[0-9]+}})
159 ; CHECK: brasl %r14, foo@PLT
160 ; CHECK: mvc [[OFFSET2]](4,{{%r[0-9]+}}), [[OFFSET1]](%r15)
161 ; CHECK: br %r14
162   %ptr1 = getelementptr float *%ptr0, i64 2
163   %ptr2 = getelementptr float *%ptr0, i64 4
164   %ptr3 = getelementptr float *%ptr0, i64 6
165   %ptr4 = getelementptr float *%ptr0, i64 8
166   %ptr5 = getelementptr float *%ptr0, i64 10
167   %ptr6 = getelementptr float *%ptr0, i64 12
168   %ptr7 = getelementptr float *%ptr0, i64 14
169   %ptr8 = getelementptr float *%ptr0, i64 16
170   %ptr9 = getelementptr float *%ptr0, i64 18
171
172   %val0 = load float *%ptr0
173   %val1 = load float *%ptr1
174   %val2 = load float *%ptr2
175   %val3 = load float *%ptr3
176   %val4 = load float *%ptr4
177   %val5 = load float *%ptr5
178   %val6 = load float *%ptr6
179   %val7 = load float *%ptr7
180   %val8 = load float *%ptr8
181   %val9 = load float *%ptr9
182
183   call void @foo()
184
185   store float %val0, float *%ptr0
186   store float %val1, float *%ptr1
187   store float %val2, float *%ptr2
188   store float %val3, float *%ptr3
189   store float %val4, float *%ptr4
190   store float %val5, float *%ptr5
191   store float %val6, float *%ptr6
192   store float %val7, float *%ptr7
193   store float %val8, float *%ptr8
194   store float %val9, float *%ptr9
195
196   ret void
197 }
198
199 ; Similarly for f64.
200 define void @f5(double *%ptr0) {
201 ; CHECK: f5:
202 ; CHECK: mvc 160(8,%r15), [[OFFSET:[0-9]+]]({{%r[0-9]+}})
203 ; CHECK: brasl %r14, foo@PLT
204 ; CHECK: mvc [[OFFSET]](8,{{%r[0-9]+}}), 160(%r15)
205 ; CHECK: br %r14
206   %ptr1 = getelementptr double *%ptr0, i64 2
207   %ptr2 = getelementptr double *%ptr0, i64 4
208   %ptr3 = getelementptr double *%ptr0, i64 6
209   %ptr4 = getelementptr double *%ptr0, i64 8
210   %ptr5 = getelementptr double *%ptr0, i64 10
211   %ptr6 = getelementptr double *%ptr0, i64 12
212   %ptr7 = getelementptr double *%ptr0, i64 14
213   %ptr8 = getelementptr double *%ptr0, i64 16
214   %ptr9 = getelementptr double *%ptr0, i64 18
215
216   %val0 = load double *%ptr0
217   %val1 = load double *%ptr1
218   %val2 = load double *%ptr2
219   %val3 = load double *%ptr3
220   %val4 = load double *%ptr4
221   %val5 = load double *%ptr5
222   %val6 = load double *%ptr6
223   %val7 = load double *%ptr7
224   %val8 = load double *%ptr8
225   %val9 = load double *%ptr9
226
227   call void @foo()
228
229   store double %val0, double *%ptr0
230   store double %val1, double *%ptr1
231   store double %val2, double *%ptr2
232   store double %val3, double *%ptr3
233   store double %val4, double *%ptr4
234   store double %val5, double *%ptr5
235   store double %val6, double *%ptr6
236   store double %val7, double *%ptr7
237   store double %val8, double *%ptr8
238   store double %val9, double *%ptr9
239
240   ret void
241 }
242
243 ; Repeat f2 with atomic accesses.  We shouldn't use MVC here.
244 define void @f6(i32 *%ptr0) {
245 ; CHECK: f6:
246 ; CHECK-NOT: mvc
247 ; CHECK: br %r14
248   %ptr1 = getelementptr i32 *%ptr0, i64 2
249   %ptr2 = getelementptr i32 *%ptr0, i64 4
250   %ptr3 = getelementptr i32 *%ptr0, i64 6
251   %ptr4 = getelementptr i32 *%ptr0, i64 8
252   %ptr5 = getelementptr i32 *%ptr0, i64 10
253   %ptr6 = getelementptr i32 *%ptr0, i64 12
254   %ptr7 = getelementptr i32 *%ptr0, i64 14
255   %ptr8 = getelementptr i32 *%ptr0, i64 16
256
257   %val0 = load atomic i32 *%ptr0 unordered, align 4
258   %val1 = load atomic i32 *%ptr1 unordered, align 4
259   %val2 = load atomic i32 *%ptr2 unordered, align 4
260   %val3 = load atomic i32 *%ptr3 unordered, align 4
261   %val4 = load atomic i32 *%ptr4 unordered, align 4
262   %val5 = load atomic i32 *%ptr5 unordered, align 4
263   %val6 = load atomic i32 *%ptr6 unordered, align 4
264   %val7 = load atomic i32 *%ptr7 unordered, align 4
265   %val8 = load atomic i32 *%ptr8 unordered, align 4
266
267   call void @foo()
268
269   store atomic i32 %val0, i32 *%ptr0 unordered, align 4
270   store atomic i32 %val1, i32 *%ptr1 unordered, align 4
271   store atomic i32 %val2, i32 *%ptr2 unordered, align 4
272   store atomic i32 %val3, i32 *%ptr3 unordered, align 4
273   store atomic i32 %val4, i32 *%ptr4 unordered, align 4
274   store atomic i32 %val5, i32 *%ptr5 unordered, align 4
275   store atomic i32 %val6, i32 *%ptr6 unordered, align 4
276   store atomic i32 %val7, i32 *%ptr7 unordered, align 4
277   store atomic i32 %val8, i32 *%ptr8 unordered, align 4
278
279   ret void
280 }
281
282 ; ...likewise volatile accesses.
283 define void @f7(i32 *%ptr0) {
284 ; CHECK: f7:
285 ; CHECK-NOT: mvc
286 ; CHECK: br %r14
287   %ptr1 = getelementptr i32 *%ptr0, i64 2
288   %ptr2 = getelementptr i32 *%ptr0, i64 4
289   %ptr3 = getelementptr i32 *%ptr0, i64 6
290   %ptr4 = getelementptr i32 *%ptr0, i64 8
291   %ptr5 = getelementptr i32 *%ptr0, i64 10
292   %ptr6 = getelementptr i32 *%ptr0, i64 12
293   %ptr7 = getelementptr i32 *%ptr0, i64 14
294   %ptr8 = getelementptr i32 *%ptr0, i64 16
295
296   %val0 = load volatile i32 *%ptr0
297   %val1 = load volatile i32 *%ptr1
298   %val2 = load volatile i32 *%ptr2
299   %val3 = load volatile i32 *%ptr3
300   %val4 = load volatile i32 *%ptr4
301   %val5 = load volatile i32 *%ptr5
302   %val6 = load volatile i32 *%ptr6
303   %val7 = load volatile i32 *%ptr7
304   %val8 = load volatile i32 *%ptr8
305
306   call void @foo()
307
308   store volatile i32 %val0, i32 *%ptr0
309   store volatile i32 %val1, i32 *%ptr1
310   store volatile i32 %val2, i32 *%ptr2
311   store volatile i32 %val3, i32 *%ptr3
312   store volatile i32 %val4, i32 *%ptr4
313   store volatile i32 %val5, i32 *%ptr5
314   store volatile i32 %val6, i32 *%ptr6
315   store volatile i32 %val7, i32 *%ptr7
316   store volatile i32 %val8, i32 *%ptr8
317
318   ret void
319 }
320
321 ; Check that LRL and STRL are not converted.
322 define void @f8() {
323 ; CHECK: f8:
324 ; CHECK-NOT: mvc
325 ; CHECK: br %r14
326   %val0 = load i32 *@g0
327   %val1 = load i32 *@g1
328   %val2 = load i32 *@g2
329   %val3 = load i32 *@g3
330   %val4 = load i32 *@g4
331   %val5 = load i32 *@g5
332   %val6 = load i32 *@g6
333   %val7 = load i32 *@g7
334   %val8 = load i32 *@g8
335   %val9 = load i32 *@g9
336
337   call void @foo()
338
339   store i32 %val0, i32 *@g0
340   store i32 %val1, i32 *@g1
341   store i32 %val2, i32 *@g2
342   store i32 %val3, i32 *@g3
343   store i32 %val4, i32 *@g4
344   store i32 %val5, i32 *@g5
345   store i32 %val6, i32 *@g6
346   store i32 %val7, i32 *@g7
347   store i32 %val8, i32 *@g8
348   store i32 %val9, i32 *@g9
349
350   ret void
351 }
352
353 ; Likewise LGRL and STGRL.
354 define void @f9() {
355 ; CHECK: f9:
356 ; CHECK-NOT: mvc
357 ; CHECK: br %r14
358   %val0 = load i64 *@h0
359   %val1 = load i64 *@h1
360   %val2 = load i64 *@h2
361   %val3 = load i64 *@h3
362   %val4 = load i64 *@h4
363   %val5 = load i64 *@h5
364   %val6 = load i64 *@h6
365   %val7 = load i64 *@h7
366   %val8 = load i64 *@h8
367   %val9 = load i64 *@h9
368
369   call void @foo()
370
371   store i64 %val0, i64 *@h0
372   store i64 %val1, i64 *@h1
373   store i64 %val2, i64 *@h2
374   store i64 %val3, i64 *@h3
375   store i64 %val4, i64 *@h4
376   store i64 %val5, i64 *@h5
377   store i64 %val6, i64 *@h6
378   store i64 %val7, i64 *@h7
379   store i64 %val8, i64 *@h8
380   store i64 %val9, i64 *@h9
381
382   ret void
383 }
384
385 ; This showed a problem with the way stack coloring updated instructions.
386 ; The copy from %val9 to %newval8 can be done using an MVC, which then
387 ; has two frame index operands.  Stack coloring chose a valid renumbering
388 ; [FI0, FI1] -> [FI1, FI2], but applied it in the form FI0 -> FI1 -> FI2,
389 ; so that both operands ended up being the same.
390 define void @f10() {
391 ; CHECK: f10:
392 ; CHECK: lgrl [[REG:%r[0-9]+]], h9
393 ; CHECK: stg [[REG]], [[VAL9:[0-9]+]](%r15)
394 ; CHECK: brasl %r14, foo@PLT
395 ; CHECK: brasl %r14, foo@PLT
396 ; CHECK: mvc [[NEWVAL8:[0-9]+]](8,%r15), [[VAL9]](%r15)
397 ; CHECK: brasl %r14, foo@PLT
398 ; CHECK: lg [[REG:%r[0-9]+]], [[NEWVAL8]](%r15)
399 ; CHECK: stgrl [[REG]], h8
400 ; CHECK: br %r14
401 entry:
402   %val0 = load volatile i64 *@h0
403   %val1 = load volatile i64 *@h1
404   %val2 = load volatile i64 *@h2
405   %val3 = load volatile i64 *@h3
406   %val4 = load volatile i64 *@h4
407   %val5 = load volatile i64 *@h5
408   %val6 = load volatile i64 *@h6
409   %val7 = load volatile i64 *@h7
410   %val8 = load volatile i64 *@h8
411   %val9 = load volatile i64 *@h9
412
413   call void @foo()
414
415   store volatile i64 %val0, i64 *@h0
416   store volatile i64 %val1, i64 *@h1
417   store volatile i64 %val2, i64 *@h2
418   store volatile i64 %val3, i64 *@h3
419   store volatile i64 %val4, i64 *@h4
420   store volatile i64 %val5, i64 *@h5
421   store volatile i64 %val6, i64 *@h6
422   store volatile i64 %val7, i64 *@h7
423
424   %check = load volatile i64 *@h0
425   %cond = icmp eq i64 %check, 0
426   br i1 %cond, label %skip, label %fallthru
427
428 fallthru:
429   call void @foo()
430
431   store volatile i64 %val0, i64 *@h0
432   store volatile i64 %val1, i64 *@h1
433   store volatile i64 %val2, i64 *@h2
434   store volatile i64 %val3, i64 *@h3
435   store volatile i64 %val4, i64 *@h4
436   store volatile i64 %val5, i64 *@h5
437   store volatile i64 %val6, i64 *@h6
438   store volatile i64 %val7, i64 *@h7
439   store volatile i64 %val8, i64 *@h8
440   br label %skip
441
442 skip:
443   %newval8 = phi i64 [ %val8, %entry ], [ %val9, %fallthru ]
444   call void @foo()
445
446   store volatile i64 %val0, i64 *@h0
447   store volatile i64 %val1, i64 *@h1
448   store volatile i64 %val2, i64 *@h2
449   store volatile i64 %val3, i64 *@h3
450   store volatile i64 %val4, i64 *@h4
451   store volatile i64 %val5, i64 *@h5
452   store volatile i64 %val6, i64 *@h6
453   store volatile i64 %val7, i64 *@h7
454   store volatile i64 %newval8, i64 *@h8
455   store volatile i64 %val9, i64 *@h9
456
457   ret void
458 }