1# RUN: llc -mtriple=s390x-linux-gnu -mcpu=z13 -start-before=greedy %s -o - \
2# RUN:   | FileCheck %s
3#
4# Test that the reg alloc hints are given in a good order that gives no more
5# than 5 LGRs in output.
6
7--- |
8  ; ModuleID = 'tc.ll'
9  source_filename = "tc.ll"
10  target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
11  target triple = "s390x-unknown-linux-gnu"
12
13  %0 = type { i32, i32, i32, float, float, float, i8*, i32 }
14
15  define void @fun(i32 signext %arg, i32 zeroext %arg1) #0 {
16  bb:
17    %tmp = sext i32 %arg to i64
18    %tmp2 = tail call i8* @sre_malloc()
19    %tmp4 = tail call i8* @sre_malloc()
20    %tmp6 = add i32 %arg, -1
21    tail call void @malloc()
22    %0 = trunc i32 %arg to i2
23    %1 = add i2 %0, -1
24    br label %bb8
25
26  bb8:                                              ; preds = %bb54, %bb
27    %lsr.iv6 = phi i2 [ %lsr.iv.next7, %bb54 ], [ %1, %bb ]
28    %tmp9 = phi i64 [ %tmp57, %bb54 ], [ 0, %bb ]
29    %tmp10 = phi i64 [ 0, %bb54 ], [ %tmp, %bb ]
30    %tmp12 = sub i64 %tmp, %tmp9
31    br label %bb14
32
33  bb14:                                             ; preds = %bb39, %bb8
34    %lsr.iv8 = phi i2 [ %lsr.iv.next9, %bb39 ], [ %lsr.iv6, %bb8 ]
35    %lsr.iv = phi i32 [ %lsr.iv.next, %bb39 ], [ 1, %bb8 ]
36    %tmp15 = phi i64 [ 0, %bb8 ], [ %tmp19, %bb39 ]
37    %tmp17 = phi i32 [ %tmp6, %bb8 ], [ %tmp35, %bb39 ]
38    %tmp18 = phi i32 [ 0, %bb8 ], [ %tmp34, %bb39 ]
39    %2 = bitcast i8* %tmp2 to float**
40    %tmp19 = add nuw nsw i64 %tmp15, 1
41    %3 = zext i2 %lsr.iv8 to i64
42    %4 = mul i64 %3, -1
43    %tmp21 = getelementptr inbounds float*, float** %2, i64 %tmp15
44    %tmp22 = load float*, float** %tmp21
45    %tmp23 = trunc i64 %tmp15 to i32
46    %scevgep = getelementptr float, float* %tmp22, i64 %tmp15
47    br label %bb25
48
49  bb25:                                             ; preds = %bb25, %bb14
50    %lsr.iv10 = phi i64 [ %lsr.iv.next11, %bb25 ], [ %4, %bb14 ]
51    %lsr.iv3 = phi float* [ %scevgep4, %bb25 ], [ %scevgep, %bb14 ]
52    %lsr.iv1 = phi i32 [ %lsr.iv.next2, %bb25 ], [ %lsr.iv, %bb14 ]
53    %tmp27 = phi i32 [ %tmp35, %bb25 ], [ %tmp17, %bb14 ]
54    %tmp28 = phi i32 [ %tmp34, %bb25 ], [ %tmp18, %bb14 ]
55    %scevgep5 = getelementptr float, float* %lsr.iv3, i64 1
56    %tmp31 = load float, float* %scevgep5
57    %tmp32 = fcmp olt float %tmp31, undef
58    %tmp34 = select i1 %tmp32, i32 %lsr.iv1, i32 %tmp28
59    %tmp35 = select i1 %tmp32, i32 %tmp23, i32 %tmp27
60    %lsr.iv.next2 = add i32 %lsr.iv1, 1
61    %scevgep4 = getelementptr float, float* %lsr.iv3, i64 1
62    %lsr.iv.next11 = add i64 %lsr.iv10, 1
63    %tmp38 = icmp eq i64 %lsr.iv.next11, 0
64    br i1 %tmp38, label %bb39, label %bb25
65
66  bb39:                                             ; preds = %bb25
67    %lsr.iv.next = add i32 %lsr.iv, 1
68    %lsr.iv.next9 = add i2 %lsr.iv8, -1
69    %tmp41 = icmp eq i64 %tmp19, %tmp10
70    br i1 %tmp41, label %bb42, label %bb14
71
72  bb42:                                             ; preds = %bb39
73    %5 = bitcast i8* %tmp4 to i32*
74    %tmp43 = getelementptr inbounds i32, i32* %5, i64 undef
75    %tmp44 = load i32, i32* %tmp43
76    %tmp45 = sub nsw i32 %tmp44, %arg
77    %tmp46 = sext i32 %tmp45 to i64
78    %tmp47 = getelementptr inbounds %0, %0* null, i64 %tmp46, i32 7
79    %tmp48 = load i32, i32* %tmp47
80    %tmp49 = add nsw i32 0, %tmp48
81    store i32 %tmp49, i32* undef
82    %cond = icmp eq i32 %arg1, 0
83    br i1 %cond, label %bb52, label %bb54
84
85  bb52:                                             ; preds = %bb42
86    %tmp5312 = bitcast float* undef to float*
87    br label %bb54
88
89  bb54:                                             ; preds = %bb42, %bb52
90    %6 = bitcast i8* %tmp4 to i32*
91    %tmp55 = add i32 0, %arg
92    %tmp56 = getelementptr inbounds i32, i32* %6, i64 undef
93    store i32 %tmp55, i32* %tmp56
94    %tmp57 = add i64 %tmp9, 1
95    %lsr.iv.next7 = add i2 %lsr.iv6, -1
96    br label %bb8
97  }
98
99  declare i8* @sre_malloc() #0
100
101  declare void @malloc() #0
102
103  ; Function Attrs: nounwind
104  declare void @llvm.stackprotector(i8*, i8**) #1
105
106  attributes #0 = { "target-cpu"="z13" }
107  attributes #1 = { nounwind }
108
109...
110
111# CHECK: lgr
112# CHECK: lgr
113# CHECK: lgr
114# CHECK: lgr
115# CHECK: lgr
116# CHECK-NOT: lgr
117
118---
119name:            fun
120alignment:       16
121tracksRegLiveness: true
122registers:
123  - { id: 0, class: gr64bit }
124  - { id: 1, class: addr64bit }
125  - { id: 2, class: addr64bit }
126  - { id: 3, class: gr32bit }
127  - { id: 4, class: gr32bit }
128  - { id: 5, class: grx32bit }
129  - { id: 6, class: addr64bit }
130  - { id: 7, class: gr64bit }
131  - { id: 8, class: grx32bit }
132  - { id: 9, class: grx32bit }
133  - { id: 10, class: addr64bit }
134  - { id: 11, class: grx32bit }
135  - { id: 12, class: grx32bit }
136  - { id: 13, class: gr64bit }
137  - { id: 14, class: gr64bit }
138  - { id: 15, class: grx32bit }
139  - { id: 16, class: gr64bit }
140  - { id: 17, class: addr64bit }
141  - { id: 18, class: addr64bit }
142  - { id: 19, class: grx32bit }
143  - { id: 20, class: grx32bit }
144  - { id: 21, class: grx32bit }
145  - { id: 22, class: grx32bit }
146  - { id: 23, class: grx32bit }
147  - { id: 24, class: grx32bit }
148  - { id: 25, class: gr64bit }
149  - { id: 26, class: gr64bit }
150  - { id: 27, class: grx32bit }
151  - { id: 28, class: grx32bit }
152  - { id: 29, class: gr64bit }
153  - { id: 30, class: grx32bit }
154  - { id: 31, class: gr64bit }
155  - { id: 32, class: gr64bit }
156  - { id: 33, class: gr32bit }
157  - { id: 34, class: grx32bit }
158  - { id: 35, class: gr64bit }
159  - { id: 36, class: gr64bit }
160  - { id: 37, class: gr64bit }
161  - { id: 38, class: grx32bit }
162  - { id: 39, class: gr64bit }
163  - { id: 40, class: grx32bit }
164  - { id: 41, class: gr64bit }
165  - { id: 42, class: gr64bit }
166  - { id: 43, class: gr64bit }
167  - { id: 44, class: gr64bit }
168  - { id: 45, class: addr64bit }
169  - { id: 46, class: gr64bit }
170  - { id: 47, class: fp32bit }
171  - { id: 48, class: fp32bit }
172  - { id: 49, class: gr32bit }
173  - { id: 50, class: gr32bit }
174  - { id: 51, class: gr64bit }
175  - { id: 52, class: addr64bit }
176  - { id: 53, class: addr64bit }
177  - { id: 54, class: gr64bit }
178  - { id: 55, class: gr32bit }
179  - { id: 56, class: addr64bit }
180  - { id: 57, class: gr64bit }
181  - { id: 58, class: grx32bit }
182  - { id: 59, class: grx32bit }
183  - { id: 60, class: addr64bit }
184  - { id: 61, class: grx32bit }
185  - { id: 62, class: grx32bit }
186  - { id: 63, class: addr64bit }
187  - { id: 64, class: addr64bit }
188  - { id: 65, class: grx32bit }
189  - { id: 66, class: grx32bit }
190  - { id: 67, class: grx32bit }
191liveins:
192  - { reg: '$r2d', virtual-reg: '%31' }
193  - { reg: '$r3d', virtual-reg: '%32' }
194frameInfo:
195  hasCalls:        true
196body:             |
197  bb.0.bb:
198    liveins: $r2d, $r3d
199
200    %32:gr64bit = COPY $r3d
201    %0:gr64bit = COPY $r2d
202    ADJCALLSTACKDOWN 0, 0
203    CallBRASL @sre_malloc, csr_systemz, implicit-def dead $r14d, implicit-def dead $cc, implicit-def $r2d
204    %1:addr64bit = COPY $r2d
205    ADJCALLSTACKUP 0, 0
206    ADJCALLSTACKDOWN 0, 0
207    CallBRASL @sre_malloc, csr_systemz, implicit-def dead $r14d, implicit-def dead $cc, implicit-def $r2d
208    %2:addr64bit = COPY $r2d
209    ADJCALLSTACKUP 0, 0
210    %3:gr32bit = AHIMuxK %0.subreg_l32, -1, implicit-def dead $cc
211    ADJCALLSTACKDOWN 0, 0
212    CallBRASL @malloc, csr_systemz, implicit-def dead $r14d, implicit-def dead $cc
213    ADJCALLSTACKUP 0, 0
214    %55:gr32bit = AHIMuxK %0.subreg_l32, 3, implicit-def dead $cc
215    %56:addr64bit = LGHI 0
216    %57:gr64bit = COPY %0
217
218  bb.1.bb8:
219    %62:grx32bit = LHIMux 0
220    %59:grx32bit = LHIMux 1
221    undef %41.subreg_l32:gr64bit = COPY %55
222    %60:addr64bit = LGHI 0
223    %61:grx32bit = COPY %3
224
225  bb.2.bb14:
226    %10:addr64bit = COPY %60
227    %60:addr64bit = nuw nsw LA %10, 1, $noreg
228    %43:gr64bit = RISBGN undef %43, %41, 62, 191, 0
229    %63:addr64bit = LCGR %43, implicit-def dead $cc
230    %45:addr64bit = SLLG %10, $noreg, 3
231    %64:addr64bit = SLLG %10, $noreg, 2
232    %64:addr64bit = AG %64, %1, 0, %45, implicit-def dead $cc :: (load 8 from %ir.tmp21)
233    %65:grx32bit = COPY %59
234
235  bb.3.bb25:
236    successors: %bb.4(0x04000000), %bb.3(0x7c000000)
237
238    %47:fp32bit = VL32 %64, 4, $noreg :: (load 4 from %ir.scevgep5)
239    %25:gr64bit = LA %64, 4, $noreg
240    CEBR %47, undef %48:fp32bit, implicit-def $cc, implicit $fpc
241    %62:grx32bit = LOCRMux %62, %65, 15, 4, implicit $cc
242    %61:grx32bit = LOCRMux %61, %10.subreg_l32, 15, 4, implicit killed $cc
243    %65:grx32bit = AHIMux %65, 1, implicit-def dead $cc
244    %63:addr64bit = LA %63, 1, $noreg
245    CGHI %63, 0, implicit-def $cc
246    %64:addr64bit = COPY %25
247    BRC 14, 6, %bb.3, implicit killed $cc
248    J %bb.4
249
250  bb.4.bb39:
251    successors: %bb.5(0x04000000), %bb.2(0x7c000000)
252
253    %59:grx32bit = AHIMux %59, 1, implicit-def dead $cc
254    %41.subreg_l32:gr64bit = AHIMux %41.subreg_l32, 3, implicit-def dead $cc
255    CGR %60, %57, implicit-def $cc
256    BRC 14, 6, %bb.2, implicit killed $cc
257    J %bb.5
258
259  bb.5.bb42:
260    successors: %bb.6(0x30000000), %bb.7(0x50000000)
261
262    %50:gr32bit = LMux %2, 0, $noreg :: (load 4 from %ir.tmp43)
263    %50:gr32bit = nsw SR %50, %0.subreg_l32, implicit-def dead $cc
264    %52:addr64bit = LGFR %50
265    %52:addr64bit = MGHI %52, 40
266    MVC undef %53:addr64bit, 0, 4, %52, 32 :: (store 4 into `i32* undef`), (load 4 from %ir.tmp47)
267    CHIMux %32.subreg_l32, 0, implicit-def $cc
268    BRC 14, 6, %bb.7, implicit killed $cc
269    J %bb.6
270
271  bb.6.bb52:
272
273  bb.7.bb54:
274    STMux %0.subreg_l32, %2, 0, $noreg :: (store 4 into %ir.tmp56)
275    %56:addr64bit = LA %56, 1, $noreg
276    %55:gr32bit = AHIMux %55, 3, implicit-def dead $cc
277    %57:gr64bit = LGHI 0
278    J %bb.1
279
280...
281