1 ; Test 32-bit additions of constants to memory.
3 ; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
8 define zeroext i1 @f1(ptr %ptr) {
10 ; CHECK: alsi 0(%r2), 1
11 ; CHECK: ipm [[REG:%r[0-5]]]
12 ; CHECK: risbg %r2, [[REG]], 63, 191, 35
14 %a = load i32, ptr %ptr
15 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %a, i32 1)
16 %val = extractvalue {i32, i1} %t, 0
17 %obit = extractvalue {i32, i1} %t, 1
18 store i32 %val, ptr %ptr
22 ; Check the high end of the constant range.
23 define zeroext i1 @f2(ptr %ptr) {
25 ; CHECK: alsi 0(%r2), 127
26 ; CHECK: ipm [[REG:%r[0-5]]]
27 ; CHECK: risbg %r2, [[REG]], 63, 191, 35
29 %a = load i32, ptr %ptr
30 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %a, i32 127)
31 %val = extractvalue {i32, i1} %t, 0
32 %obit = extractvalue {i32, i1} %t, 1
33 store i32 %val, ptr %ptr
37 ; Check the next constant up, which must use an addition and a store.
38 define zeroext i1 @f3(i32 %dummy, ptr %ptr) {
40 ; CHECK: l [[VAL:%r[0-5]]], 0(%r3)
41 ; CHECK: alfi [[VAL]], 128
42 ; CHECK-DAG: st [[VAL]], 0(%r3)
43 ; CHECK-DAG: ipm [[REG:%r[0-5]]]
44 ; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 35
46 %a = load i32, ptr %ptr
47 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %a, i32 128)
48 %val = extractvalue {i32, i1} %t, 0
49 %obit = extractvalue {i32, i1} %t, 1
50 store i32 %val, ptr %ptr
54 ; Check the low end of the constant range.
55 define zeroext i1 @f4(ptr %ptr) {
57 ; CHECK: alsi 0(%r2), -128
58 ; CHECK: ipm [[REG:%r[0-5]]]
59 ; CHECK: risbg %r2, [[REG]], 63, 191, 35
61 %a = load i32, ptr %ptr
62 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %a, i32 -128)
63 %val = extractvalue {i32, i1} %t, 0
64 %obit = extractvalue {i32, i1} %t, 1
65 store i32 %val, ptr %ptr
69 ; Check the next value down, with the same comment as f3.
70 define zeroext i1 @f5(i32 %dummy, ptr %ptr) {
72 ; CHECK: l [[VAL:%r[0-5]]], 0(%r3)
73 ; CHECK: alfi [[VAL]], 4294967167
74 ; CHECK-DAG: st [[VAL]], 0(%r3)
75 ; CHECK-DAG: ipm [[REG:%r[0-5]]]
76 ; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 35
78 %a = load i32, ptr %ptr
79 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %a, i32 -129)
80 %val = extractvalue {i32, i1} %t, 0
81 %obit = extractvalue {i32, i1} %t, 1
82 store i32 %val, ptr %ptr
86 ; Check the high end of the aligned ALSI range.
87 define zeroext i1 @f6(ptr %base) {
89 ; CHECK: alsi 524284(%r2), 1
90 ; CHECK: ipm [[REG:%r[0-5]]]
91 ; CHECK: risbg %r2, [[REG]], 63, 191, 35
93 %ptr = getelementptr i32, ptr %base, i64 131071
94 %a = load i32, ptr %ptr
95 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %a, i32 1)
96 %val = extractvalue {i32, i1} %t, 0
97 %obit = extractvalue {i32, i1} %t, 1
98 store i32 %val, ptr %ptr
102 ; Check the next word up, which must use separate address logic.
103 ; Other sequences besides this one would be OK.
104 define zeroext i1 @f7(ptr %base) {
106 ; CHECK: agfi %r2, 524288
107 ; CHECK: alsi 0(%r2), 1
108 ; CHECK: ipm [[REG:%r[0-5]]]
109 ; CHECK: risbg %r2, [[REG]], 63, 191, 35
111 %ptr = getelementptr i32, ptr %base, i64 131072
112 %a = load i32, ptr %ptr
113 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %a, i32 1)
114 %val = extractvalue {i32, i1} %t, 0
115 %obit = extractvalue {i32, i1} %t, 1
116 store i32 %val, ptr %ptr
120 ; Check the low end of the ALSI range.
121 define zeroext i1 @f8(ptr %base) {
123 ; CHECK: alsi -524288(%r2), 1
124 ; CHECK: ipm [[REG:%r[0-5]]]
125 ; CHECK: risbg %r2, [[REG]], 63, 191, 35
127 %ptr = getelementptr i32, ptr %base, i64 -131072
128 %a = load i32, ptr %ptr
129 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %a, i32 1)
130 %val = extractvalue {i32, i1} %t, 0
131 %obit = extractvalue {i32, i1} %t, 1
132 store i32 %val, ptr %ptr
136 ; Check the next word down, which must use separate address logic.
137 ; Other sequences besides this one would be OK.
138 define zeroext i1 @f9(ptr %base) {
140 ; CHECK: agfi %r2, -524292
141 ; CHECK: alsi 0(%r2), 1
142 ; CHECK: ipm [[REG:%r[0-5]]]
143 ; CHECK: risbg %r2, [[REG]], 63, 191, 35
145 %ptr = getelementptr i32, ptr %base, i64 -131073
146 %a = load i32, ptr %ptr
147 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %a, i32 1)
148 %val = extractvalue {i32, i1} %t, 0
149 %obit = extractvalue {i32, i1} %t, 1
150 store i32 %val, ptr %ptr
154 ; Check that ALSI does not allow indices.
155 define zeroext i1 @f10(i64 %base, i64 %index) {
157 ; CHECK: agr %r2, %r3
158 ; CHECK: alsi 4(%r2), 1
159 ; CHECK: ipm [[REG:%r[0-5]]]
160 ; CHECK: risbg %r2, [[REG]], 63, 191, 35
162 %add1 = add i64 %base, %index
163 %add2 = add i64 %add1, 4
164 %ptr = inttoptr i64 %add2 to ptr
165 %a = load i32, ptr %ptr
166 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %a, i32 1)
167 %val = extractvalue {i32, i1} %t, 0
168 %obit = extractvalue {i32, i1} %t, 1
169 store i32 %val, ptr %ptr
173 ; Check that adding 127 to a spilled value can use ALSI.
174 define zeroext i1 @f11(ptr %ptr, i32 %sel) {
176 ; CHECK: alsi {{[0-9]+}}(%r15), 127
179 %val0 = load volatile i32, ptr %ptr
180 %val1 = load volatile i32, ptr %ptr
181 %val2 = load volatile i32, ptr %ptr
182 %val3 = load volatile i32, ptr %ptr
183 %val4 = load volatile i32, ptr %ptr
184 %val5 = load volatile i32, ptr %ptr
185 %val6 = load volatile i32, ptr %ptr
186 %val7 = load volatile i32, ptr %ptr
187 %val8 = load volatile i32, ptr %ptr
188 %val9 = load volatile i32, ptr %ptr
189 %val10 = load volatile i32, ptr %ptr
190 %val11 = load volatile i32, ptr %ptr
191 %val12 = load volatile i32, ptr %ptr
192 %val13 = load volatile i32, ptr %ptr
193 %val14 = load volatile i32, ptr %ptr
194 %val15 = load volatile i32, ptr %ptr
196 %test = icmp ne i32 %sel, 0
197 br i1 %test, label %add, label %store
200 %t0 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %val0, i32 127)
201 %add0 = extractvalue {i32, i1} %t0, 0
202 %obit0 = extractvalue {i32, i1} %t0, 1
203 %t1 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %val1, i32 127)
204 %add1 = extractvalue {i32, i1} %t1, 0
205 %obit1 = extractvalue {i32, i1} %t1, 1
206 %res1 = or i1 %obit0, %obit1
207 %t2 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %val2, i32 127)
208 %add2 = extractvalue {i32, i1} %t2, 0
209 %obit2 = extractvalue {i32, i1} %t2, 1
210 %res2 = or i1 %res1, %obit2
211 %t3 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %val3, i32 127)
212 %add3 = extractvalue {i32, i1} %t3, 0
213 %obit3 = extractvalue {i32, i1} %t3, 1
214 %res3 = or i1 %res2, %obit3
215 %t4 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %val4, i32 127)
216 %add4 = extractvalue {i32, i1} %t4, 0
217 %obit4 = extractvalue {i32, i1} %t4, 1
218 %res4 = or i1 %res3, %obit4
219 %t5 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %val5, i32 127)
220 %add5 = extractvalue {i32, i1} %t5, 0
221 %obit5 = extractvalue {i32, i1} %t5, 1
222 %res5 = or i1 %res4, %obit5
223 %t6 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %val6, i32 127)
224 %add6 = extractvalue {i32, i1} %t6, 0
225 %obit6 = extractvalue {i32, i1} %t6, 1
226 %res6 = or i1 %res5, %obit6
227 %t7 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %val7, i32 127)
228 %add7 = extractvalue {i32, i1} %t7, 0
229 %obit7 = extractvalue {i32, i1} %t7, 1
230 %res7 = or i1 %res6, %obit7
231 %t8 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %val8, i32 127)
232 %add8 = extractvalue {i32, i1} %t8, 0
233 %obit8 = extractvalue {i32, i1} %t8, 1
234 %res8 = or i1 %res7, %obit8
235 %t9 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %val9, i32 127)
236 %add9 = extractvalue {i32, i1} %t9, 0
237 %obit9 = extractvalue {i32, i1} %t9, 1
238 %res9 = or i1 %res8, %obit9
239 %t10 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %val10, i32 127)
240 %add10 = extractvalue {i32, i1} %t10, 0
241 %obit10 = extractvalue {i32, i1} %t10, 1
242 %res10 = or i1 %res9, %obit10
243 %t11 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %val11, i32 127)
244 %add11 = extractvalue {i32, i1} %t11, 0
245 %obit11 = extractvalue {i32, i1} %t11, 1
246 %res11 = or i1 %res10, %obit11
247 %t12 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %val12, i32 127)
248 %add12 = extractvalue {i32, i1} %t12, 0
249 %obit12 = extractvalue {i32, i1} %t12, 1
250 %res12 = or i1 %res11, %obit12
251 %t13 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %val13, i32 127)
252 %add13 = extractvalue {i32, i1} %t13, 0
253 %obit13 = extractvalue {i32, i1} %t13, 1
254 %res13 = or i1 %res12, %obit13
255 %t14 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %val14, i32 127)
256 %add14 = extractvalue {i32, i1} %t14, 0
257 %obit14 = extractvalue {i32, i1} %t14, 1
258 %res14 = or i1 %res13, %obit14
259 %t15 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %val15, i32 127)
260 %add15 = extractvalue {i32, i1} %t15, 0
261 %obit15 = extractvalue {i32, i1} %t15, 1
262 %res15 = or i1 %res14, %obit15
267 %new0 = phi i32 [ %val0, %entry ], [ %add0, %add ]
268 %new1 = phi i32 [ %val1, %entry ], [ %add1, %add ]
269 %new2 = phi i32 [ %val2, %entry ], [ %add2, %add ]
270 %new3 = phi i32 [ %val3, %entry ], [ %add3, %add ]
271 %new4 = phi i32 [ %val4, %entry ], [ %add4, %add ]
272 %new5 = phi i32 [ %val5, %entry ], [ %add5, %add ]
273 %new6 = phi i32 [ %val6, %entry ], [ %add6, %add ]
274 %new7 = phi i32 [ %val7, %entry ], [ %add7, %add ]
275 %new8 = phi i32 [ %val8, %entry ], [ %add8, %add ]
276 %new9 = phi i32 [ %val9, %entry ], [ %add9, %add ]
277 %new10 = phi i32 [ %val10, %entry ], [ %add10, %add ]
278 %new11 = phi i32 [ %val11, %entry ], [ %add11, %add ]
279 %new12 = phi i32 [ %val12, %entry ], [ %add12, %add ]
280 %new13 = phi i32 [ %val13, %entry ], [ %add13, %add ]
281 %new14 = phi i32 [ %val14, %entry ], [ %add14, %add ]
282 %new15 = phi i32 [ %val15, %entry ], [ %add15, %add ]
283 %res = phi i1 [ 0, %entry ], [ %res15, %add ]
285 store volatile i32 %new0, ptr %ptr
286 store volatile i32 %new1, ptr %ptr
287 store volatile i32 %new2, ptr %ptr
288 store volatile i32 %new3, ptr %ptr
289 store volatile i32 %new4, ptr %ptr
290 store volatile i32 %new5, ptr %ptr
291 store volatile i32 %new6, ptr %ptr
292 store volatile i32 %new7, ptr %ptr
293 store volatile i32 %new8, ptr %ptr
294 store volatile i32 %new9, ptr %ptr
295 store volatile i32 %new10, ptr %ptr
296 store volatile i32 %new11, ptr %ptr
297 store volatile i32 %new12, ptr %ptr
298 store volatile i32 %new13, ptr %ptr
299 store volatile i32 %new14, ptr %ptr
300 store volatile i32 %new15, ptr %ptr
305 ; Check that adding -128 to a spilled value can use ALSI.
306 define zeroext i1 @f12(ptr %ptr, i32 %sel) {
308 ; CHECK: alsi {{[0-9]+}}(%r15), -128
311 %val0 = load volatile i32, ptr %ptr
312 %val1 = load volatile i32, ptr %ptr
313 %val2 = load volatile i32, ptr %ptr
314 %val3 = load volatile i32, ptr %ptr
315 %val4 = load volatile i32, ptr %ptr
316 %val5 = load volatile i32, ptr %ptr
317 %val6 = load volatile i32, ptr %ptr
318 %val7 = load volatile i32, ptr %ptr
319 %val8 = load volatile i32, ptr %ptr
320 %val9 = load volatile i32, ptr %ptr
321 %val10 = load volatile i32, ptr %ptr
322 %val11 = load volatile i32, ptr %ptr
323 %val12 = load volatile i32, ptr %ptr
324 %val13 = load volatile i32, ptr %ptr
325 %val14 = load volatile i32, ptr %ptr
326 %val15 = load volatile i32, ptr %ptr
328 %test = icmp ne i32 %sel, 0
329 br i1 %test, label %add, label %store
332 %t0 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %val0, i32 -128)
333 %add0 = extractvalue {i32, i1} %t0, 0
334 %obit0 = extractvalue {i32, i1} %t0, 1
335 %t1 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %val1, i32 -128)
336 %add1 = extractvalue {i32, i1} %t1, 0
337 %obit1 = extractvalue {i32, i1} %t1, 1
338 %res1 = or i1 %obit0, %obit1
339 %t2 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %val2, i32 -128)
340 %add2 = extractvalue {i32, i1} %t2, 0
341 %obit2 = extractvalue {i32, i1} %t2, 1
342 %res2 = or i1 %res1, %obit2
343 %t3 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %val3, i32 -128)
344 %add3 = extractvalue {i32, i1} %t3, 0
345 %obit3 = extractvalue {i32, i1} %t3, 1
346 %res3 = or i1 %res2, %obit3
347 %t4 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %val4, i32 -128)
348 %add4 = extractvalue {i32, i1} %t4, 0
349 %obit4 = extractvalue {i32, i1} %t4, 1
350 %res4 = or i1 %res3, %obit4
351 %t5 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %val5, i32 -128)
352 %add5 = extractvalue {i32, i1} %t5, 0
353 %obit5 = extractvalue {i32, i1} %t5, 1
354 %res5 = or i1 %res4, %obit5
355 %t6 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %val6, i32 -128)
356 %add6 = extractvalue {i32, i1} %t6, 0
357 %obit6 = extractvalue {i32, i1} %t6, 1
358 %res6 = or i1 %res5, %obit6
359 %t7 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %val7, i32 -128)
360 %add7 = extractvalue {i32, i1} %t7, 0
361 %obit7 = extractvalue {i32, i1} %t7, 1
362 %res7 = or i1 %res6, %obit7
363 %t8 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %val8, i32 -128)
364 %add8 = extractvalue {i32, i1} %t8, 0
365 %obit8 = extractvalue {i32, i1} %t8, 1
366 %res8 = or i1 %res7, %obit8
367 %t9 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %val9, i32 -128)
368 %add9 = extractvalue {i32, i1} %t9, 0
369 %obit9 = extractvalue {i32, i1} %t9, 1
370 %res9 = or i1 %res8, %obit9
371 %t10 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %val10, i32 -128)
372 %add10 = extractvalue {i32, i1} %t10, 0
373 %obit10 = extractvalue {i32, i1} %t10, 1
374 %res10 = or i1 %res9, %obit10
375 %t11 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %val11, i32 -128)
376 %add11 = extractvalue {i32, i1} %t11, 0
377 %obit11 = extractvalue {i32, i1} %t11, 1
378 %res11 = or i1 %res10, %obit11
379 %t12 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %val12, i32 -128)
380 %add12 = extractvalue {i32, i1} %t12, 0
381 %obit12 = extractvalue {i32, i1} %t12, 1
382 %res12 = or i1 %res11, %obit12
383 %t13 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %val13, i32 -128)
384 %add13 = extractvalue {i32, i1} %t13, 0
385 %obit13 = extractvalue {i32, i1} %t13, 1
386 %res13 = or i1 %res12, %obit13
387 %t14 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %val14, i32 -128)
388 %add14 = extractvalue {i32, i1} %t14, 0
389 %obit14 = extractvalue {i32, i1} %t14, 1
390 %res14 = or i1 %res13, %obit14
391 %t15 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %val15, i32 -128)
392 %add15 = extractvalue {i32, i1} %t15, 0
393 %obit15 = extractvalue {i32, i1} %t15, 1
394 %res15 = or i1 %res14, %obit15
399 %new0 = phi i32 [ %val0, %entry ], [ %add0, %add ]
400 %new1 = phi i32 [ %val1, %entry ], [ %add1, %add ]
401 %new2 = phi i32 [ %val2, %entry ], [ %add2, %add ]
402 %new3 = phi i32 [ %val3, %entry ], [ %add3, %add ]
403 %new4 = phi i32 [ %val4, %entry ], [ %add4, %add ]
404 %new5 = phi i32 [ %val5, %entry ], [ %add5, %add ]
405 %new6 = phi i32 [ %val6, %entry ], [ %add6, %add ]
406 %new7 = phi i32 [ %val7, %entry ], [ %add7, %add ]
407 %new8 = phi i32 [ %val8, %entry ], [ %add8, %add ]
408 %new9 = phi i32 [ %val9, %entry ], [ %add9, %add ]
409 %new10 = phi i32 [ %val10, %entry ], [ %add10, %add ]
410 %new11 = phi i32 [ %val11, %entry ], [ %add11, %add ]
411 %new12 = phi i32 [ %val12, %entry ], [ %add12, %add ]
412 %new13 = phi i32 [ %val13, %entry ], [ %add13, %add ]
413 %new14 = phi i32 [ %val14, %entry ], [ %add14, %add ]
414 %new15 = phi i32 [ %val15, %entry ], [ %add15, %add ]
415 %res = phi i1 [ 0, %entry ], [ %res15, %add ]
417 store volatile i32 %new0, ptr %ptr
418 store volatile i32 %new1, ptr %ptr
419 store volatile i32 %new2, ptr %ptr
420 store volatile i32 %new3, ptr %ptr
421 store volatile i32 %new4, ptr %ptr
422 store volatile i32 %new5, ptr %ptr
423 store volatile i32 %new6, ptr %ptr
424 store volatile i32 %new7, ptr %ptr
425 store volatile i32 %new8, ptr %ptr
426 store volatile i32 %new9, ptr %ptr
427 store volatile i32 %new10, ptr %ptr
428 store volatile i32 %new11, ptr %ptr
429 store volatile i32 %new12, ptr %ptr
430 store volatile i32 %new13, ptr %ptr
431 store volatile i32 %new14, ptr %ptr
432 store volatile i32 %new15, ptr %ptr
437 ; Check using the overflow result for a branch.
438 define void @f13(ptr %ptr) {
440 ; CHECK: alsi 0(%r2), 1
441 ; CHECK: jgnle foo@PLT
443 %a = load i32, ptr %ptr
444 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %a, i32 1)
445 %val = extractvalue {i32, i1} %t, 0
446 %obit = extractvalue {i32, i1} %t, 1
447 store i32 %val, ptr %ptr
448 br i1 %obit, label %call, label %exit
458 ; ... and the same with the inverted direction.
459 define void @f14(ptr %ptr) {
461 ; CHECK: alsi 0(%r2), 1
462 ; CHECK: jgle foo@PLT
464 %a = load i32, ptr %ptr
465 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %a, i32 1)
466 %val = extractvalue {i32, i1} %t, 0
467 %obit = extractvalue {i32, i1} %t, 1
468 store i32 %val, ptr %ptr
469 br i1 %obit, label %exit, label %call
479 declare {i32, i1} @llvm.uadd.with.overflow.i32(i32, i32) nounwind readnone