1; Test 32-bit additions of constants to memory.  The tests here
2; assume z10 register pressure, without the high words being available.
3;
4; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 | FileCheck %s
5
6; Check additions of 1.
7define void @f1(i32 *%ptr) {
8; CHECK-LABEL: f1:
9; CHECK: asi 0(%r2), 1
10; CHECK: br %r14
11  %val = load i32, i32 *%ptr
12  %add = add i32 %val, 127
13  store i32 %add, i32 *%ptr
14  ret void
15}
16
17; Check the high end of the constant range.
18define void @f2(i32 *%ptr) {
19; CHECK-LABEL: f2:
20; CHECK: asi 0(%r2), 127
21; CHECK: br %r14
22  %val = load i32, i32 *%ptr
23  %add = add i32 %val, 127
24  store i32 %add, i32 *%ptr
25  ret void
26}
27
28; Check the next constant up, which must use an addition and a store.
29; Both L/AHI and LHI/A would be OK.
30define void @f3(i32 *%ptr) {
31; CHECK-LABEL: f3:
32; CHECK-NOT: asi
33; CHECK: st %r0, 0(%r2)
34; CHECK: br %r14
35  %val = load i32, i32 *%ptr
36  %add = add i32 %val, 128
37  store i32 %add, i32 *%ptr
38  ret void
39}
40
41; Check the low end of the constant range.
42define void @f4(i32 *%ptr) {
43; CHECK-LABEL: f4:
44; CHECK: asi 0(%r2), -128
45; CHECK: br %r14
46  %val = load i32, i32 *%ptr
47  %add = add i32 %val, -128
48  store i32 %add, i32 *%ptr
49  ret void
50}
51
52; Check the next value down, with the same comment as f3.
53define void @f5(i32 *%ptr) {
54; CHECK-LABEL: f5:
55; CHECK-NOT: asi
56; CHECK: st %r0, 0(%r2)
57; CHECK: br %r14
58  %val = load i32, i32 *%ptr
59  %add = add i32 %val, -129
60  store i32 %add, i32 *%ptr
61  ret void
62}
63
64; Check the high end of the aligned ASI range.
65define void @f6(i32 *%base) {
66; CHECK-LABEL: f6:
67; CHECK: asi 524284(%r2), 1
68; CHECK: br %r14
69  %ptr = getelementptr i32, i32 *%base, i64 131071
70  %val = load i32, i32 *%ptr
71  %add = add i32 %val, 1
72  store i32 %add, i32 *%ptr
73  ret void
74}
75
76; Check the next word up, which must use separate address logic.
77; Other sequences besides this one would be OK.
78define void @f7(i32 *%base) {
79; CHECK-LABEL: f7:
80; CHECK: agfi %r2, 524288
81; CHECK: asi 0(%r2), 1
82; CHECK: br %r14
83  %ptr = getelementptr i32, i32 *%base, i64 131072
84  %val = load i32, i32 *%ptr
85  %add = add i32 %val, 1
86  store i32 %add, i32 *%ptr
87  ret void
88}
89
90; Check the low end of the ASI range.
91define void @f8(i32 *%base) {
92; CHECK-LABEL: f8:
93; CHECK: asi -524288(%r2), 1
94; CHECK: br %r14
95  %ptr = getelementptr i32, i32 *%base, i64 -131072
96  %val = load i32, i32 *%ptr
97  %add = add i32 %val, 1
98  store i32 %add, i32 *%ptr
99  ret void
100}
101
102; Check the next word down, which must use separate address logic.
103; Other sequences besides this one would be OK.
104define void @f9(i32 *%base) {
105; CHECK-LABEL: f9:
106; CHECK: agfi %r2, -524292
107; CHECK: asi 0(%r2), 1
108; CHECK: br %r14
109  %ptr = getelementptr i32, i32 *%base, i64 -131073
110  %val = load i32, i32 *%ptr
111  %add = add i32 %val, 1
112  store i32 %add, i32 *%ptr
113  ret void
114}
115
116; Check that ASI does not allow indices.
117define void @f10(i64 %base, i64 %index) {
118; CHECK-LABEL: f10:
119; CHECK: agr %r2, %r3
120; CHECK: asi 4(%r2), 1
121; CHECK: br %r14
122  %add1 = add i64 %base, %index
123  %add2 = add i64 %add1, 4
124  %ptr = inttoptr i64 %add2 to i32 *
125  %val = load i32, i32 *%ptr
126  %add = add i32 %val, 1
127  store i32 %add, i32 *%ptr
128  ret void
129}
130
131; Check that adding 127 to a spilled value can use ASI.
132define void @f11(i32 *%ptr, i32 %sel) {
133; CHECK-LABEL: f11:
134; CHECK: asi {{[0-9]+}}(%r15), 127
135; CHECK: br %r14
136entry:
137  %val0 = load volatile i32, i32 *%ptr
138  %val1 = load volatile i32, i32 *%ptr
139  %val2 = load volatile i32, i32 *%ptr
140  %val3 = load volatile i32, i32 *%ptr
141  %val4 = load volatile i32, i32 *%ptr
142  %val5 = load volatile i32, i32 *%ptr
143  %val6 = load volatile i32, i32 *%ptr
144  %val7 = load volatile i32, i32 *%ptr
145  %val8 = load volatile i32, i32 *%ptr
146  %val9 = load volatile i32, i32 *%ptr
147  %val10 = load volatile i32, i32 *%ptr
148  %val11 = load volatile i32, i32 *%ptr
149  %val12 = load volatile i32, i32 *%ptr
150  %val13 = load volatile i32, i32 *%ptr
151  %val14 = load volatile i32, i32 *%ptr
152  %val15 = load volatile i32, i32 *%ptr
153
154  %test = icmp ne i32 %sel, 0
155  br i1 %test, label %add, label %store
156
157add:
158  %add0 = add i32 %val0, 127
159  %add1 = add i32 %val1, 127
160  %add2 = add i32 %val2, 127
161  %add3 = add i32 %val3, 127
162  %add4 = add i32 %val4, 127
163  %add5 = add i32 %val5, 127
164  %add6 = add i32 %val6, 127
165  %add7 = add i32 %val7, 127
166  %add8 = add i32 %val8, 127
167  %add9 = add i32 %val9, 127
168  %add10 = add i32 %val10, 127
169  %add11 = add i32 %val11, 127
170  %add12 = add i32 %val12, 127
171  %add13 = add i32 %val13, 127
172  %add14 = add i32 %val14, 127
173  %add15 = add i32 %val15, 127
174  br label %store
175
176store:
177  %new0 = phi i32 [ %val0, %entry ], [ %add0, %add ]
178  %new1 = phi i32 [ %val1, %entry ], [ %add1, %add ]
179  %new2 = phi i32 [ %val2, %entry ], [ %add2, %add ]
180  %new3 = phi i32 [ %val3, %entry ], [ %add3, %add ]
181  %new4 = phi i32 [ %val4, %entry ], [ %add4, %add ]
182  %new5 = phi i32 [ %val5, %entry ], [ %add5, %add ]
183  %new6 = phi i32 [ %val6, %entry ], [ %add6, %add ]
184  %new7 = phi i32 [ %val7, %entry ], [ %add7, %add ]
185  %new8 = phi i32 [ %val8, %entry ], [ %add8, %add ]
186  %new9 = phi i32 [ %val9, %entry ], [ %add9, %add ]
187  %new10 = phi i32 [ %val10, %entry ], [ %add10, %add ]
188  %new11 = phi i32 [ %val11, %entry ], [ %add11, %add ]
189  %new12 = phi i32 [ %val12, %entry ], [ %add12, %add ]
190  %new13 = phi i32 [ %val13, %entry ], [ %add13, %add ]
191  %new14 = phi i32 [ %val14, %entry ], [ %add14, %add ]
192  %new15 = phi i32 [ %val15, %entry ], [ %add15, %add ]
193
194  store volatile i32 %new0, i32 *%ptr
195  store volatile i32 %new1, i32 *%ptr
196  store volatile i32 %new2, i32 *%ptr
197  store volatile i32 %new3, i32 *%ptr
198  store volatile i32 %new4, i32 *%ptr
199  store volatile i32 %new5, i32 *%ptr
200  store volatile i32 %new6, i32 *%ptr
201  store volatile i32 %new7, i32 *%ptr
202  store volatile i32 %new8, i32 *%ptr
203  store volatile i32 %new9, i32 *%ptr
204  store volatile i32 %new10, i32 *%ptr
205  store volatile i32 %new11, i32 *%ptr
206  store volatile i32 %new12, i32 *%ptr
207  store volatile i32 %new13, i32 *%ptr
208  store volatile i32 %new14, i32 *%ptr
209  store volatile i32 %new15, i32 *%ptr
210
211  ret void
212}
213
214; Check that adding -128 to a spilled value can use ASI.
215define void @f12(i32 *%ptr, i32 %sel) {
216; CHECK-LABEL: f12:
217; CHECK: asi {{[0-9]+}}(%r15), -128
218; CHECK: br %r14
219entry:
220  %val0 = load volatile i32, i32 *%ptr
221  %val1 = load volatile i32, i32 *%ptr
222  %val2 = load volatile i32, i32 *%ptr
223  %val3 = load volatile i32, i32 *%ptr
224  %val4 = load volatile i32, i32 *%ptr
225  %val5 = load volatile i32, i32 *%ptr
226  %val6 = load volatile i32, i32 *%ptr
227  %val7 = load volatile i32, i32 *%ptr
228  %val8 = load volatile i32, i32 *%ptr
229  %val9 = load volatile i32, i32 *%ptr
230  %val10 = load volatile i32, i32 *%ptr
231  %val11 = load volatile i32, i32 *%ptr
232  %val12 = load volatile i32, i32 *%ptr
233  %val13 = load volatile i32, i32 *%ptr
234  %val14 = load volatile i32, i32 *%ptr
235  %val15 = load volatile i32, i32 *%ptr
236
237  %test = icmp ne i32 %sel, 0
238  br i1 %test, label %add, label %store
239
240add:
241  %add0 = add i32 %val0, -128
242  %add1 = add i32 %val1, -128
243  %add2 = add i32 %val2, -128
244  %add3 = add i32 %val3, -128
245  %add4 = add i32 %val4, -128
246  %add5 = add i32 %val5, -128
247  %add6 = add i32 %val6, -128
248  %add7 = add i32 %val7, -128
249  %add8 = add i32 %val8, -128
250  %add9 = add i32 %val9, -128
251  %add10 = add i32 %val10, -128
252  %add11 = add i32 %val11, -128
253  %add12 = add i32 %val12, -128
254  %add13 = add i32 %val13, -128
255  %add14 = add i32 %val14, -128
256  %add15 = add i32 %val15, -128
257  br label %store
258
259store:
260  %new0 = phi i32 [ %val0, %entry ], [ %add0, %add ]
261  %new1 = phi i32 [ %val1, %entry ], [ %add1, %add ]
262  %new2 = phi i32 [ %val2, %entry ], [ %add2, %add ]
263  %new3 = phi i32 [ %val3, %entry ], [ %add3, %add ]
264  %new4 = phi i32 [ %val4, %entry ], [ %add4, %add ]
265  %new5 = phi i32 [ %val5, %entry ], [ %add5, %add ]
266  %new6 = phi i32 [ %val6, %entry ], [ %add6, %add ]
267  %new7 = phi i32 [ %val7, %entry ], [ %add7, %add ]
268  %new8 = phi i32 [ %val8, %entry ], [ %add8, %add ]
269  %new9 = phi i32 [ %val9, %entry ], [ %add9, %add ]
270  %new10 = phi i32 [ %val10, %entry ], [ %add10, %add ]
271  %new11 = phi i32 [ %val11, %entry ], [ %add11, %add ]
272  %new12 = phi i32 [ %val12, %entry ], [ %add12, %add ]
273  %new13 = phi i32 [ %val13, %entry ], [ %add13, %add ]
274  %new14 = phi i32 [ %val14, %entry ], [ %add14, %add ]
275  %new15 = phi i32 [ %val15, %entry ], [ %add15, %add ]
276
277  store volatile i32 %new0, i32 *%ptr
278  store volatile i32 %new1, i32 *%ptr
279  store volatile i32 %new2, i32 *%ptr
280  store volatile i32 %new3, i32 *%ptr
281  store volatile i32 %new4, i32 *%ptr
282  store volatile i32 %new5, i32 *%ptr
283  store volatile i32 %new6, i32 *%ptr
284  store volatile i32 %new7, i32 *%ptr
285  store volatile i32 %new8, i32 *%ptr
286  store volatile i32 %new9, i32 *%ptr
287  store volatile i32 %new10, i32 *%ptr
288  store volatile i32 %new11, i32 *%ptr
289  store volatile i32 %new12, i32 *%ptr
290  store volatile i32 %new13, i32 *%ptr
291  store volatile i32 %new14, i32 *%ptr
292  store volatile i32 %new15, i32 *%ptr
293
294  ret void
295}
296