AArch64/ARM64: move ARM64 into AArch64's place
[oota-llvm.git] / test / CodeGen / AArch64 / arm64-xaluo.ll
1 ; RUN: llc < %s -march=arm64 | FileCheck %s
2
3 ;
4 ; Get the actual value of the overflow bit.
5 ;
6 define i1 @saddo.i32(i32 %v1, i32 %v2, i32* %res) {
7 entry:
8 ; CHECK-LABEL:  saddo.i32
9 ; CHECK:        adds w8, w0, w1
10 ; CHECK-NEXT:   cset w0, vs
11   %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2)
12   %val = extractvalue {i32, i1} %t, 0
13   %obit = extractvalue {i32, i1} %t, 1
14   store i32 %val, i32* %res
15   ret i1 %obit
16 }
17
18 define i1 @saddo.i64(i64 %v1, i64 %v2, i64* %res) {
19 entry:
20 ; CHECK-LABEL:  saddo.i64
21 ; CHECK:        adds x8, x0, x1
22 ; CHECK-NEXT:   cset w0, vs
23   %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2)
24   %val = extractvalue {i64, i1} %t, 0
25   %obit = extractvalue {i64, i1} %t, 1
26   store i64 %val, i64* %res
27   ret i1 %obit
28 }
29
30 define i1 @uaddo.i32(i32 %v1, i32 %v2, i32* %res) {
31 entry:
32 ; CHECK-LABEL:  uaddo.i32
33 ; CHECK:        adds w8, w0, w1
34 ; CHECK-NEXT:   cset w0, hs
35   %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)
36   %val = extractvalue {i32, i1} %t, 0
37   %obit = extractvalue {i32, i1} %t, 1
38   store i32 %val, i32* %res
39   ret i1 %obit
40 }
41
42 define i1 @uaddo.i64(i64 %v1, i64 %v2, i64* %res) {
43 entry:
44 ; CHECK-LABEL:  uaddo.i64
45 ; CHECK:        adds x8, x0, x1
46 ; CHECK-NEXT:   cset w0, hs
47   %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2)
48   %val = extractvalue {i64, i1} %t, 0
49   %obit = extractvalue {i64, i1} %t, 1
50   store i64 %val, i64* %res
51   ret i1 %obit
52 }
53
54 define i1 @ssubo.i32(i32 %v1, i32 %v2, i32* %res) {
55 entry:
56 ; CHECK-LABEL:  ssubo.i32
57 ; CHECK:        subs w8, w0, w1
58 ; CHECK-NEXT:   cset w0, vs
59   %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2)
60   %val = extractvalue {i32, i1} %t, 0
61   %obit = extractvalue {i32, i1} %t, 1
62   store i32 %val, i32* %res
63   ret i1 %obit
64 }
65
66 define i1 @ssubo.i64(i64 %v1, i64 %v2, i64* %res) {
67 entry:
68 ; CHECK-LABEL:  ssubo.i64
69 ; CHECK:        subs x8, x0, x1
70 ; CHECK-NEXT:   cset w0, vs
71   %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2)
72   %val = extractvalue {i64, i1} %t, 0
73   %obit = extractvalue {i64, i1} %t, 1
74   store i64 %val, i64* %res
75   ret i1 %obit
76 }
77
78 define i1 @usubo.i32(i32 %v1, i32 %v2, i32* %res) {
79 entry:
80 ; CHECK-LABEL:  usubo.i32
81 ; CHECK:        subs w8, w0, w1
82 ; CHECK-NEXT:   cset w0, lo
83   %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2)
84   %val = extractvalue {i32, i1} %t, 0
85   %obit = extractvalue {i32, i1} %t, 1
86   store i32 %val, i32* %res
87   ret i1 %obit
88 }
89
90 define i1 @usubo.i64(i64 %v1, i64 %v2, i64* %res) {
91 entry:
92 ; CHECK-LABEL:  usubo.i64
93 ; CHECK:        subs x8, x0, x1
94 ; CHECK-NEXT:   cset w0, lo
95   %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2)
96   %val = extractvalue {i64, i1} %t, 0
97   %obit = extractvalue {i64, i1} %t, 1
98   store i64 %val, i64* %res
99   ret i1 %obit
100 }
101
102 define i1 @smulo.i32(i32 %v1, i32 %v2, i32* %res) {
103 entry:
104 ; CHECK-LABEL:  smulo.i32
105 ; CHECK:        smull x8, w0, w1
106 ; CHECK-NEXT:   lsr x9, x8, #32
107 ; CHECK-NEXT:   cmp w9, w8, asr #31
108 ; CHECK-NEXT:   cset w0, ne
109   %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
110   %val = extractvalue {i32, i1} %t, 0
111   %obit = extractvalue {i32, i1} %t, 1
112   store i32 %val, i32* %res
113   ret i1 %obit
114 }
115
116 define i1 @smulo.i64(i64 %v1, i64 %v2, i64* %res) {
117 entry:
118 ; CHECK-LABEL:  smulo.i64
119 ; CHECK:        mul x8, x0, x1
120 ; CHECK-NEXT:   smulh x9, x0, x1
121 ; CHECK-NEXT:   cmp x9, x8, asr #63
122 ; CHECK-NEXT:   cset w0, ne
123   %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
124   %val = extractvalue {i64, i1} %t, 0
125   %obit = extractvalue {i64, i1} %t, 1
126   store i64 %val, i64* %res
127   ret i1 %obit
128 }
129
130 define i1 @umulo.i32(i32 %v1, i32 %v2, i32* %res) {
131 entry:
132 ; CHECK-LABEL:  umulo.i32
133 ; CHECK:        umull x8, w0, w1
134 ; CHECK-NEXT:   cmp xzr, x8, lsr #32
135 ; CHECK-NEXT:   cset w0, ne
136   %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
137   %val = extractvalue {i32, i1} %t, 0
138   %obit = extractvalue {i32, i1} %t, 1
139   store i32 %val, i32* %res
140   ret i1 %obit
141 }
142
143 define i1 @umulo.i64(i64 %v1, i64 %v2, i64* %res) {
144 entry:
145 ; CHECK-LABEL:  umulo.i64
146 ; CHECK:        umulh x8, x0, x1
147 ; CHECK-NEXT:   cmp xzr, x8
148 ; CHECK-NEXT:   cset w8, ne
149 ; CHECK-NEXT:   mul x9, x0, x1
150   %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
151   %val = extractvalue {i64, i1} %t, 0
152   %obit = extractvalue {i64, i1} %t, 1
153   store i64 %val, i64* %res
154   ret i1 %obit
155 }
156
157
158 ;
159 ; Check the use of the overflow bit in combination with a select instruction.
160 ;
161 define i32 @saddo.select.i32(i32 %v1, i32 %v2) {
162 entry:
163 ; CHECK-LABEL:  saddo.select.i32
164 ; CHECK:        cmn w0, w1
165 ; CHECK-NEXT:   csel w0, w0, w1, vs
166   %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2)
167   %obit = extractvalue {i32, i1} %t, 1
168   %ret = select i1 %obit, i32 %v1, i32 %v2
169   ret i32 %ret
170 }
171
172 define i64 @saddo.select.i64(i64 %v1, i64 %v2) {
173 entry:
174 ; CHECK-LABEL:  saddo.select.i64
175 ; CHECK:        cmn x0, x1
176 ; CHECK-NEXT:   csel x0, x0, x1, vs
177   %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2)
178   %obit = extractvalue {i64, i1} %t, 1
179   %ret = select i1 %obit, i64 %v1, i64 %v2
180   ret i64 %ret
181 }
182
183 define i32 @uaddo.select.i32(i32 %v1, i32 %v2) {
184 entry:
185 ; CHECK-LABEL:  uaddo.select.i32
186 ; CHECK:        cmn w0, w1
187 ; CHECK-NEXT:   csel w0, w0, w1, hs
188   %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)
189   %obit = extractvalue {i32, i1} %t, 1
190   %ret = select i1 %obit, i32 %v1, i32 %v2
191   ret i32 %ret
192 }
193
194 define i64 @uaddo.select.i64(i64 %v1, i64 %v2) {
195 entry:
196 ; CHECK-LABEL:  uaddo.select.i64
197 ; CHECK:        cmn x0, x1
198 ; CHECK-NEXT:   csel x0, x0, x1, hs
199   %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2)
200   %obit = extractvalue {i64, i1} %t, 1
201   %ret = select i1 %obit, i64 %v1, i64 %v2
202   ret i64 %ret
203 }
204
205 define i32 @ssubo.select.i32(i32 %v1, i32 %v2) {
206 entry:
207 ; CHECK-LABEL:  ssubo.select.i32
208 ; CHECK:        cmp w0, w1
209 ; CHECK-NEXT:   csel w0, w0, w1, vs
210   %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2)
211   %obit = extractvalue {i32, i1} %t, 1
212   %ret = select i1 %obit, i32 %v1, i32 %v2
213   ret i32 %ret
214 }
215
216 define i64 @ssubo.select.i64(i64 %v1, i64 %v2) {
217 entry:
218 ; CHECK-LABEL:  ssubo.select.i64
219 ; CHECK:        cmp x0, x1
220 ; CHECK-NEXT:   csel x0, x0, x1, vs
221   %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2)
222   %obit = extractvalue {i64, i1} %t, 1
223   %ret = select i1 %obit, i64 %v1, i64 %v2
224   ret i64 %ret
225 }
226
227 define i32 @usubo.select.i32(i32 %v1, i32 %v2) {
228 entry:
229 ; CHECK-LABEL:  usubo.select.i32
230 ; CHECK:        cmp w0, w1
231 ; CHECK-NEXT:   csel w0, w0, w1, lo
232   %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2)
233   %obit = extractvalue {i32, i1} %t, 1
234   %ret = select i1 %obit, i32 %v1, i32 %v2
235   ret i32 %ret
236 }
237
238 define i64 @usubo.select.i64(i64 %v1, i64 %v2) {
239 entry:
240 ; CHECK-LABEL:  usubo.select.i64
241 ; CHECK:        cmp x0, x1
242 ; CHECK-NEXT:   csel x0, x0, x1, lo
243   %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2)
244   %obit = extractvalue {i64, i1} %t, 1
245   %ret = select i1 %obit, i64 %v1, i64 %v2
246   ret i64 %ret
247 }
248
249 define i32 @smulo.select.i32(i32 %v1, i32 %v2) {
250 entry:
251 ; CHECK-LABEL:  smulo.select.i32
252 ; CHECK:        smull    x8, w0, w1
253 ; CHECK-NEXT:   lsr     x9, x8, #32
254 ; CHECK-NEXT:   cmp     w9, w8, asr #31
255 ; CHECK-NEXT:   csel    w0, w0, w1, ne
256   %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
257   %obit = extractvalue {i32, i1} %t, 1
258   %ret = select i1 %obit, i32 %v1, i32 %v2
259   ret i32 %ret
260 }
261
262 define i64 @smulo.select.i64(i64 %v1, i64 %v2) {
263 entry:
264 ; CHECK-LABEL:  smulo.select.i64
265 ; CHECK:        mul      x8, x0, x1
266 ; CHECK-NEXT:   smulh   x9, x0, x1
267 ; CHECK-NEXT:   cmp     x9, x8, asr #63
268 ; CHECK-NEXT:   csel    x0, x0, x1, ne
269   %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
270   %obit = extractvalue {i64, i1} %t, 1
271   %ret = select i1 %obit, i64 %v1, i64 %v2
272   ret i64 %ret
273 }
274
275 define i32 @umulo.select.i32(i32 %v1, i32 %v2) {
276 entry:
277 ; CHECK-LABEL:  umulo.select.i32
278 ; CHECK:        umull    x8, w0, w1
279 ; CHECK-NEXT:   cmp     xzr, x8, lsr #32
280 ; CHECK-NEXT:   csel    w0, w0, w1, ne
281   %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
282   %obit = extractvalue {i32, i1} %t, 1
283   %ret = select i1 %obit, i32 %v1, i32 %v2
284   ret i32 %ret
285 }
286
287 define i64 @umulo.select.i64(i64 %v1, i64 %v2) {
288 entry:
289 ; CHECK-LABEL:  umulo.select.i64
290 ; CHECK:        umulh   x8, x0, x1
291 ; CHECK-NEXT:   cmp     xzr, x8
292 ; CHECK-NEXT:   csel    x0, x0, x1, ne
293   %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
294   %obit = extractvalue {i64, i1} %t, 1
295   %ret = select i1 %obit, i64 %v1, i64 %v2
296   ret i64 %ret
297 }
298
299
300 ;
301 ; Check the use of the overflow bit in combination with a branch instruction.
302 ;
303 define i1 @saddo.br.i32(i32 %v1, i32 %v2) {
304 entry:
305 ; CHECK-LABEL:  saddo.br.i32
306 ; CHECK:        cmn w0, w1
307 ; CHECK-NEXT:   b.vc
308   %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2)
309   %val = extractvalue {i32, i1} %t, 0
310   %obit = extractvalue {i32, i1} %t, 1
311   br i1 %obit, label %overflow, label %continue
312
313 overflow:
314   ret i1 false
315
316 continue:
317   ret i1 true
318 }
319
320 define i1 @saddo.br.i64(i64 %v1, i64 %v2) {
321 entry:
322 ; CHECK-LABEL:  saddo.br.i64
323 ; CHECK:        cmn x0, x1
324 ; CHECK-NEXT:   b.vc
325   %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2)
326   %val = extractvalue {i64, i1} %t, 0
327   %obit = extractvalue {i64, i1} %t, 1
328   br i1 %obit, label %overflow, label %continue
329
330 overflow:
331   ret i1 false
332
333 continue:
334   ret i1 true
335 }
336
337 define i1 @uaddo.br.i32(i32 %v1, i32 %v2) {
338 entry:
339 ; CHECK-LABEL:  uaddo.br.i32
340 ; CHECK:        cmn w0, w1
341 ; CHECK-NEXT:   b.lo
342   %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)
343   %val = extractvalue {i32, i1} %t, 0
344   %obit = extractvalue {i32, i1} %t, 1
345   br i1 %obit, label %overflow, label %continue
346
347 overflow:
348   ret i1 false
349
350 continue:
351   ret i1 true
352 }
353
354 define i1 @uaddo.br.i64(i64 %v1, i64 %v2) {
355 entry:
356 ; CHECK-LABEL:  uaddo.br.i64
357 ; CHECK:        cmn x0, x1
358 ; CHECK-NEXT:   b.lo
359   %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2)
360   %val = extractvalue {i64, i1} %t, 0
361   %obit = extractvalue {i64, i1} %t, 1
362   br i1 %obit, label %overflow, label %continue
363
364 overflow:
365   ret i1 false
366
367 continue:
368   ret i1 true
369 }
370
371 define i1 @ssubo.br.i32(i32 %v1, i32 %v2) {
372 entry:
373 ; CHECK-LABEL:  ssubo.br.i32
374 ; CHECK:        cmp w0, w1
375 ; CHECK-NEXT:   b.vc
376   %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2)
377   %val = extractvalue {i32, i1} %t, 0
378   %obit = extractvalue {i32, i1} %t, 1
379   br i1 %obit, label %overflow, label %continue
380
381 overflow:
382   ret i1 false
383
384 continue:
385   ret i1 true
386 }
387
388 define i1 @ssubo.br.i64(i64 %v1, i64 %v2) {
389 entry:
390 ; CHECK-LABEL:  ssubo.br.i64
391 ; CHECK:        cmp x0, x1
392 ; CHECK-NEXT:   b.vc
393   %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2)
394   %val = extractvalue {i64, i1} %t, 0
395   %obit = extractvalue {i64, i1} %t, 1
396   br i1 %obit, label %overflow, label %continue
397
398 overflow:
399   ret i1 false
400
401 continue:
402   ret i1 true
403 }
404
405 define i1 @usubo.br.i32(i32 %v1, i32 %v2) {
406 entry:
407 ; CHECK-LABEL:  usubo.br.i32
408 ; CHECK:        cmp w0, w1
409 ; CHECK-NEXT:   b.hs
410   %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2)
411   %val = extractvalue {i32, i1} %t, 0
412   %obit = extractvalue {i32, i1} %t, 1
413   br i1 %obit, label %overflow, label %continue
414
415 overflow:
416   ret i1 false
417
418 continue:
419   ret i1 true
420 }
421
422 define i1 @usubo.br.i64(i64 %v1, i64 %v2) {
423 entry:
424 ; CHECK-LABEL:  usubo.br.i64
425 ; CHECK:        cmp x0, x1
426 ; CHECK-NEXT:   b.hs
427   %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2)
428   %val = extractvalue {i64, i1} %t, 0
429   %obit = extractvalue {i64, i1} %t, 1
430   br i1 %obit, label %overflow, label %continue
431
432 overflow:
433   ret i1 false
434
435 continue:
436   ret i1 true
437 }
438
439 define i1 @smulo.br.i32(i32 %v1, i32 %v2) {
440 entry:
441 ; CHECK-LABEL:  smulo.br.i32
442 ; CHECK:        smull    x8, w0, w1
443 ; CHECK-NEXT:   lsr     x9, x8, #32
444 ; CHECK-NEXT:   cmp     w9, w8, asr #31
445 ; CHECK-NEXT:   b.eq
446   %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
447   %val = extractvalue {i32, i1} %t, 0
448   %obit = extractvalue {i32, i1} %t, 1
449   br i1 %obit, label %overflow, label %continue
450
451 overflow:
452   ret i1 false
453
454 continue:
455   ret i1 true
456 }
457
458 define i1 @smulo.br.i64(i64 %v1, i64 %v2) {
459 entry:
460 ; CHECK-LABEL:  smulo.br.i64
461 ; CHECK:        mul      x8, x0, x1
462 ; CHECK-NEXT:   smulh   x9, x0, x1
463 ; CHECK-NEXT:   cmp     x9, x8, asr #63
464 ; CHECK-NEXT:   b.eq
465   %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
466   %val = extractvalue {i64, i1} %t, 0
467   %obit = extractvalue {i64, i1} %t, 1
468   br i1 %obit, label %overflow, label %continue
469
470 overflow:
471   ret i1 false
472
473 continue:
474   ret i1 true
475 }
476
477 define i1 @umulo.br.i32(i32 %v1, i32 %v2) {
478 entry:
479 ; CHECK-LABEL:  umulo.br.i32
480 ; CHECK:        umull    x8, w0, w1
481 ; CHECK-NEXT:   cmp     xzr, x8, lsr #32
482 ; CHECK-NEXT:   b.eq
483   %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
484   %val = extractvalue {i32, i1} %t, 0
485   %obit = extractvalue {i32, i1} %t, 1
486   br i1 %obit, label %overflow, label %continue
487
488 overflow:
489   ret i1 false
490
491 continue:
492   ret i1 true
493 }
494
495 define i1 @umulo.br.i64(i64 %v1, i64 %v2) {
496 entry:
497 ; CHECK-LABEL:  umulo.br.i64
498 ; CHECK:        umulh   x8, x0, x1
499 ; CHECK-NEXT:   cbz
500   %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
501   %val = extractvalue {i64, i1} %t, 0
502   %obit = extractvalue {i64, i1} %t, 1
503   br i1 %obit, label %overflow, label %continue
504
505 overflow:
506   ret i1 false
507
508 continue:
509   ret i1 true
510 }
511
512 declare {i32, i1} @llvm.sadd.with.overflow.i32(i32, i32) nounwind readnone
513 declare {i64, i1} @llvm.sadd.with.overflow.i64(i64, i64) nounwind readnone
514 declare {i32, i1} @llvm.uadd.with.overflow.i32(i32, i32) nounwind readnone
515 declare {i64, i1} @llvm.uadd.with.overflow.i64(i64, i64) nounwind readnone
516 declare {i32, i1} @llvm.ssub.with.overflow.i32(i32, i32) nounwind readnone
517 declare {i64, i1} @llvm.ssub.with.overflow.i64(i64, i64) nounwind readnone
518 declare {i32, i1} @llvm.usub.with.overflow.i32(i32, i32) nounwind readnone
519 declare {i64, i1} @llvm.usub.with.overflow.i64(i64, i64) nounwind readnone
520 declare {i32, i1} @llvm.smul.with.overflow.i32(i32, i32) nounwind readnone
521 declare {i64, i1} @llvm.smul.with.overflow.i64(i64, i64) nounwind readnone
522 declare {i32, i1} @llvm.umul.with.overflow.i32(i32, i32) nounwind readnone
523 declare {i64, i1} @llvm.umul.with.overflow.i64(i64, i64) nounwind readnone
524