1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=arm64-eabi -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK,SDAG
3 ; RUN: llc < %s -mtriple=arm64-eabi -fast-isel -fast-isel-abort=1 -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK,FAST
4 ; RUN: llc < %s -mtriple=arm64-eabi -global-isel -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK,GISEL
7 ; Get the actual value of the overflow bit.
9 define zeroext i1 @saddo1.i32(i32 %v1, i32 %v2, ptr %res) {
10 ; SDAG-LABEL: saddo1.i32:
11 ; SDAG: // %bb.0: // %entry
12 ; SDAG-NEXT: adds w8, w0, w1
13 ; SDAG-NEXT: cset w0, vs
14 ; SDAG-NEXT: str w8, [x2]
17 ; FAST-LABEL: saddo1.i32:
18 ; FAST: // %bb.0: // %entry
19 ; FAST-NEXT: adds w8, w0, w1
20 ; FAST-NEXT: cset w9, vs
21 ; FAST-NEXT: str w8, [x2]
22 ; FAST-NEXT: and w0, w9, #0x1
25 ; GISEL-LABEL: saddo1.i32:
26 ; GISEL: // %bb.0: // %entry
27 ; GISEL-NEXT: adds w8, w0, w1
28 ; GISEL-NEXT: cset w0, vs
29 ; GISEL-NEXT: str w8, [x2]
32 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2)
33 %val = extractvalue {i32, i1} %t, 0
34 %obit = extractvalue {i32, i1} %t, 1
35 store i32 %val, ptr %res
39 ; Test the immediate version.
40 define zeroext i1 @saddo2.i32(i32 %v1, ptr %res) {
41 ; SDAG-LABEL: saddo2.i32:
42 ; SDAG: // %bb.0: // %entry
43 ; SDAG-NEXT: adds w8, w0, #4
44 ; SDAG-NEXT: cset w0, vs
45 ; SDAG-NEXT: str w8, [x1]
48 ; FAST-LABEL: saddo2.i32:
49 ; FAST: // %bb.0: // %entry
50 ; FAST-NEXT: adds w8, w0, #4
51 ; FAST-NEXT: cset w9, vs
52 ; FAST-NEXT: str w8, [x1]
53 ; FAST-NEXT: and w0, w9, #0x1
56 ; GISEL-LABEL: saddo2.i32:
57 ; GISEL: // %bb.0: // %entry
58 ; GISEL-NEXT: adds w8, w0, #4
59 ; GISEL-NEXT: cset w0, vs
60 ; GISEL-NEXT: str w8, [x1]
63 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 4)
64 %val = extractvalue {i32, i1} %t, 0
65 %obit = extractvalue {i32, i1} %t, 1
66 store i32 %val, ptr %res
70 ; Test negative immediates.
71 define zeroext i1 @saddo3.i32(i32 %v1, ptr %res) {
72 ; SDAG-LABEL: saddo3.i32:
73 ; SDAG: // %bb.0: // %entry
74 ; SDAG-NEXT: subs w8, w0, #4
75 ; SDAG-NEXT: cset w0, vs
76 ; SDAG-NEXT: str w8, [x1]
79 ; FAST-LABEL: saddo3.i32:
80 ; FAST: // %bb.0: // %entry
81 ; FAST-NEXT: subs w8, w0, #4
82 ; FAST-NEXT: cset w9, vs
83 ; FAST-NEXT: str w8, [x1]
84 ; FAST-NEXT: and w0, w9, #0x1
87 ; GISEL-LABEL: saddo3.i32:
88 ; GISEL: // %bb.0: // %entry
89 ; GISEL-NEXT: subs w8, w0, #4
90 ; GISEL-NEXT: cset w0, vs
91 ; GISEL-NEXT: str w8, [x1]
94 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 -4)
95 %val = extractvalue {i32, i1} %t, 0
96 %obit = extractvalue {i32, i1} %t, 1
97 store i32 %val, ptr %res
101 ; Test immediates that are too large to be encoded.
102 define zeroext i1 @saddo4.i32(i32 %v1, ptr %res) {
103 ; SDAG-LABEL: saddo4.i32:
104 ; SDAG: // %bb.0: // %entry
105 ; SDAG-NEXT: mov w8, #16777215 // =0xffffff
106 ; SDAG-NEXT: adds w8, w0, w8
107 ; SDAG-NEXT: cset w0, vs
108 ; SDAG-NEXT: str w8, [x1]
111 ; FAST-LABEL: saddo4.i32:
112 ; FAST: // %bb.0: // %entry
113 ; FAST-NEXT: mov w8, #16777215 // =0xffffff
114 ; FAST-NEXT: adds w8, w0, w8
115 ; FAST-NEXT: cset w9, vs
116 ; FAST-NEXT: str w8, [x1]
117 ; FAST-NEXT: and w0, w9, #0x1
120 ; GISEL-LABEL: saddo4.i32:
121 ; GISEL: // %bb.0: // %entry
122 ; GISEL-NEXT: mov w8, #16777215 // =0xffffff
123 ; GISEL-NEXT: adds w8, w0, w8
124 ; GISEL-NEXT: cset w0, vs
125 ; GISEL-NEXT: str w8, [x1]
128 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 16777215)
129 %val = extractvalue {i32, i1} %t, 0
130 %obit = extractvalue {i32, i1} %t, 1
131 store i32 %val, ptr %res
135 ; Test shift folding.
136 define zeroext i1 @saddo5.i32(i32 %v1, i32 %v2, ptr %res) {
137 ; SDAG-LABEL: saddo5.i32:
138 ; SDAG: // %bb.0: // %entry
139 ; SDAG-NEXT: adds w8, w0, w1, lsl #16
140 ; SDAG-NEXT: cset w0, vs
141 ; SDAG-NEXT: str w8, [x2]
144 ; FAST-LABEL: saddo5.i32:
145 ; FAST: // %bb.0: // %entry
146 ; FAST-NEXT: adds w8, w0, w1, lsl #16
147 ; FAST-NEXT: cset w9, vs
148 ; FAST-NEXT: and w0, w9, #0x1
149 ; FAST-NEXT: str w8, [x2]
152 ; GISEL-LABEL: saddo5.i32:
153 ; GISEL: // %bb.0: // %entry
154 ; GISEL-NEXT: adds w8, w0, w1, lsl #16
155 ; GISEL-NEXT: cset w0, vs
156 ; GISEL-NEXT: str w8, [x2]
159 %lsl = shl i32 %v2, 16
160 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %lsl)
161 %val = extractvalue {i32, i1} %t, 0
162 %obit = extractvalue {i32, i1} %t, 1
163 store i32 %val, ptr %res
167 define zeroext i1 @saddo1.i64(i64 %v1, i64 %v2, ptr %res) {
168 ; SDAG-LABEL: saddo1.i64:
169 ; SDAG: // %bb.0: // %entry
170 ; SDAG-NEXT: adds x8, x0, x1
171 ; SDAG-NEXT: cset w0, vs
172 ; SDAG-NEXT: str x8, [x2]
175 ; FAST-LABEL: saddo1.i64:
176 ; FAST: // %bb.0: // %entry
177 ; FAST-NEXT: adds x8, x0, x1
178 ; FAST-NEXT: cset w9, vs
179 ; FAST-NEXT: str x8, [x2]
180 ; FAST-NEXT: and w0, w9, #0x1
183 ; GISEL-LABEL: saddo1.i64:
184 ; GISEL: // %bb.0: // %entry
185 ; GISEL-NEXT: adds x8, x0, x1
186 ; GISEL-NEXT: cset w0, vs
187 ; GISEL-NEXT: str x8, [x2]
190 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2)
191 %val = extractvalue {i64, i1} %t, 0
192 %obit = extractvalue {i64, i1} %t, 1
193 store i64 %val, ptr %res
197 define zeroext i1 @saddo2.i64(i64 %v1, ptr %res) {
198 ; SDAG-LABEL: saddo2.i64:
199 ; SDAG: // %bb.0: // %entry
200 ; SDAG-NEXT: adds x8, x0, #4
201 ; SDAG-NEXT: cset w0, vs
202 ; SDAG-NEXT: str x8, [x1]
205 ; FAST-LABEL: saddo2.i64:
206 ; FAST: // %bb.0: // %entry
207 ; FAST-NEXT: adds x8, x0, #4
208 ; FAST-NEXT: cset w9, vs
209 ; FAST-NEXT: str x8, [x1]
210 ; FAST-NEXT: and w0, w9, #0x1
213 ; GISEL-LABEL: saddo2.i64:
214 ; GISEL: // %bb.0: // %entry
215 ; GISEL-NEXT: adds x8, x0, #4
216 ; GISEL-NEXT: cset w0, vs
217 ; GISEL-NEXT: str x8, [x1]
220 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 4)
221 %val = extractvalue {i64, i1} %t, 0
222 %obit = extractvalue {i64, i1} %t, 1
223 store i64 %val, ptr %res
227 define zeroext i1 @saddo3.i64(i64 %v1, ptr %res) {
228 ; SDAG-LABEL: saddo3.i64:
229 ; SDAG: // %bb.0: // %entry
230 ; SDAG-NEXT: subs x8, x0, #4
231 ; SDAG-NEXT: cset w0, vs
232 ; SDAG-NEXT: str x8, [x1]
235 ; FAST-LABEL: saddo3.i64:
236 ; FAST: // %bb.0: // %entry
237 ; FAST-NEXT: subs x8, x0, #4
238 ; FAST-NEXT: cset w9, vs
239 ; FAST-NEXT: str x8, [x1]
240 ; FAST-NEXT: and w0, w9, #0x1
243 ; GISEL-LABEL: saddo3.i64:
244 ; GISEL: // %bb.0: // %entry
245 ; GISEL-NEXT: subs x8, x0, #4
246 ; GISEL-NEXT: cset w0, vs
247 ; GISEL-NEXT: str x8, [x1]
250 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 -4)
251 %val = extractvalue {i64, i1} %t, 0
252 %obit = extractvalue {i64, i1} %t, 1
253 store i64 %val, ptr %res
257 define zeroext i1 @uaddo.i32(i32 %v1, i32 %v2, ptr %res) {
258 ; SDAG-LABEL: uaddo.i32:
259 ; SDAG: // %bb.0: // %entry
260 ; SDAG-NEXT: adds w8, w0, w1
261 ; SDAG-NEXT: cset w0, hs
262 ; SDAG-NEXT: str w8, [x2]
265 ; FAST-LABEL: uaddo.i32:
266 ; FAST: // %bb.0: // %entry
267 ; FAST-NEXT: adds w8, w0, w1
268 ; FAST-NEXT: cset w9, hs
269 ; FAST-NEXT: str w8, [x2]
270 ; FAST-NEXT: and w0, w9, #0x1
273 ; GISEL-LABEL: uaddo.i32:
274 ; GISEL: // %bb.0: // %entry
275 ; GISEL-NEXT: adds w8, w0, w1
276 ; GISEL-NEXT: cset w0, hs
277 ; GISEL-NEXT: str w8, [x2]
280 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)
281 %val = extractvalue {i32, i1} %t, 0
282 %obit = extractvalue {i32, i1} %t, 1
283 store i32 %val, ptr %res
287 define zeroext i1 @uaddo.i64(i64 %v1, i64 %v2, ptr %res) {
288 ; SDAG-LABEL: uaddo.i64:
289 ; SDAG: // %bb.0: // %entry
290 ; SDAG-NEXT: adds x8, x0, x1
291 ; SDAG-NEXT: cset w0, hs
292 ; SDAG-NEXT: str x8, [x2]
295 ; FAST-LABEL: uaddo.i64:
296 ; FAST: // %bb.0: // %entry
297 ; FAST-NEXT: adds x8, x0, x1
298 ; FAST-NEXT: cset w9, hs
299 ; FAST-NEXT: str x8, [x2]
300 ; FAST-NEXT: and w0, w9, #0x1
303 ; GISEL-LABEL: uaddo.i64:
304 ; GISEL: // %bb.0: // %entry
305 ; GISEL-NEXT: adds x8, x0, x1
306 ; GISEL-NEXT: cset w0, hs
307 ; GISEL-NEXT: str x8, [x2]
310 %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2)
311 %val = extractvalue {i64, i1} %t, 0
312 %obit = extractvalue {i64, i1} %t, 1
313 store i64 %val, ptr %res
317 define zeroext i1 @ssubo1.i32(i32 %v1, i32 %v2, ptr %res) {
318 ; SDAG-LABEL: ssubo1.i32:
319 ; SDAG: // %bb.0: // %entry
320 ; SDAG-NEXT: subs w8, w0, w1
321 ; SDAG-NEXT: cset w0, vs
322 ; SDAG-NEXT: str w8, [x2]
325 ; FAST-LABEL: ssubo1.i32:
326 ; FAST: // %bb.0: // %entry
327 ; FAST-NEXT: subs w8, w0, w1
328 ; FAST-NEXT: cset w9, vs
329 ; FAST-NEXT: str w8, [x2]
330 ; FAST-NEXT: and w0, w9, #0x1
333 ; GISEL-LABEL: ssubo1.i32:
334 ; GISEL: // %bb.0: // %entry
335 ; GISEL-NEXT: subs w8, w0, w1
336 ; GISEL-NEXT: cset w0, vs
337 ; GISEL-NEXT: str w8, [x2]
340 %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2)
341 %val = extractvalue {i32, i1} %t, 0
342 %obit = extractvalue {i32, i1} %t, 1
343 store i32 %val, ptr %res
347 define zeroext i1 @ssubo2.i32(i32 %v1, ptr %res) {
348 ; SDAG-LABEL: ssubo2.i32:
349 ; SDAG: // %bb.0: // %entry
350 ; SDAG-NEXT: adds w8, w0, #4
351 ; SDAG-NEXT: cset w0, vs
352 ; SDAG-NEXT: str w8, [x1]
355 ; FAST-LABEL: ssubo2.i32:
356 ; FAST: // %bb.0: // %entry
357 ; FAST-NEXT: adds w8, w0, #4
358 ; FAST-NEXT: cset w9, vs
359 ; FAST-NEXT: str w8, [x1]
360 ; FAST-NEXT: and w0, w9, #0x1
363 ; GISEL-LABEL: ssubo2.i32:
364 ; GISEL: // %bb.0: // %entry
365 ; GISEL-NEXT: adds w8, w0, #4
366 ; GISEL-NEXT: cset w0, vs
367 ; GISEL-NEXT: str w8, [x1]
370 %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 -4)
371 %val = extractvalue {i32, i1} %t, 0
372 %obit = extractvalue {i32, i1} %t, 1
373 store i32 %val, ptr %res
377 define zeroext i1 @ssubo.i64(i64 %v1, i64 %v2, ptr %res) {
378 ; SDAG-LABEL: ssubo.i64:
379 ; SDAG: // %bb.0: // %entry
380 ; SDAG-NEXT: subs x8, x0, x1
381 ; SDAG-NEXT: cset w0, vs
382 ; SDAG-NEXT: str x8, [x2]
385 ; FAST-LABEL: ssubo.i64:
386 ; FAST: // %bb.0: // %entry
387 ; FAST-NEXT: subs x8, x0, x1
388 ; FAST-NEXT: cset w9, vs
389 ; FAST-NEXT: str x8, [x2]
390 ; FAST-NEXT: and w0, w9, #0x1
393 ; GISEL-LABEL: ssubo.i64:
394 ; GISEL: // %bb.0: // %entry
395 ; GISEL-NEXT: subs x8, x0, x1
396 ; GISEL-NEXT: cset w0, vs
397 ; GISEL-NEXT: str x8, [x2]
400 %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2)
401 %val = extractvalue {i64, i1} %t, 0
402 %obit = extractvalue {i64, i1} %t, 1
403 store i64 %val, ptr %res
407 define zeroext i1 @usubo.i32(i32 %v1, i32 %v2, ptr %res) {
408 ; SDAG-LABEL: usubo.i32:
409 ; SDAG: // %bb.0: // %entry
410 ; SDAG-NEXT: subs w8, w0, w1
411 ; SDAG-NEXT: cset w0, lo
412 ; SDAG-NEXT: str w8, [x2]
415 ; FAST-LABEL: usubo.i32:
416 ; FAST: // %bb.0: // %entry
417 ; FAST-NEXT: subs w8, w0, w1
418 ; FAST-NEXT: cset w9, lo
419 ; FAST-NEXT: str w8, [x2]
420 ; FAST-NEXT: and w0, w9, #0x1
423 ; GISEL-LABEL: usubo.i32:
424 ; GISEL: // %bb.0: // %entry
425 ; GISEL-NEXT: subs w8, w0, w1
426 ; GISEL-NEXT: cset w0, lo
427 ; GISEL-NEXT: str w8, [x2]
430 %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2)
431 %val = extractvalue {i32, i1} %t, 0
432 %obit = extractvalue {i32, i1} %t, 1
433 store i32 %val, ptr %res
437 define zeroext i1 @usubo.i64(i64 %v1, i64 %v2, ptr %res) {
438 ; SDAG-LABEL: usubo.i64:
439 ; SDAG: // %bb.0: // %entry
440 ; SDAG-NEXT: subs x8, x0, x1
441 ; SDAG-NEXT: cset w0, lo
442 ; SDAG-NEXT: str x8, [x2]
445 ; FAST-LABEL: usubo.i64:
446 ; FAST: // %bb.0: // %entry
447 ; FAST-NEXT: subs x8, x0, x1
448 ; FAST-NEXT: cset w9, lo
449 ; FAST-NEXT: str x8, [x2]
450 ; FAST-NEXT: and w0, w9, #0x1
453 ; GISEL-LABEL: usubo.i64:
454 ; GISEL: // %bb.0: // %entry
455 ; GISEL-NEXT: subs x8, x0, x1
456 ; GISEL-NEXT: cset w0, lo
457 ; GISEL-NEXT: str x8, [x2]
460 %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2)
461 %val = extractvalue {i64, i1} %t, 0
462 %obit = extractvalue {i64, i1} %t, 1
463 store i64 %val, ptr %res
467 define zeroext i1 @smulo.i32(i32 %v1, i32 %v2, ptr %res) {
468 ; SDAG-LABEL: smulo.i32:
469 ; SDAG: // %bb.0: // %entry
470 ; SDAG-NEXT: smull x8, w0, w1
471 ; SDAG-NEXT: cmp x8, w8, sxtw
472 ; SDAG-NEXT: str w8, [x2]
473 ; SDAG-NEXT: cset w0, ne
476 ; FAST-LABEL: smulo.i32:
477 ; FAST: // %bb.0: // %entry
478 ; FAST-NEXT: smull x8, w0, w1
479 ; FAST-NEXT: cmp x8, w8, sxtw
480 ; FAST-NEXT: str w8, [x2]
481 ; FAST-NEXT: cset w9, ne
482 ; FAST-NEXT: and w0, w9, #0x1
485 ; GISEL-LABEL: smulo.i32:
486 ; GISEL: // %bb.0: // %entry
487 ; GISEL-NEXT: smull x8, w0, w1
488 ; GISEL-NEXT: mul w9, w0, w1
489 ; GISEL-NEXT: asr x8, x8, #32
490 ; GISEL-NEXT: str w9, [x2]
491 ; GISEL-NEXT: cmp w8, w9, asr #31
492 ; GISEL-NEXT: cset w0, ne
495 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
496 %val = extractvalue {i32, i1} %t, 0
497 %obit = extractvalue {i32, i1} %t, 1
498 store i32 %val, ptr %res
502 define zeroext i1 @smulo.i64(i64 %v1, i64 %v2, ptr %res) {
503 ; SDAG-LABEL: smulo.i64:
504 ; SDAG: // %bb.0: // %entry
505 ; SDAG-NEXT: mul x8, x0, x1
506 ; SDAG-NEXT: smulh x9, x0, x1
507 ; SDAG-NEXT: str x8, [x2]
508 ; SDAG-NEXT: cmp x9, x8, asr #63
509 ; SDAG-NEXT: cset w0, ne
512 ; FAST-LABEL: smulo.i64:
513 ; FAST: // %bb.0: // %entry
514 ; FAST-NEXT: mul x8, x0, x1
515 ; FAST-NEXT: smulh x9, x0, x1
516 ; FAST-NEXT: str x8, [x2]
517 ; FAST-NEXT: cmp x9, x8, asr #63
518 ; FAST-NEXT: cset w9, ne
519 ; FAST-NEXT: and w0, w9, #0x1
522 ; GISEL-LABEL: smulo.i64:
523 ; GISEL: // %bb.0: // %entry
524 ; GISEL-NEXT: smulh x8, x0, x1
525 ; GISEL-NEXT: mul x9, x0, x1
526 ; GISEL-NEXT: cmp x8, x9, asr #63
527 ; GISEL-NEXT: str x9, [x2]
528 ; GISEL-NEXT: cset w0, ne
531 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
532 %val = extractvalue {i64, i1} %t, 0
533 %obit = extractvalue {i64, i1} %t, 1
534 store i64 %val, ptr %res
538 define zeroext i1 @smulo2.i64(i64 %v1, ptr %res) {
539 ; SDAG-LABEL: smulo2.i64:
540 ; SDAG: // %bb.0: // %entry
541 ; SDAG-NEXT: adds x8, x0, x0
542 ; SDAG-NEXT: cset w0, vs
543 ; SDAG-NEXT: str x8, [x1]
546 ; FAST-LABEL: smulo2.i64:
547 ; FAST: // %bb.0: // %entry
548 ; FAST-NEXT: adds x8, x0, x0
549 ; FAST-NEXT: cset w9, vs
550 ; FAST-NEXT: str x8, [x1]
551 ; FAST-NEXT: and w0, w9, #0x1
554 ; GISEL-LABEL: smulo2.i64:
555 ; GISEL: // %bb.0: // %entry
556 ; GISEL-NEXT: adds x8, x0, x0
557 ; GISEL-NEXT: cset w0, vs
558 ; GISEL-NEXT: str x8, [x1]
561 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 2)
562 %val = extractvalue {i64, i1} %t, 0
563 %obit = extractvalue {i64, i1} %t, 1
564 store i64 %val, ptr %res
568 define zeroext i1 @umulo.i32(i32 %v1, i32 %v2, ptr %res) {
569 ; SDAG-LABEL: umulo.i32:
570 ; SDAG: // %bb.0: // %entry
571 ; SDAG-NEXT: umull x8, w0, w1
572 ; SDAG-NEXT: tst x8, #0xffffffff00000000
573 ; SDAG-NEXT: str w8, [x2]
574 ; SDAG-NEXT: cset w0, ne
577 ; FAST-LABEL: umulo.i32:
578 ; FAST: // %bb.0: // %entry
579 ; FAST-NEXT: umull x8, w0, w1
580 ; FAST-NEXT: tst x8, #0xffffffff00000000
581 ; FAST-NEXT: str w8, [x2]
582 ; FAST-NEXT: cset w9, ne
583 ; FAST-NEXT: and w0, w9, #0x1
586 ; GISEL-LABEL: umulo.i32:
587 ; GISEL: // %bb.0: // %entry
588 ; GISEL-NEXT: umull x8, w0, w1
589 ; GISEL-NEXT: mul w9, w0, w1
590 ; GISEL-NEXT: lsr x8, x8, #32
591 ; GISEL-NEXT: str w9, [x2]
592 ; GISEL-NEXT: cmp w8, #0
593 ; GISEL-NEXT: cset w0, ne
596 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
597 %val = extractvalue {i32, i1} %t, 0
598 %obit = extractvalue {i32, i1} %t, 1
599 store i32 %val, ptr %res
603 define zeroext i1 @umulo.i64(i64 %v1, i64 %v2, ptr %res) {
604 ; SDAG-LABEL: umulo.i64:
605 ; SDAG: // %bb.0: // %entry
606 ; SDAG-NEXT: umulh x8, x0, x1
607 ; SDAG-NEXT: mul x9, x0, x1
608 ; SDAG-NEXT: cmp xzr, x8
609 ; SDAG-NEXT: cset w0, ne
610 ; SDAG-NEXT: str x9, [x2]
613 ; FAST-LABEL: umulo.i64:
614 ; FAST: // %bb.0: // %entry
615 ; FAST-NEXT: umulh x8, x0, x1
616 ; FAST-NEXT: mul x9, x0, x1
617 ; FAST-NEXT: cmp xzr, x8
618 ; FAST-NEXT: cset w8, ne
619 ; FAST-NEXT: and w0, w8, #0x1
620 ; FAST-NEXT: str x9, [x2]
623 ; GISEL-LABEL: umulo.i64:
624 ; GISEL: // %bb.0: // %entry
625 ; GISEL-NEXT: umulh x8, x0, x1
626 ; GISEL-NEXT: mul x9, x0, x1
627 ; GISEL-NEXT: cmp x8, #0
628 ; GISEL-NEXT: cset w0, ne
629 ; GISEL-NEXT: str x9, [x2]
632 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
633 %val = extractvalue {i64, i1} %t, 0
634 %obit = extractvalue {i64, i1} %t, 1
635 store i64 %val, ptr %res
639 define zeroext i1 @umulo2.i64(i64 %v1, ptr %res) {
640 ; SDAG-LABEL: umulo2.i64:
641 ; SDAG: // %bb.0: // %entry
642 ; SDAG-NEXT: adds x8, x0, x0
643 ; SDAG-NEXT: cset w0, hs
644 ; SDAG-NEXT: str x8, [x1]
647 ; FAST-LABEL: umulo2.i64:
648 ; FAST: // %bb.0: // %entry
649 ; FAST-NEXT: adds x8, x0, x0
650 ; FAST-NEXT: cset w9, hs
651 ; FAST-NEXT: str x8, [x1]
652 ; FAST-NEXT: and w0, w9, #0x1
655 ; GISEL-LABEL: umulo2.i64:
656 ; GISEL: // %bb.0: // %entry
657 ; GISEL-NEXT: adds x8, x0, x0
658 ; GISEL-NEXT: cset w0, hs
659 ; GISEL-NEXT: str x8, [x1]
662 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 2)
663 %val = extractvalue {i64, i1} %t, 0
664 %obit = extractvalue {i64, i1} %t, 1
665 store i64 %val, ptr %res
671 ; Check the use of the overflow bit in combination with a select instruction.
673 define i32 @saddo.select.i32(i32 %v1, i32 %v2) {
674 ; SDAG-LABEL: saddo.select.i32:
675 ; SDAG: // %bb.0: // %entry
676 ; SDAG-NEXT: cmn w0, w1
677 ; SDAG-NEXT: csel w0, w0, w1, vs
680 ; FAST-LABEL: saddo.select.i32:
681 ; FAST: // %bb.0: // %entry
682 ; FAST-NEXT: cmn w0, w1
683 ; FAST-NEXT: csel w0, w0, w1, vs
686 ; GISEL-LABEL: saddo.select.i32:
687 ; GISEL: // %bb.0: // %entry
688 ; GISEL-NEXT: cmn w0, w1
689 ; GISEL-NEXT: cset w8, vs
690 ; GISEL-NEXT: tst w8, #0x1
691 ; GISEL-NEXT: csel w0, w0, w1, ne
694 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2)
695 %obit = extractvalue {i32, i1} %t, 1
696 %ret = select i1 %obit, i32 %v1, i32 %v2
700 define i1 @saddo.not.i32(i32 %v1, i32 %v2) {
701 ; SDAG-LABEL: saddo.not.i32:
702 ; SDAG: // %bb.0: // %entry
703 ; SDAG-NEXT: cmn w0, w1
704 ; SDAG-NEXT: cset w0, vc
707 ; FAST-LABEL: saddo.not.i32:
708 ; FAST: // %bb.0: // %entry
709 ; FAST-NEXT: cmn w0, w1
710 ; FAST-NEXT: cset w0, vc
713 ; GISEL-LABEL: saddo.not.i32:
714 ; GISEL: // %bb.0: // %entry
715 ; GISEL-NEXT: cmn w0, w1
716 ; GISEL-NEXT: cset w8, vs
717 ; GISEL-NEXT: eor w0, w8, #0x1
720 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2)
721 %obit = extractvalue {i32, i1} %t, 1
722 %ret = xor i1 %obit, true
726 define i64 @saddo.select.i64(i64 %v1, i64 %v2) {
727 ; SDAG-LABEL: saddo.select.i64:
728 ; SDAG: // %bb.0: // %entry
729 ; SDAG-NEXT: cmn x0, x1
730 ; SDAG-NEXT: csel x0, x0, x1, vs
733 ; FAST-LABEL: saddo.select.i64:
734 ; FAST: // %bb.0: // %entry
735 ; FAST-NEXT: cmn x0, x1
736 ; FAST-NEXT: csel x0, x0, x1, vs
739 ; GISEL-LABEL: saddo.select.i64:
740 ; GISEL: // %bb.0: // %entry
741 ; GISEL-NEXT: cmn x0, x1
742 ; GISEL-NEXT: cset w8, vs
743 ; GISEL-NEXT: tst w8, #0x1
744 ; GISEL-NEXT: csel x0, x0, x1, ne
747 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2)
748 %obit = extractvalue {i64, i1} %t, 1
749 %ret = select i1 %obit, i64 %v1, i64 %v2
753 define i1 @saddo.not.i64(i64 %v1, i64 %v2) {
754 ; SDAG-LABEL: saddo.not.i64:
755 ; SDAG: // %bb.0: // %entry
756 ; SDAG-NEXT: cmn x0, x1
757 ; SDAG-NEXT: cset w0, vc
760 ; FAST-LABEL: saddo.not.i64:
761 ; FAST: // %bb.0: // %entry
762 ; FAST-NEXT: cmn x0, x1
763 ; FAST-NEXT: cset w0, vc
766 ; GISEL-LABEL: saddo.not.i64:
767 ; GISEL: // %bb.0: // %entry
768 ; GISEL-NEXT: cmn x0, x1
769 ; GISEL-NEXT: cset w8, vs
770 ; GISEL-NEXT: eor w0, w8, #0x1
773 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2)
774 %obit = extractvalue {i64, i1} %t, 1
775 %ret = xor i1 %obit, true
779 define i32 @uaddo.select.i32(i32 %v1, i32 %v2) {
780 ; SDAG-LABEL: uaddo.select.i32:
781 ; SDAG: // %bb.0: // %entry
782 ; SDAG-NEXT: cmn w0, w1
783 ; SDAG-NEXT: csel w0, w0, w1, hs
786 ; FAST-LABEL: uaddo.select.i32:
787 ; FAST: // %bb.0: // %entry
788 ; FAST-NEXT: cmn w0, w1
789 ; FAST-NEXT: csel w0, w0, w1, hs
792 ; GISEL-LABEL: uaddo.select.i32:
793 ; GISEL: // %bb.0: // %entry
794 ; GISEL-NEXT: cmn w0, w1
795 ; GISEL-NEXT: cset w8, hs
796 ; GISEL-NEXT: tst w8, #0x1
797 ; GISEL-NEXT: csel w0, w0, w1, ne
800 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)
801 %obit = extractvalue {i32, i1} %t, 1
802 %ret = select i1 %obit, i32 %v1, i32 %v2
806 define i1 @uaddo.not.i32(i32 %v1, i32 %v2) {
807 ; SDAG-LABEL: uaddo.not.i32:
808 ; SDAG: // %bb.0: // %entry
809 ; SDAG-NEXT: cmn w0, w1
810 ; SDAG-NEXT: cset w0, lo
813 ; FAST-LABEL: uaddo.not.i32:
814 ; FAST: // %bb.0: // %entry
815 ; FAST-NEXT: cmn w0, w1
816 ; FAST-NEXT: cset w0, lo
819 ; GISEL-LABEL: uaddo.not.i32:
820 ; GISEL: // %bb.0: // %entry
821 ; GISEL-NEXT: cmn w0, w1
822 ; GISEL-NEXT: cset w8, hs
823 ; GISEL-NEXT: eor w0, w8, #0x1
826 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)
827 %obit = extractvalue {i32, i1} %t, 1
828 %ret = xor i1 %obit, true
832 define i64 @uaddo.select.i64(i64 %v1, i64 %v2) {
833 ; SDAG-LABEL: uaddo.select.i64:
834 ; SDAG: // %bb.0: // %entry
835 ; SDAG-NEXT: cmn x0, x1
836 ; SDAG-NEXT: csel x0, x0, x1, hs
839 ; FAST-LABEL: uaddo.select.i64:
840 ; FAST: // %bb.0: // %entry
841 ; FAST-NEXT: cmn x0, x1
842 ; FAST-NEXT: csel x0, x0, x1, hs
845 ; GISEL-LABEL: uaddo.select.i64:
846 ; GISEL: // %bb.0: // %entry
847 ; GISEL-NEXT: cmn x0, x1
848 ; GISEL-NEXT: cset w8, hs
849 ; GISEL-NEXT: tst w8, #0x1
850 ; GISEL-NEXT: csel x0, x0, x1, ne
853 %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2)
854 %obit = extractvalue {i64, i1} %t, 1
855 %ret = select i1 %obit, i64 %v1, i64 %v2
859 define i1 @uaddo.not.i64(i64 %v1, i64 %v2) {
860 ; SDAG-LABEL: uaddo.not.i64:
861 ; SDAG: // %bb.0: // %entry
862 ; SDAG-NEXT: cmn x0, x1
863 ; SDAG-NEXT: cset w0, lo
866 ; FAST-LABEL: uaddo.not.i64:
867 ; FAST: // %bb.0: // %entry
868 ; FAST-NEXT: cmn x0, x1
869 ; FAST-NEXT: cset w0, lo
872 ; GISEL-LABEL: uaddo.not.i64:
873 ; GISEL: // %bb.0: // %entry
874 ; GISEL-NEXT: cmn x0, x1
875 ; GISEL-NEXT: cset w8, hs
876 ; GISEL-NEXT: eor w0, w8, #0x1
879 %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2)
880 %obit = extractvalue {i64, i1} %t, 1
881 %ret = xor i1 %obit, true
885 define i32 @ssubo.select.i32(i32 %v1, i32 %v2) {
886 ; SDAG-LABEL: ssubo.select.i32:
887 ; SDAG: // %bb.0: // %entry
888 ; SDAG-NEXT: cmp w0, w1
889 ; SDAG-NEXT: csel w0, w0, w1, vs
892 ; FAST-LABEL: ssubo.select.i32:
893 ; FAST: // %bb.0: // %entry
894 ; FAST-NEXT: cmp w0, w1
895 ; FAST-NEXT: csel w0, w0, w1, vs
898 ; GISEL-LABEL: ssubo.select.i32:
899 ; GISEL: // %bb.0: // %entry
900 ; GISEL-NEXT: cmp w0, w1
901 ; GISEL-NEXT: cset w8, vs
902 ; GISEL-NEXT: tst w8, #0x1
903 ; GISEL-NEXT: csel w0, w0, w1, ne
906 %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2)
907 %obit = extractvalue {i32, i1} %t, 1
908 %ret = select i1 %obit, i32 %v1, i32 %v2
912 define i1 @ssubo.not.i32(i32 %v1, i32 %v2) {
913 ; SDAG-LABEL: ssubo.not.i32:
914 ; SDAG: // %bb.0: // %entry
915 ; SDAG-NEXT: cmp w0, w1
916 ; SDAG-NEXT: cset w0, vc
919 ; FAST-LABEL: ssubo.not.i32:
920 ; FAST: // %bb.0: // %entry
921 ; FAST-NEXT: cmp w0, w1
922 ; FAST-NEXT: cset w0, vc
925 ; GISEL-LABEL: ssubo.not.i32:
926 ; GISEL: // %bb.0: // %entry
927 ; GISEL-NEXT: cmp w0, w1
928 ; GISEL-NEXT: cset w8, vs
929 ; GISEL-NEXT: eor w0, w8, #0x1
932 %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2)
933 %obit = extractvalue {i32, i1} %t, 1
934 %ret = xor i1 %obit, true
938 define i64 @ssubo.select.i64(i64 %v1, i64 %v2) {
939 ; SDAG-LABEL: ssubo.select.i64:
940 ; SDAG: // %bb.0: // %entry
941 ; SDAG-NEXT: cmp x0, x1
942 ; SDAG-NEXT: csel x0, x0, x1, vs
945 ; FAST-LABEL: ssubo.select.i64:
946 ; FAST: // %bb.0: // %entry
947 ; FAST-NEXT: cmp x0, x1
948 ; FAST-NEXT: csel x0, x0, x1, vs
951 ; GISEL-LABEL: ssubo.select.i64:
952 ; GISEL: // %bb.0: // %entry
953 ; GISEL-NEXT: cmp x0, x1
954 ; GISEL-NEXT: cset w8, vs
955 ; GISEL-NEXT: tst w8, #0x1
956 ; GISEL-NEXT: csel x0, x0, x1, ne
959 %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2)
960 %obit = extractvalue {i64, i1} %t, 1
961 %ret = select i1 %obit, i64 %v1, i64 %v2
965 define i1 @ssub.not.i64(i64 %v1, i64 %v2) {
966 ; SDAG-LABEL: ssub.not.i64:
967 ; SDAG: // %bb.0: // %entry
968 ; SDAG-NEXT: cmp x0, x1
969 ; SDAG-NEXT: cset w0, vc
972 ; FAST-LABEL: ssub.not.i64:
973 ; FAST: // %bb.0: // %entry
974 ; FAST-NEXT: cmp x0, x1
975 ; FAST-NEXT: cset w0, vc
978 ; GISEL-LABEL: ssub.not.i64:
979 ; GISEL: // %bb.0: // %entry
980 ; GISEL-NEXT: cmp x0, x1
981 ; GISEL-NEXT: cset w8, vs
982 ; GISEL-NEXT: eor w0, w8, #0x1
985 %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2)
986 %obit = extractvalue {i64, i1} %t, 1
987 %ret = xor i1 %obit, true
991 define i32 @usubo.select.i32(i32 %v1, i32 %v2) {
992 ; SDAG-LABEL: usubo.select.i32:
993 ; SDAG: // %bb.0: // %entry
994 ; SDAG-NEXT: cmp w0, w1
995 ; SDAG-NEXT: csel w0, w0, w1, lo
998 ; FAST-LABEL: usubo.select.i32:
999 ; FAST: // %bb.0: // %entry
1000 ; FAST-NEXT: cmp w0, w1
1001 ; FAST-NEXT: csel w0, w0, w1, lo
1004 ; GISEL-LABEL: usubo.select.i32:
1005 ; GISEL: // %bb.0: // %entry
1006 ; GISEL-NEXT: cmp w0, w1
1007 ; GISEL-NEXT: cset w8, lo
1008 ; GISEL-NEXT: tst w8, #0x1
1009 ; GISEL-NEXT: csel w0, w0, w1, ne
1012 %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2)
1013 %obit = extractvalue {i32, i1} %t, 1
1014 %ret = select i1 %obit, i32 %v1, i32 %v2
1018 define i1 @usubo.not.i32(i32 %v1, i32 %v2) {
1019 ; SDAG-LABEL: usubo.not.i32:
1020 ; SDAG: // %bb.0: // %entry
1021 ; SDAG-NEXT: cmp w0, w1
1022 ; SDAG-NEXT: cset w0, hs
1025 ; FAST-LABEL: usubo.not.i32:
1026 ; FAST: // %bb.0: // %entry
1027 ; FAST-NEXT: cmp w0, w1
1028 ; FAST-NEXT: cset w0, hs
1031 ; GISEL-LABEL: usubo.not.i32:
1032 ; GISEL: // %bb.0: // %entry
1033 ; GISEL-NEXT: cmp w0, w1
1034 ; GISEL-NEXT: cset w8, lo
1035 ; GISEL-NEXT: eor w0, w8, #0x1
1038 %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2)
1039 %obit = extractvalue {i32, i1} %t, 1
1040 %ret = xor i1 %obit, true
1044 define i64 @usubo.select.i64(i64 %v1, i64 %v2) {
1045 ; SDAG-LABEL: usubo.select.i64:
1046 ; SDAG: // %bb.0: // %entry
1047 ; SDAG-NEXT: cmp x0, x1
1048 ; SDAG-NEXT: csel x0, x0, x1, lo
1051 ; FAST-LABEL: usubo.select.i64:
1052 ; FAST: // %bb.0: // %entry
1053 ; FAST-NEXT: cmp x0, x1
1054 ; FAST-NEXT: csel x0, x0, x1, lo
1057 ; GISEL-LABEL: usubo.select.i64:
1058 ; GISEL: // %bb.0: // %entry
1059 ; GISEL-NEXT: cmp x0, x1
1060 ; GISEL-NEXT: cset w8, lo
1061 ; GISEL-NEXT: tst w8, #0x1
1062 ; GISEL-NEXT: csel x0, x0, x1, ne
1065 %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2)
1066 %obit = extractvalue {i64, i1} %t, 1
1067 %ret = select i1 %obit, i64 %v1, i64 %v2
1071 define i1 @usubo.not.i64(i64 %v1, i64 %v2) {
1072 ; SDAG-LABEL: usubo.not.i64:
1073 ; SDAG: // %bb.0: // %entry
1074 ; SDAG-NEXT: cmp x0, x1
1075 ; SDAG-NEXT: cset w0, hs
1078 ; FAST-LABEL: usubo.not.i64:
1079 ; FAST: // %bb.0: // %entry
1080 ; FAST-NEXT: cmp x0, x1
1081 ; FAST-NEXT: cset w0, hs
1084 ; GISEL-LABEL: usubo.not.i64:
1085 ; GISEL: // %bb.0: // %entry
1086 ; GISEL-NEXT: cmp x0, x1
1087 ; GISEL-NEXT: cset w8, lo
1088 ; GISEL-NEXT: eor w0, w8, #0x1
1091 %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2)
1092 %obit = extractvalue {i64, i1} %t, 1
1093 %ret = xor i1 %obit, true
1097 define i32 @smulo.select.i32(i32 %v1, i32 %v2) {
1098 ; SDAG-LABEL: smulo.select.i32:
1099 ; SDAG: // %bb.0: // %entry
1100 ; SDAG-NEXT: smull x8, w0, w1
1101 ; SDAG-NEXT: cmp x8, w8, sxtw
1102 ; SDAG-NEXT: csel w0, w0, w1, ne
1105 ; FAST-LABEL: smulo.select.i32:
1106 ; FAST: // %bb.0: // %entry
1107 ; FAST-NEXT: smull x8, w0, w1
1108 ; FAST-NEXT: cmp x8, w8, sxtw
1109 ; FAST-NEXT: csel w0, w0, w1, ne
1112 ; GISEL-LABEL: smulo.select.i32:
1113 ; GISEL: // %bb.0: // %entry
1114 ; GISEL-NEXT: smull x8, w0, w1
1115 ; GISEL-NEXT: mul w9, w0, w1
1116 ; GISEL-NEXT: asr x8, x8, #32
1117 ; GISEL-NEXT: cmp w8, w9, asr #31
1118 ; GISEL-NEXT: csel w0, w0, w1, ne
1121 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
1122 %obit = extractvalue {i32, i1} %t, 1
1123 %ret = select i1 %obit, i32 %v1, i32 %v2
1127 define i1 @smulo.not.i32(i32 %v1, i32 %v2) {
1128 ; SDAG-LABEL: smulo.not.i32:
1129 ; SDAG: // %bb.0: // %entry
1130 ; SDAG-NEXT: smull x8, w0, w1
1131 ; SDAG-NEXT: cmp x8, w8, sxtw
1132 ; SDAG-NEXT: cset w0, eq
1135 ; FAST-LABEL: smulo.not.i32:
1136 ; FAST: // %bb.0: // %entry
1137 ; FAST-NEXT: smull x8, w0, w1
1138 ; FAST-NEXT: cmp x8, w8, sxtw
1139 ; FAST-NEXT: cset w0, eq
1142 ; GISEL-LABEL: smulo.not.i32:
1143 ; GISEL: // %bb.0: // %entry
1144 ; GISEL-NEXT: smull x8, w0, w1
1145 ; GISEL-NEXT: mul w9, w0, w1
1146 ; GISEL-NEXT: asr x8, x8, #32
1147 ; GISEL-NEXT: cmp w8, w9, asr #31
1148 ; GISEL-NEXT: cset w8, ne
1149 ; GISEL-NEXT: eor w0, w8, #0x1
1152 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
1153 %obit = extractvalue {i32, i1} %t, 1
1154 %ret = xor i1 %obit, true
1158 define i64 @smulo.select.i64(i64 %v1, i64 %v2) {
1159 ; SDAG-LABEL: smulo.select.i64:
1160 ; SDAG: // %bb.0: // %entry
1161 ; SDAG-NEXT: mul x8, x0, x1
1162 ; SDAG-NEXT: smulh x9, x0, x1
1163 ; SDAG-NEXT: cmp x9, x8, asr #63
1164 ; SDAG-NEXT: csel x0, x0, x1, ne
1167 ; FAST-LABEL: smulo.select.i64:
1168 ; FAST: // %bb.0: // %entry
1169 ; FAST-NEXT: mul x8, x0, x1
1170 ; FAST-NEXT: smulh x9, x0, x1
1171 ; FAST-NEXT: cmp x9, x8, asr #63
1172 ; FAST-NEXT: csel x0, x0, x1, ne
1175 ; GISEL-LABEL: smulo.select.i64:
1176 ; GISEL: // %bb.0: // %entry
1177 ; GISEL-NEXT: smulh x8, x0, x1
1178 ; GISEL-NEXT: mul x9, x0, x1
1179 ; GISEL-NEXT: cmp x8, x9, asr #63
1180 ; GISEL-NEXT: csel x0, x0, x1, ne
1183 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
1184 %obit = extractvalue {i64, i1} %t, 1
1185 %ret = select i1 %obit, i64 %v1, i64 %v2
1189 define i1 @smulo.not.i64(i64 %v1, i64 %v2) {
1190 ; SDAG-LABEL: smulo.not.i64:
1191 ; SDAG: // %bb.0: // %entry
1192 ; SDAG-NEXT: mul x8, x0, x1
1193 ; SDAG-NEXT: smulh x9, x0, x1
1194 ; SDAG-NEXT: cmp x9, x8, asr #63
1195 ; SDAG-NEXT: cset w0, eq
1198 ; FAST-LABEL: smulo.not.i64:
1199 ; FAST: // %bb.0: // %entry
1200 ; FAST-NEXT: mul x8, x0, x1
1201 ; FAST-NEXT: smulh x9, x0, x1
1202 ; FAST-NEXT: cmp x9, x8, asr #63
1203 ; FAST-NEXT: cset w0, eq
1206 ; GISEL-LABEL: smulo.not.i64:
1207 ; GISEL: // %bb.0: // %entry
1208 ; GISEL-NEXT: smulh x8, x0, x1
1209 ; GISEL-NEXT: mul x9, x0, x1
1210 ; GISEL-NEXT: cmp x8, x9, asr #63
1211 ; GISEL-NEXT: cset w8, ne
1212 ; GISEL-NEXT: eor w0, w8, #0x1
1215 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
1216 %obit = extractvalue {i64, i1} %t, 1
1217 %ret = xor i1 %obit, true
1221 define i32 @umulo.select.i32(i32 %v1, i32 %v2) {
1222 ; SDAG-LABEL: umulo.select.i32:
1223 ; SDAG: // %bb.0: // %entry
1224 ; SDAG-NEXT: umull x8, w0, w1
1225 ; SDAG-NEXT: tst x8, #0xffffffff00000000
1226 ; SDAG-NEXT: csel w0, w0, w1, ne
1229 ; FAST-LABEL: umulo.select.i32:
1230 ; FAST: // %bb.0: // %entry
1231 ; FAST-NEXT: umull x8, w0, w1
1232 ; FAST-NEXT: tst x8, #0xffffffff00000000
1233 ; FAST-NEXT: csel w0, w0, w1, ne
1236 ; GISEL-LABEL: umulo.select.i32:
1237 ; GISEL: // %bb.0: // %entry
1238 ; GISEL-NEXT: umull x8, w0, w1
1239 ; GISEL-NEXT: lsr x8, x8, #32
1240 ; GISEL-NEXT: cmp w8, #0
1241 ; GISEL-NEXT: csel w0, w0, w1, ne
1244 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
1245 %obit = extractvalue {i32, i1} %t, 1
1246 %ret = select i1 %obit, i32 %v1, i32 %v2
1250 define i1 @umulo.not.i32(i32 %v1, i32 %v2) {
1251 ; SDAG-LABEL: umulo.not.i32:
1252 ; SDAG: // %bb.0: // %entry
1253 ; SDAG-NEXT: umull x8, w0, w1
1254 ; SDAG-NEXT: tst x8, #0xffffffff00000000
1255 ; SDAG-NEXT: cset w0, eq
1258 ; FAST-LABEL: umulo.not.i32:
1259 ; FAST: // %bb.0: // %entry
1260 ; FAST-NEXT: umull x8, w0, w1
1261 ; FAST-NEXT: tst x8, #0xffffffff00000000
1262 ; FAST-NEXT: cset w0, eq
1265 ; GISEL-LABEL: umulo.not.i32:
1266 ; GISEL: // %bb.0: // %entry
1267 ; GISEL-NEXT: umull x8, w0, w1
1268 ; GISEL-NEXT: lsr x8, x8, #32
1269 ; GISEL-NEXT: cmp w8, #0
1270 ; GISEL-NEXT: cset w8, ne
1271 ; GISEL-NEXT: eor w0, w8, #0x1
1274 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
1275 %obit = extractvalue {i32, i1} %t, 1
1276 %ret = xor i1 %obit, true
1280 define i64 @umulo.select.i64(i64 %v1, i64 %v2) {
1281 ; SDAG-LABEL: umulo.select.i64:
1282 ; SDAG: // %bb.0: // %entry
1283 ; SDAG-NEXT: umulh x8, x0, x1
1284 ; SDAG-NEXT: cmp xzr, x8
1285 ; SDAG-NEXT: csel x0, x0, x1, ne
1288 ; FAST-LABEL: umulo.select.i64:
1289 ; FAST: // %bb.0: // %entry
1290 ; FAST-NEXT: umulh x8, x0, x1
1291 ; FAST-NEXT: cmp xzr, x8
1292 ; FAST-NEXT: csel x0, x0, x1, ne
1295 ; GISEL-LABEL: umulo.select.i64:
1296 ; GISEL: // %bb.0: // %entry
1297 ; GISEL-NEXT: umulh x8, x0, x1
1298 ; GISEL-NEXT: cmp x8, #0
1299 ; GISEL-NEXT: csel x0, x0, x1, ne
1302 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
1303 %obit = extractvalue {i64, i1} %t, 1
1304 %ret = select i1 %obit, i64 %v1, i64 %v2
1308 define i1 @umulo.not.i64(i64 %v1, i64 %v2) {
1309 ; SDAG-LABEL: umulo.not.i64:
1310 ; SDAG: // %bb.0: // %entry
1311 ; SDAG-NEXT: umulh x8, x0, x1
1312 ; SDAG-NEXT: cmp xzr, x8
1313 ; SDAG-NEXT: cset w0, eq
1316 ; FAST-LABEL: umulo.not.i64:
1317 ; FAST: // %bb.0: // %entry
1318 ; FAST-NEXT: umulh x8, x0, x1
1319 ; FAST-NEXT: cmp xzr, x8
1320 ; FAST-NEXT: cset w0, eq
1323 ; GISEL-LABEL: umulo.not.i64:
1324 ; GISEL: // %bb.0: // %entry
1325 ; GISEL-NEXT: umulh x8, x0, x1
1326 ; GISEL-NEXT: cmp x8, #0
1327 ; GISEL-NEXT: cset w8, ne
1328 ; GISEL-NEXT: eor w0, w8, #0x1
1331 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
1332 %obit = extractvalue {i64, i1} %t, 1
1333 %ret = xor i1 %obit, true
1338 define i8 @uaddo.selectboth.i8(i8 %a, i8 %b) {
1339 ; SDAG-LABEL: uaddo.selectboth.i8:
1340 ; SDAG: // %bb.0: // %entry
1341 ; SDAG-NEXT: and w9, w0, #0xff
1342 ; SDAG-NEXT: mov w8, #10 // =0xa
1343 ; SDAG-NEXT: add w9, w9, w1, uxtb
1344 ; SDAG-NEXT: tst w9, #0x100
1345 ; SDAG-NEXT: csel w0, w9, w8, ne
1348 ; FAST-LABEL: uaddo.selectboth.i8:
1349 ; FAST: // %bb.0: // %entry
1350 ; FAST-NEXT: and w9, w0, #0xff
1351 ; FAST-NEXT: mov w8, #10 // =0xa
1352 ; FAST-NEXT: add w9, w9, w1, uxtb
1353 ; FAST-NEXT: tst w9, #0x100
1354 ; FAST-NEXT: csel w0, w9, w8, ne
1357 ; GISEL-LABEL: uaddo.selectboth.i8:
1358 ; GISEL: // %bb.0: // %entry
1359 ; GISEL-NEXT: and w9, w1, #0xff
1360 ; GISEL-NEXT: mov w8, #10 // =0xa
1361 ; GISEL-NEXT: add w9, w9, w0, uxtb
1362 ; GISEL-NEXT: cmp w9, w9, uxtb
1363 ; GISEL-NEXT: csel w0, w9, w8, ne
1366 %m = call { i8, i1 } @llvm.uadd.with.overflow.i8(i8 %a, i8 %b)
1367 %m1 = extractvalue { i8, i1 } %m, 0
1368 %m2 = extractvalue { i8, i1 } %m, 1
1369 %r = select i1 %m2, i8 %m1, i8 10
1373 define i8 @saddo.selectboth.i8(i8 %a, i8 %b) {
1374 ; SDAG-LABEL: saddo.selectboth.i8:
1375 ; SDAG: // %bb.0: // %entry
1376 ; SDAG-NEXT: sxtb w9, w0
1377 ; SDAG-NEXT: mov w8, #10 // =0xa
1378 ; SDAG-NEXT: add w9, w9, w1, sxtb
1379 ; SDAG-NEXT: cmp w9, w9, sxtb
1380 ; SDAG-NEXT: csel w0, w9, w8, ne
1383 ; FAST-LABEL: saddo.selectboth.i8:
1384 ; FAST: // %bb.0: // %entry
1385 ; FAST-NEXT: sxtb w9, w0
1386 ; FAST-NEXT: mov w8, #10 // =0xa
1387 ; FAST-NEXT: add w9, w9, w1, sxtb
1388 ; FAST-NEXT: cmp w9, w9, sxtb
1389 ; FAST-NEXT: csel w0, w9, w8, ne
1392 ; GISEL-LABEL: saddo.selectboth.i8:
1393 ; GISEL: // %bb.0: // %entry
1394 ; GISEL-NEXT: sxtb w9, w1
1395 ; GISEL-NEXT: mov w8, #10 // =0xa
1396 ; GISEL-NEXT: add w9, w9, w0, sxtb
1397 ; GISEL-NEXT: cmp w9, w9, sxtb
1398 ; GISEL-NEXT: csel w0, w9, w8, ne
1401 %m = call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 %a, i8 %b)
1402 %m1 = extractvalue { i8, i1 } %m, 0
1403 %m2 = extractvalue { i8, i1 } %m, 1
1404 %r = select i1 %m2, i8 %m1, i8 10
1408 define i16 @uaddo.selectboth.i16(i16 %a, i16 %b) {
1409 ; SDAG-LABEL: uaddo.selectboth.i16:
1410 ; SDAG: // %bb.0: // %entry
1411 ; SDAG-NEXT: and w9, w0, #0xffff
1412 ; SDAG-NEXT: mov w8, #10 // =0xa
1413 ; SDAG-NEXT: add w9, w9, w1, uxth
1414 ; SDAG-NEXT: tst w9, #0x10000
1415 ; SDAG-NEXT: csel w0, w9, w8, ne
1418 ; FAST-LABEL: uaddo.selectboth.i16:
1419 ; FAST: // %bb.0: // %entry
1420 ; FAST-NEXT: and w9, w0, #0xffff
1421 ; FAST-NEXT: mov w8, #10 // =0xa
1422 ; FAST-NEXT: add w9, w9, w1, uxth
1423 ; FAST-NEXT: tst w9, #0x10000
1424 ; FAST-NEXT: csel w0, w9, w8, ne
1427 ; GISEL-LABEL: uaddo.selectboth.i16:
1428 ; GISEL: // %bb.0: // %entry
1429 ; GISEL-NEXT: and w9, w1, #0xffff
1430 ; GISEL-NEXT: mov w8, #10 // =0xa
1431 ; GISEL-NEXT: add w9, w9, w0, uxth
1432 ; GISEL-NEXT: cmp w9, w9, uxth
1433 ; GISEL-NEXT: csel w0, w9, w8, ne
1436 %m = call { i16, i1 } @llvm.uadd.with.overflow.i16(i16 %a, i16 %b)
1437 %m1 = extractvalue { i16, i1 } %m, 0
1438 %m2 = extractvalue { i16, i1 } %m, 1
1439 %r = select i1 %m2, i16 %m1, i16 10
1443 define i16 @saddo.selectboth.i16(i16 %a, i16 %b) {
1444 ; SDAG-LABEL: saddo.selectboth.i16:
1445 ; SDAG: // %bb.0: // %entry
1446 ; SDAG-NEXT: sxth w9, w0
1447 ; SDAG-NEXT: mov w8, #10 // =0xa
1448 ; SDAG-NEXT: add w9, w9, w1, sxth
1449 ; SDAG-NEXT: cmp w9, w9, sxth
1450 ; SDAG-NEXT: csel w0, w9, w8, ne
1453 ; FAST-LABEL: saddo.selectboth.i16:
1454 ; FAST: // %bb.0: // %entry
1455 ; FAST-NEXT: sxth w9, w0
1456 ; FAST-NEXT: mov w8, #10 // =0xa
1457 ; FAST-NEXT: add w9, w9, w1, sxth
1458 ; FAST-NEXT: cmp w9, w9, sxth
1459 ; FAST-NEXT: csel w0, w9, w8, ne
1462 ; GISEL-LABEL: saddo.selectboth.i16:
1463 ; GISEL: // %bb.0: // %entry
1464 ; GISEL-NEXT: sxth w9, w1
1465 ; GISEL-NEXT: mov w8, #10 // =0xa
1466 ; GISEL-NEXT: add w9, w9, w0, sxth
1467 ; GISEL-NEXT: cmp w9, w9, sxth
1468 ; GISEL-NEXT: csel w0, w9, w8, ne
1471 %m = call { i16, i1 } @llvm.sadd.with.overflow.i16(i16 %a, i16 %b)
1472 %m1 = extractvalue { i16, i1 } %m, 0
1473 %m2 = extractvalue { i16, i1 } %m, 1
1474 %r = select i1 %m2, i16 %m1, i16 10
1478 define i32 @uaddo.selectboth.i32(i32 %a, i32 %b) {
1479 ; SDAG-LABEL: uaddo.selectboth.i32:
1480 ; SDAG: // %bb.0: // %entry
1481 ; SDAG-NEXT: mov w8, #10 // =0xa
1482 ; SDAG-NEXT: adds w9, w0, w1
1483 ; SDAG-NEXT: csel w0, w9, w8, hs
1486 ; FAST-LABEL: uaddo.selectboth.i32:
1487 ; FAST: // %bb.0: // %entry
1488 ; FAST-NEXT: mov w8, #10 // =0xa
1489 ; FAST-NEXT: adds w9, w0, w1
1490 ; FAST-NEXT: csel w0, w9, w8, hs
1493 ; GISEL-LABEL: uaddo.selectboth.i32:
1494 ; GISEL: // %bb.0: // %entry
1495 ; GISEL-NEXT: adds w9, w0, w1
1496 ; GISEL-NEXT: mov w8, #10 // =0xa
1497 ; GISEL-NEXT: cset w10, hs
1498 ; GISEL-NEXT: tst w10, #0x1
1499 ; GISEL-NEXT: csel w0, w9, w8, ne
1502 %m = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %a, i32 %b)
1503 %m1 = extractvalue { i32, i1 } %m, 0
1504 %m2 = extractvalue { i32, i1 } %m, 1
1505 %r = select i1 %m2, i32 %m1, i32 10
1509 define i32 @saddo.selectboth.i32(i32 %a, i32 %b) {
1510 ; SDAG-LABEL: saddo.selectboth.i32:
1511 ; SDAG: // %bb.0: // %entry
1512 ; SDAG-NEXT: mov w8, #10 // =0xa
1513 ; SDAG-NEXT: adds w9, w0, w1
1514 ; SDAG-NEXT: csel w0, w9, w8, vs
1517 ; FAST-LABEL: saddo.selectboth.i32:
1518 ; FAST: // %bb.0: // %entry
1519 ; FAST-NEXT: mov w8, #10 // =0xa
1520 ; FAST-NEXT: adds w9, w0, w1
1521 ; FAST-NEXT: csel w0, w9, w8, vs
1524 ; GISEL-LABEL: saddo.selectboth.i32:
1525 ; GISEL: // %bb.0: // %entry
1526 ; GISEL-NEXT: adds w9, w0, w1
1527 ; GISEL-NEXT: mov w8, #10 // =0xa
1528 ; GISEL-NEXT: cset w10, vs
1529 ; GISEL-NEXT: tst w10, #0x1
1530 ; GISEL-NEXT: csel w0, w9, w8, ne
1533 %m = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %a, i32 %b)
1534 %m1 = extractvalue { i32, i1 } %m, 0
1535 %m2 = extractvalue { i32, i1 } %m, 1
1536 %r = select i1 %m2, i32 %m1, i32 10
1540 define i64 @uaddo.selectboth.i64(i64 %a, i64 %b) {
1541 ; SDAG-LABEL: uaddo.selectboth.i64:
1542 ; SDAG: // %bb.0: // %entry
1543 ; SDAG-NEXT: mov w8, #10 // =0xa
1544 ; SDAG-NEXT: adds x9, x0, x1
1545 ; SDAG-NEXT: csel x0, x9, x8, hs
1548 ; FAST-LABEL: uaddo.selectboth.i64:
1549 ; FAST: // %bb.0: // %entry
1550 ; FAST-NEXT: mov x8, #10 // =0xa
1551 ; FAST-NEXT: adds x9, x0, x1
1552 ; FAST-NEXT: csel x0, x9, x8, hs
1555 ; GISEL-LABEL: uaddo.selectboth.i64:
1556 ; GISEL: // %bb.0: // %entry
1557 ; GISEL-NEXT: adds x9, x0, x1
1558 ; GISEL-NEXT: mov w8, #10 // =0xa
1559 ; GISEL-NEXT: cset w10, hs
1560 ; GISEL-NEXT: tst w10, #0x1
1561 ; GISEL-NEXT: csel x0, x9, x8, ne
1564 %m = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %a, i64 %b)
1565 %m1 = extractvalue { i64, i1 } %m, 0
1566 %m2 = extractvalue { i64, i1 } %m, 1
1567 %r = select i1 %m2, i64 %m1, i64 10
1571 define i64 @saddo.selectboth.i64(i64 %a, i64 %b) {
1572 ; SDAG-LABEL: saddo.selectboth.i64:
1573 ; SDAG: // %bb.0: // %entry
1574 ; SDAG-NEXT: mov w8, #10 // =0xa
1575 ; SDAG-NEXT: adds x9, x0, x1
1576 ; SDAG-NEXT: csel x0, x9, x8, vs
1579 ; FAST-LABEL: saddo.selectboth.i64:
1580 ; FAST: // %bb.0: // %entry
1581 ; FAST-NEXT: mov x8, #10 // =0xa
1582 ; FAST-NEXT: adds x9, x0, x1
1583 ; FAST-NEXT: csel x0, x9, x8, vs
1586 ; GISEL-LABEL: saddo.selectboth.i64:
1587 ; GISEL: // %bb.0: // %entry
1588 ; GISEL-NEXT: adds x9, x0, x1
1589 ; GISEL-NEXT: mov w8, #10 // =0xa
1590 ; GISEL-NEXT: cset w10, vs
1591 ; GISEL-NEXT: tst w10, #0x1
1592 ; GISEL-NEXT: csel x0, x9, x8, ne
1595 %m = call { i64, i1 } @llvm.sadd.with.overflow.i64(i64 %a, i64 %b)
1596 %m1 = extractvalue { i64, i1 } %m, 0
1597 %m2 = extractvalue { i64, i1 } %m, 1
1598 %r = select i1 %m2, i64 %m1, i64 10
1602 define i8 @usubo.selectboth.i8(i8 %a, i8 %b) {
1603 ; SDAG-LABEL: usubo.selectboth.i8:
1604 ; SDAG: // %bb.0: // %entry
1605 ; SDAG-NEXT: and w9, w0, #0xff
1606 ; SDAG-NEXT: mov w8, #10 // =0xa
1607 ; SDAG-NEXT: sub w9, w9, w1, uxtb
1608 ; SDAG-NEXT: tst w9, #0xffffff00
1609 ; SDAG-NEXT: csel w0, w9, w8, ne
1612 ; FAST-LABEL: usubo.selectboth.i8:
1613 ; FAST: // %bb.0: // %entry
1614 ; FAST-NEXT: and w9, w0, #0xff
1615 ; FAST-NEXT: mov w8, #10 // =0xa
1616 ; FAST-NEXT: sub w9, w9, w1, uxtb
1617 ; FAST-NEXT: tst w9, #0xffffff00
1618 ; FAST-NEXT: csel w0, w9, w8, ne
1621 ; GISEL-LABEL: usubo.selectboth.i8:
1622 ; GISEL: // %bb.0: // %entry
1623 ; GISEL-NEXT: and w9, w0, #0xff
1624 ; GISEL-NEXT: mov w8, #10 // =0xa
1625 ; GISEL-NEXT: sub w9, w9, w1, uxtb
1626 ; GISEL-NEXT: cmp w9, w9, uxtb
1627 ; GISEL-NEXT: csel w0, w9, w8, ne
1630 %m = call { i8, i1 } @llvm.usub.with.overflow.i8(i8 %a, i8 %b)
1631 %m1 = extractvalue { i8, i1 } %m, 0
1632 %m2 = extractvalue { i8, i1 } %m, 1
1633 %r = select i1 %m2, i8 %m1, i8 10
1637 define i8 @ssubo.selectboth.i8(i8 %a, i8 %b) {
1638 ; CHECK-LABEL: ssubo.selectboth.i8:
1639 ; CHECK: // %bb.0: // %entry
1640 ; CHECK-NEXT: sxtb w9, w0
1641 ; CHECK-NEXT: mov w8, #10 // =0xa
1642 ; CHECK-NEXT: sub w9, w9, w1, sxtb
1643 ; CHECK-NEXT: cmp w9, w9, sxtb
1644 ; CHECK-NEXT: csel w0, w9, w8, ne
1647 %m = call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %a, i8 %b)
1648 %m1 = extractvalue { i8, i1 } %m, 0
1649 %m2 = extractvalue { i8, i1 } %m, 1
1650 %r = select i1 %m2, i8 %m1, i8 10
1654 define i16 @usubo.selectboth.i16(i16 %a, i16 %b) {
1655 ; SDAG-LABEL: usubo.selectboth.i16:
1656 ; SDAG: // %bb.0: // %entry
1657 ; SDAG-NEXT: and w9, w0, #0xffff
1658 ; SDAG-NEXT: mov w8, #10 // =0xa
1659 ; SDAG-NEXT: sub w9, w9, w1, uxth
1660 ; SDAG-NEXT: tst w9, #0xffff0000
1661 ; SDAG-NEXT: csel w0, w9, w8, ne
1664 ; FAST-LABEL: usubo.selectboth.i16:
1665 ; FAST: // %bb.0: // %entry
1666 ; FAST-NEXT: and w9, w0, #0xffff
1667 ; FAST-NEXT: mov w8, #10 // =0xa
1668 ; FAST-NEXT: sub w9, w9, w1, uxth
1669 ; FAST-NEXT: tst w9, #0xffff0000
1670 ; FAST-NEXT: csel w0, w9, w8, ne
1673 ; GISEL-LABEL: usubo.selectboth.i16:
1674 ; GISEL: // %bb.0: // %entry
1675 ; GISEL-NEXT: and w9, w0, #0xffff
1676 ; GISEL-NEXT: mov w8, #10 // =0xa
1677 ; GISEL-NEXT: sub w9, w9, w1, uxth
1678 ; GISEL-NEXT: cmp w9, w9, uxth
1679 ; GISEL-NEXT: csel w0, w9, w8, ne
1682 %m = call { i16, i1 } @llvm.usub.with.overflow.i16(i16 %a, i16 %b)
1683 %m1 = extractvalue { i16, i1 } %m, 0
1684 %m2 = extractvalue { i16, i1 } %m, 1
1685 %r = select i1 %m2, i16 %m1, i16 10
1689 define i16 @ssubo.selectboth.i16(i16 %a, i16 %b) {
1690 ; CHECK-LABEL: ssubo.selectboth.i16:
1691 ; CHECK: // %bb.0: // %entry
1692 ; CHECK-NEXT: sxth w9, w0
1693 ; CHECK-NEXT: mov w8, #10 // =0xa
1694 ; CHECK-NEXT: sub w9, w9, w1, sxth
1695 ; CHECK-NEXT: cmp w9, w9, sxth
1696 ; CHECK-NEXT: csel w0, w9, w8, ne
1699 %m = call { i16, i1 } @llvm.ssub.with.overflow.i16(i16 %a, i16 %b)
1700 %m1 = extractvalue { i16, i1 } %m, 0
1701 %m2 = extractvalue { i16, i1 } %m, 1
1702 %r = select i1 %m2, i16 %m1, i16 10
1706 define i32 @usubo.selectboth.i32(i32 %a, i32 %b) {
1707 ; SDAG-LABEL: usubo.selectboth.i32:
1708 ; SDAG: // %bb.0: // %entry
1709 ; SDAG-NEXT: mov w8, #10 // =0xa
1710 ; SDAG-NEXT: subs w9, w0, w1
1711 ; SDAG-NEXT: csel w0, w9, w8, lo
1714 ; FAST-LABEL: usubo.selectboth.i32:
1715 ; FAST: // %bb.0: // %entry
1716 ; FAST-NEXT: mov w8, #10 // =0xa
1717 ; FAST-NEXT: subs w9, w0, w1
1718 ; FAST-NEXT: csel w0, w9, w8, lo
1721 ; GISEL-LABEL: usubo.selectboth.i32:
1722 ; GISEL: // %bb.0: // %entry
1723 ; GISEL-NEXT: subs w9, w0, w1
1724 ; GISEL-NEXT: mov w8, #10 // =0xa
1725 ; GISEL-NEXT: cset w10, lo
1726 ; GISEL-NEXT: tst w10, #0x1
1727 ; GISEL-NEXT: csel w0, w9, w8, ne
1730 %m = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %a, i32 %b)
1731 %m1 = extractvalue { i32, i1 } %m, 0
1732 %m2 = extractvalue { i32, i1 } %m, 1
1733 %r = select i1 %m2, i32 %m1, i32 10
1737 define i32 @ssubo.selectboth.i32(i32 %a, i32 %b) {
1738 ; SDAG-LABEL: ssubo.selectboth.i32:
1739 ; SDAG: // %bb.0: // %entry
1740 ; SDAG-NEXT: mov w8, #10 // =0xa
1741 ; SDAG-NEXT: subs w9, w0, w1
1742 ; SDAG-NEXT: csel w0, w9, w8, vs
1745 ; FAST-LABEL: ssubo.selectboth.i32:
1746 ; FAST: // %bb.0: // %entry
1747 ; FAST-NEXT: mov w8, #10 // =0xa
1748 ; FAST-NEXT: subs w9, w0, w1
1749 ; FAST-NEXT: csel w0, w9, w8, vs
1752 ; GISEL-LABEL: ssubo.selectboth.i32:
1753 ; GISEL: // %bb.0: // %entry
1754 ; GISEL-NEXT: subs w9, w0, w1
1755 ; GISEL-NEXT: mov w8, #10 // =0xa
1756 ; GISEL-NEXT: cset w10, vs
1757 ; GISEL-NEXT: tst w10, #0x1
1758 ; GISEL-NEXT: csel w0, w9, w8, ne
1761 %m = call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %a, i32 %b)
1762 %m1 = extractvalue { i32, i1 } %m, 0
1763 %m2 = extractvalue { i32, i1 } %m, 1
1764 %r = select i1 %m2, i32 %m1, i32 10
1768 define i64 @usubo.selectboth.i64(i64 %a, i64 %b) {
1769 ; SDAG-LABEL: usubo.selectboth.i64:
1770 ; SDAG: // %bb.0: // %entry
1771 ; SDAG-NEXT: mov w8, #10 // =0xa
1772 ; SDAG-NEXT: subs x9, x0, x1
1773 ; SDAG-NEXT: csel x0, x9, x8, lo
1776 ; FAST-LABEL: usubo.selectboth.i64:
1777 ; FAST: // %bb.0: // %entry
1778 ; FAST-NEXT: mov x8, #10 // =0xa
1779 ; FAST-NEXT: subs x9, x0, x1
1780 ; FAST-NEXT: csel x0, x9, x8, lo
1783 ; GISEL-LABEL: usubo.selectboth.i64:
1784 ; GISEL: // %bb.0: // %entry
1785 ; GISEL-NEXT: subs x9, x0, x1
1786 ; GISEL-NEXT: mov w8, #10 // =0xa
1787 ; GISEL-NEXT: cset w10, lo
1788 ; GISEL-NEXT: tst w10, #0x1
1789 ; GISEL-NEXT: csel x0, x9, x8, ne
1792 %m = call { i64, i1 } @llvm.usub.with.overflow.i64(i64 %a, i64 %b)
1793 %m1 = extractvalue { i64, i1 } %m, 0
1794 %m2 = extractvalue { i64, i1 } %m, 1
1795 %r = select i1 %m2, i64 %m1, i64 10
1799 define i64 @ssubo.selectboth.i64(i64 %a, i64 %b) {
1800 ; SDAG-LABEL: ssubo.selectboth.i64:
1801 ; SDAG: // %bb.0: // %entry
1802 ; SDAG-NEXT: mov w8, #10 // =0xa
1803 ; SDAG-NEXT: subs x9, x0, x1
1804 ; SDAG-NEXT: csel x0, x9, x8, vs
1807 ; FAST-LABEL: ssubo.selectboth.i64:
1808 ; FAST: // %bb.0: // %entry
1809 ; FAST-NEXT: mov x8, #10 // =0xa
1810 ; FAST-NEXT: subs x9, x0, x1
1811 ; FAST-NEXT: csel x0, x9, x8, vs
1814 ; GISEL-LABEL: ssubo.selectboth.i64:
1815 ; GISEL: // %bb.0: // %entry
1816 ; GISEL-NEXT: subs x9, x0, x1
1817 ; GISEL-NEXT: mov w8, #10 // =0xa
1818 ; GISEL-NEXT: cset w10, vs
1819 ; GISEL-NEXT: tst w10, #0x1
1820 ; GISEL-NEXT: csel x0, x9, x8, ne
1823 %m = call { i64, i1 } @llvm.ssub.with.overflow.i64(i64 %a, i64 %b)
1824 %m1 = extractvalue { i64, i1 } %m, 0
1825 %m2 = extractvalue { i64, i1 } %m, 1
1826 %r = select i1 %m2, i64 %m1, i64 10
1831 define i8 @umulo.selectboth.i8(i8 %a, i8 %b) {
1832 ; SDAG-LABEL: umulo.selectboth.i8:
1833 ; SDAG: // %bb.0: // %entry
1834 ; SDAG-NEXT: and w9, w1, #0xff
1835 ; SDAG-NEXT: and w10, w0, #0xff
1836 ; SDAG-NEXT: mov w8, #10 // =0xa
1837 ; SDAG-NEXT: mul w9, w10, w9
1838 ; SDAG-NEXT: tst w9, #0xff00
1839 ; SDAG-NEXT: csel w0, w9, w8, ne
1842 ; FAST-LABEL: umulo.selectboth.i8:
1843 ; FAST: // %bb.0: // %entry
1844 ; FAST-NEXT: and w9, w1, #0xff
1845 ; FAST-NEXT: and w10, w0, #0xff
1846 ; FAST-NEXT: mov w8, #10 // =0xa
1847 ; FAST-NEXT: mul w9, w10, w9
1848 ; FAST-NEXT: tst w9, #0xff00
1849 ; FAST-NEXT: csel w0, w9, w8, ne
1852 ; GISEL-LABEL: umulo.selectboth.i8:
1853 ; GISEL: // %bb.0: // %entry
1854 ; GISEL-NEXT: and w9, w0, #0xff
1855 ; GISEL-NEXT: and w10, w1, #0xff
1856 ; GISEL-NEXT: mov w8, #10 // =0xa
1857 ; GISEL-NEXT: mul w9, w9, w10
1858 ; GISEL-NEXT: cmp w9, w9, uxtb
1859 ; GISEL-NEXT: csel w0, w9, w8, ne
1862 %m = call { i8, i1 } @llvm.umul.with.overflow.i8(i8 %a, i8 %b)
1863 %m1 = extractvalue { i8, i1 } %m, 0
1864 %m2 = extractvalue { i8, i1 } %m, 1
1865 %r = select i1 %m2, i8 %m1, i8 10
1869 define i8 @smulo.selectboth.i8(i8 %a, i8 %b) {
1870 ; SDAG-LABEL: smulo.selectboth.i8:
1871 ; SDAG: // %bb.0: // %entry
1872 ; SDAG-NEXT: sxtb w9, w1
1873 ; SDAG-NEXT: sxtb w10, w0
1874 ; SDAG-NEXT: mov w8, #10 // =0xa
1875 ; SDAG-NEXT: mul w9, w10, w9
1876 ; SDAG-NEXT: cmp w9, w9, sxtb
1877 ; SDAG-NEXT: csel w0, w9, w8, ne
1880 ; FAST-LABEL: smulo.selectboth.i8:
1881 ; FAST: // %bb.0: // %entry
1882 ; FAST-NEXT: sxtb w9, w1
1883 ; FAST-NEXT: sxtb w10, w0
1884 ; FAST-NEXT: mov w8, #10 // =0xa
1885 ; FAST-NEXT: mul w9, w10, w9
1886 ; FAST-NEXT: cmp w9, w9, sxtb
1887 ; FAST-NEXT: csel w0, w9, w8, ne
1890 ; GISEL-LABEL: smulo.selectboth.i8:
1891 ; GISEL: // %bb.0: // %entry
1892 ; GISEL-NEXT: sxtb w9, w0
1893 ; GISEL-NEXT: sxtb w10, w1
1894 ; GISEL-NEXT: mov w8, #10 // =0xa
1895 ; GISEL-NEXT: mul w9, w9, w10
1896 ; GISEL-NEXT: cmp w9, w9, sxtb
1897 ; GISEL-NEXT: csel w0, w9, w8, ne
1900 %m = call { i8, i1 } @llvm.smul.with.overflow.i8(i8 %a, i8 %b)
1901 %m1 = extractvalue { i8, i1 } %m, 0
1902 %m2 = extractvalue { i8, i1 } %m, 1
1903 %r = select i1 %m2, i8 %m1, i8 10
1907 define i16 @umulo.selectboth.i16(i16 %a, i16 %b) {
1908 ; SDAG-LABEL: umulo.selectboth.i16:
1909 ; SDAG: // %bb.0: // %entry
1910 ; SDAG-NEXT: and w9, w1, #0xffff
1911 ; SDAG-NEXT: and w10, w0, #0xffff
1912 ; SDAG-NEXT: mov w8, #10 // =0xa
1913 ; SDAG-NEXT: mul w9, w10, w9
1914 ; SDAG-NEXT: tst w9, #0xffff0000
1915 ; SDAG-NEXT: csel w0, w9, w8, ne
1918 ; FAST-LABEL: umulo.selectboth.i16:
1919 ; FAST: // %bb.0: // %entry
1920 ; FAST-NEXT: and w9, w1, #0xffff
1921 ; FAST-NEXT: and w10, w0, #0xffff
1922 ; FAST-NEXT: mov w8, #10 // =0xa
1923 ; FAST-NEXT: mul w9, w10, w9
1924 ; FAST-NEXT: tst w9, #0xffff0000
1925 ; FAST-NEXT: csel w0, w9, w8, ne
1928 ; GISEL-LABEL: umulo.selectboth.i16:
1929 ; GISEL: // %bb.0: // %entry
1930 ; GISEL-NEXT: and w9, w0, #0xffff
1931 ; GISEL-NEXT: and w10, w1, #0xffff
1932 ; GISEL-NEXT: mov w8, #10 // =0xa
1933 ; GISEL-NEXT: mul w9, w9, w10
1934 ; GISEL-NEXT: cmp w9, w9, uxth
1935 ; GISEL-NEXT: csel w0, w9, w8, ne
1938 %m = call { i16, i1 } @llvm.umul.with.overflow.i16(i16 %a, i16 %b)
1939 %m1 = extractvalue { i16, i1 } %m, 0
1940 %m2 = extractvalue { i16, i1 } %m, 1
1941 %r = select i1 %m2, i16 %m1, i16 10
1945 define i16 @smulo.selectboth.i16(i16 %a, i16 %b) {
1946 ; SDAG-LABEL: smulo.selectboth.i16:
1947 ; SDAG: // %bb.0: // %entry
1948 ; SDAG-NEXT: sxth w9, w1
1949 ; SDAG-NEXT: sxth w10, w0
1950 ; SDAG-NEXT: mov w8, #10 // =0xa
1951 ; SDAG-NEXT: mul w9, w10, w9
1952 ; SDAG-NEXT: cmp w9, w9, sxth
1953 ; SDAG-NEXT: csel w0, w9, w8, ne
1956 ; FAST-LABEL: smulo.selectboth.i16:
1957 ; FAST: // %bb.0: // %entry
1958 ; FAST-NEXT: sxth w9, w1
1959 ; FAST-NEXT: sxth w10, w0
1960 ; FAST-NEXT: mov w8, #10 // =0xa
1961 ; FAST-NEXT: mul w9, w10, w9
1962 ; FAST-NEXT: cmp w9, w9, sxth
1963 ; FAST-NEXT: csel w0, w9, w8, ne
1966 ; GISEL-LABEL: smulo.selectboth.i16:
1967 ; GISEL: // %bb.0: // %entry
1968 ; GISEL-NEXT: sxth w9, w0
1969 ; GISEL-NEXT: sxth w10, w1
1970 ; GISEL-NEXT: mov w8, #10 // =0xa
1971 ; GISEL-NEXT: mul w9, w9, w10
1972 ; GISEL-NEXT: cmp w9, w9, sxth
1973 ; GISEL-NEXT: csel w0, w9, w8, ne
1976 %m = call { i16, i1 } @llvm.smul.with.overflow.i16(i16 %a, i16 %b)
1977 %m1 = extractvalue { i16, i1 } %m, 0
1978 %m2 = extractvalue { i16, i1 } %m, 1
1979 %r = select i1 %m2, i16 %m1, i16 10
1983 define i32 @umulo.selectboth.i32(i32 %a, i32 %b) {
1984 ; SDAG-LABEL: umulo.selectboth.i32:
1985 ; SDAG: // %bb.0: // %entry
1986 ; SDAG-NEXT: umull x9, w0, w1
1987 ; SDAG-NEXT: mov w8, #10 // =0xa
1988 ; SDAG-NEXT: tst x9, #0xffffffff00000000
1989 ; SDAG-NEXT: csel w0, w9, w8, ne
1992 ; FAST-LABEL: umulo.selectboth.i32:
1993 ; FAST: // %bb.0: // %entry
1994 ; FAST-NEXT: umull x9, w0, w1
1995 ; FAST-NEXT: mov w8, #10 // =0xa
1996 ; FAST-NEXT: tst x9, #0xffffffff00000000
1997 ; FAST-NEXT: csel w0, w9, w8, ne
2000 ; GISEL-LABEL: umulo.selectboth.i32:
2001 ; GISEL: // %bb.0: // %entry
2002 ; GISEL-NEXT: umull x9, w0, w1
2003 ; GISEL-NEXT: mov w8, #10 // =0xa
2004 ; GISEL-NEXT: mul w10, w0, w1
2005 ; GISEL-NEXT: lsr x9, x9, #32
2006 ; GISEL-NEXT: cmp w9, #0
2007 ; GISEL-NEXT: csel w0, w10, w8, ne
2010 %m = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %a, i32 %b)
2011 %m1 = extractvalue { i32, i1 } %m, 0
2012 %m2 = extractvalue { i32, i1 } %m, 1
2013 %r = select i1 %m2, i32 %m1, i32 10
2017 define i32 @smulo.selectboth.i32(i32 %a, i32 %b) {
2018 ; SDAG-LABEL: smulo.selectboth.i32:
2019 ; SDAG: // %bb.0: // %entry
2020 ; SDAG-NEXT: smull x9, w0, w1
2021 ; SDAG-NEXT: mov w8, #10 // =0xa
2022 ; SDAG-NEXT: cmp x9, w9, sxtw
2023 ; SDAG-NEXT: csel w0, w9, w8, ne
2026 ; FAST-LABEL: smulo.selectboth.i32:
2027 ; FAST: // %bb.0: // %entry
2028 ; FAST-NEXT: smull x9, w0, w1
2029 ; FAST-NEXT: mov w8, #10 // =0xa
2030 ; FAST-NEXT: cmp x9, w9, sxtw
2031 ; FAST-NEXT: csel w0, w9, w8, ne
2034 ; GISEL-LABEL: smulo.selectboth.i32:
2035 ; GISEL: // %bb.0: // %entry
2036 ; GISEL-NEXT: smull x9, w0, w1
2037 ; GISEL-NEXT: mov w8, #10 // =0xa
2038 ; GISEL-NEXT: mul w10, w0, w1
2039 ; GISEL-NEXT: asr x9, x9, #32
2040 ; GISEL-NEXT: cmp w9, w10, asr #31
2041 ; GISEL-NEXT: csel w0, w10, w8, ne
2044 %m = call { i32, i1 } @llvm.smul.with.overflow.i32(i32 %a, i32 %b)
2045 %m1 = extractvalue { i32, i1 } %m, 0
2046 %m2 = extractvalue { i32, i1 } %m, 1
2047 %r = select i1 %m2, i32 %m1, i32 10
2051 define i64 @umulo.selectboth.i64(i64 %a, i64 %b) {
2052 ; SDAG-LABEL: umulo.selectboth.i64:
2053 ; SDAG: // %bb.0: // %entry
2054 ; SDAG-NEXT: umulh x9, x0, x1
2055 ; SDAG-NEXT: mov w8, #10 // =0xa
2056 ; SDAG-NEXT: mul x10, x0, x1
2057 ; SDAG-NEXT: cmp xzr, x9
2058 ; SDAG-NEXT: csel x0, x10, x8, ne
2061 ; FAST-LABEL: umulo.selectboth.i64:
2062 ; FAST: // %bb.0: // %entry
2063 ; FAST-NEXT: umulh x9, x0, x1
2064 ; FAST-NEXT: mov x8, #10 // =0xa
2065 ; FAST-NEXT: mul x10, x0, x1
2066 ; FAST-NEXT: cmp xzr, x9
2067 ; FAST-NEXT: csel x0, x10, x8, ne
2070 ; GISEL-LABEL: umulo.selectboth.i64:
2071 ; GISEL: // %bb.0: // %entry
2072 ; GISEL-NEXT: umulh x9, x0, x1
2073 ; GISEL-NEXT: mov w8, #10 // =0xa
2074 ; GISEL-NEXT: mul x10, x0, x1
2075 ; GISEL-NEXT: cmp x9, #0
2076 ; GISEL-NEXT: csel x0, x10, x8, ne
2079 %m = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 %a, i64 %b)
2080 %m1 = extractvalue { i64, i1 } %m, 0
2081 %m2 = extractvalue { i64, i1 } %m, 1
2082 %r = select i1 %m2, i64 %m1, i64 10
2086 define i64 @smulo.selectboth.i64(i64 %a, i64 %b) {
2087 ; SDAG-LABEL: smulo.selectboth.i64:
2088 ; SDAG: // %bb.0: // %entry
2089 ; SDAG-NEXT: mul x9, x0, x1
2090 ; SDAG-NEXT: mov w8, #10 // =0xa
2091 ; SDAG-NEXT: smulh x10, x0, x1
2092 ; SDAG-NEXT: cmp x10, x9, asr #63
2093 ; SDAG-NEXT: csel x0, x9, x8, ne
2096 ; FAST-LABEL: smulo.selectboth.i64:
2097 ; FAST: // %bb.0: // %entry
2098 ; FAST-NEXT: mul x9, x0, x1
2099 ; FAST-NEXT: mov x8, #10 // =0xa
2100 ; FAST-NEXT: smulh x10, x0, x1
2101 ; FAST-NEXT: cmp x10, x9, asr #63
2102 ; FAST-NEXT: csel x0, x9, x8, ne
2105 ; GISEL-LABEL: smulo.selectboth.i64:
2106 ; GISEL: // %bb.0: // %entry
2107 ; GISEL-NEXT: smulh x9, x0, x1
2108 ; GISEL-NEXT: mov w8, #10 // =0xa
2109 ; GISEL-NEXT: mul x10, x0, x1
2110 ; GISEL-NEXT: cmp x9, x10, asr #63
2111 ; GISEL-NEXT: csel x0, x10, x8, ne
2114 %m = call { i64, i1 } @llvm.smul.with.overflow.i64(i64 %a, i64 %b)
2115 %m1 = extractvalue { i64, i1 } %m, 0
2116 %m2 = extractvalue { i64, i1 } %m, 1
2117 %r = select i1 %m2, i64 %m1, i64 10
2123 ; Check the use of the overflow bit in combination with a branch instruction.
2125 define zeroext i1 @saddo.br.i32(i32 %v1, i32 %v2) {
2126 ; SDAG-LABEL: saddo.br.i32:
2127 ; SDAG: // %bb.0: // %entry
2128 ; SDAG-NEXT: cmn w0, w1
2129 ; SDAG-NEXT: cset w0, vc
2132 ; FAST-LABEL: saddo.br.i32:
2133 ; FAST: // %bb.0: // %entry
2134 ; FAST-NEXT: cmn w0, w1
2135 ; FAST-NEXT: mov w8, #1 // =0x1
2136 ; FAST-NEXT: cset w9, vs
2137 ; FAST-NEXT: bic w8, w8, w9
2138 ; FAST-NEXT: and w0, w8, #0x1
2141 ; GISEL-LABEL: saddo.br.i32:
2142 ; GISEL: // %bb.0: // %entry
2143 ; GISEL-NEXT: cmn w0, w1
2144 ; GISEL-NEXT: cset w8, vs
2145 ; GISEL-NEXT: eor w0, w8, #0x1
2148 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2)
2149 %val = extractvalue {i32, i1} %t, 0
2150 %obit = extractvalue {i32, i1} %t, 1
2151 br i1 %obit, label %overflow, label %continue
2160 define zeroext i1 @saddo.br.i64(i64 %v1, i64 %v2) {
2161 ; SDAG-LABEL: saddo.br.i64:
2162 ; SDAG: // %bb.0: // %entry
2163 ; SDAG-NEXT: cmn x0, x1
2164 ; SDAG-NEXT: cset w0, vc
2167 ; FAST-LABEL: saddo.br.i64:
2168 ; FAST: // %bb.0: // %entry
2169 ; FAST-NEXT: cmn x0, x1
2170 ; FAST-NEXT: mov w8, #1 // =0x1
2171 ; FAST-NEXT: cset w9, vs
2172 ; FAST-NEXT: bic w8, w8, w9
2173 ; FAST-NEXT: and w0, w8, #0x1
2176 ; GISEL-LABEL: saddo.br.i64:
2177 ; GISEL: // %bb.0: // %entry
2178 ; GISEL-NEXT: cmn x0, x1
2179 ; GISEL-NEXT: cset w8, vs
2180 ; GISEL-NEXT: eor w0, w8, #0x1
2183 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2)
2184 %val = extractvalue {i64, i1} %t, 0
2185 %obit = extractvalue {i64, i1} %t, 1
2186 br i1 %obit, label %overflow, label %continue
2195 define zeroext i1 @uaddo.br.i32(i32 %v1, i32 %v2) {
2196 ; SDAG-LABEL: uaddo.br.i32:
2197 ; SDAG: // %bb.0: // %entry
2198 ; SDAG-NEXT: cmn w0, w1
2199 ; SDAG-NEXT: cset w0, lo
2202 ; FAST-LABEL: uaddo.br.i32:
2203 ; FAST: // %bb.0: // %entry
2204 ; FAST-NEXT: cmn w0, w1
2205 ; FAST-NEXT: mov w8, #1 // =0x1
2206 ; FAST-NEXT: cset w9, hs
2207 ; FAST-NEXT: bic w8, w8, w9
2208 ; FAST-NEXT: and w0, w8, #0x1
2211 ; GISEL-LABEL: uaddo.br.i32:
2212 ; GISEL: // %bb.0: // %entry
2213 ; GISEL-NEXT: cmn w0, w1
2214 ; GISEL-NEXT: cset w8, hs
2215 ; GISEL-NEXT: eor w0, w8, #0x1
2218 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)
2219 %val = extractvalue {i32, i1} %t, 0
2220 %obit = extractvalue {i32, i1} %t, 1
2221 br i1 %obit, label %overflow, label %continue
2230 define zeroext i1 @uaddo.br.i64(i64 %v1, i64 %v2) {
2231 ; SDAG-LABEL: uaddo.br.i64:
2232 ; SDAG: // %bb.0: // %entry
2233 ; SDAG-NEXT: cmn x0, x1
2234 ; SDAG-NEXT: cset w0, lo
2237 ; FAST-LABEL: uaddo.br.i64:
2238 ; FAST: // %bb.0: // %entry
2239 ; FAST-NEXT: cmn x0, x1
2240 ; FAST-NEXT: mov w8, #1 // =0x1
2241 ; FAST-NEXT: cset w9, hs
2242 ; FAST-NEXT: bic w8, w8, w9
2243 ; FAST-NEXT: and w0, w8, #0x1
2246 ; GISEL-LABEL: uaddo.br.i64:
2247 ; GISEL: // %bb.0: // %entry
2248 ; GISEL-NEXT: cmn x0, x1
2249 ; GISEL-NEXT: cset w8, hs
2250 ; GISEL-NEXT: eor w0, w8, #0x1
2253 %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2)
2254 %val = extractvalue {i64, i1} %t, 0
2255 %obit = extractvalue {i64, i1} %t, 1
2256 br i1 %obit, label %overflow, label %continue
2265 define zeroext i1 @ssubo.br.i32(i32 %v1, i32 %v2) {
2266 ; SDAG-LABEL: ssubo.br.i32:
2267 ; SDAG: // %bb.0: // %entry
2268 ; SDAG-NEXT: cmp w0, w1
2269 ; SDAG-NEXT: cset w0, vc
2272 ; FAST-LABEL: ssubo.br.i32:
2273 ; FAST: // %bb.0: // %entry
2274 ; FAST-NEXT: cmp w0, w1
2275 ; FAST-NEXT: mov w8, #1 // =0x1
2276 ; FAST-NEXT: cset w9, vs
2277 ; FAST-NEXT: bic w8, w8, w9
2278 ; FAST-NEXT: and w0, w8, #0x1
2281 ; GISEL-LABEL: ssubo.br.i32:
2282 ; GISEL: // %bb.0: // %entry
2283 ; GISEL-NEXT: cmp w0, w1
2284 ; GISEL-NEXT: cset w8, vs
2285 ; GISEL-NEXT: eor w0, w8, #0x1
2288 %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2)
2289 %val = extractvalue {i32, i1} %t, 0
2290 %obit = extractvalue {i32, i1} %t, 1
2291 br i1 %obit, label %overflow, label %continue
2300 define zeroext i1 @ssubo.br.i64(i64 %v1, i64 %v2) {
2301 ; SDAG-LABEL: ssubo.br.i64:
2302 ; SDAG: // %bb.0: // %entry
2303 ; SDAG-NEXT: cmp x0, x1
2304 ; SDAG-NEXT: cset w0, vc
2307 ; FAST-LABEL: ssubo.br.i64:
2308 ; FAST: // %bb.0: // %entry
2309 ; FAST-NEXT: cmp x0, x1
2310 ; FAST-NEXT: mov w8, #1 // =0x1
2311 ; FAST-NEXT: cset w9, vs
2312 ; FAST-NEXT: bic w8, w8, w9
2313 ; FAST-NEXT: and w0, w8, #0x1
2316 ; GISEL-LABEL: ssubo.br.i64:
2317 ; GISEL: // %bb.0: // %entry
2318 ; GISEL-NEXT: cmp x0, x1
2319 ; GISEL-NEXT: cset w8, vs
2320 ; GISEL-NEXT: eor w0, w8, #0x1
2323 %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2)
2324 %val = extractvalue {i64, i1} %t, 0
2325 %obit = extractvalue {i64, i1} %t, 1
2326 br i1 %obit, label %overflow, label %continue
2335 define zeroext i1 @usubo.br.i32(i32 %v1, i32 %v2) {
2336 ; SDAG-LABEL: usubo.br.i32:
2337 ; SDAG: // %bb.0: // %entry
2338 ; SDAG-NEXT: cmp w0, w1
2339 ; SDAG-NEXT: cset w0, hs
2342 ; FAST-LABEL: usubo.br.i32:
2343 ; FAST: // %bb.0: // %entry
2344 ; FAST-NEXT: cmp w0, w1
2345 ; FAST-NEXT: mov w8, #1 // =0x1
2346 ; FAST-NEXT: cset w9, lo
2347 ; FAST-NEXT: bic w8, w8, w9
2348 ; FAST-NEXT: and w0, w8, #0x1
2351 ; GISEL-LABEL: usubo.br.i32:
2352 ; GISEL: // %bb.0: // %entry
2353 ; GISEL-NEXT: cmp w0, w1
2354 ; GISEL-NEXT: cset w8, lo
2355 ; GISEL-NEXT: eor w0, w8, #0x1
2358 %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2)
2359 %val = extractvalue {i32, i1} %t, 0
2360 %obit = extractvalue {i32, i1} %t, 1
2361 br i1 %obit, label %overflow, label %continue
2370 define zeroext i1 @usubo.br.i64(i64 %v1, i64 %v2) {
2371 ; SDAG-LABEL: usubo.br.i64:
2372 ; SDAG: // %bb.0: // %entry
2373 ; SDAG-NEXT: cmp x0, x1
2374 ; SDAG-NEXT: cset w0, hs
2377 ; FAST-LABEL: usubo.br.i64:
2378 ; FAST: // %bb.0: // %entry
2379 ; FAST-NEXT: cmp x0, x1
2380 ; FAST-NEXT: mov w8, #1 // =0x1
2381 ; FAST-NEXT: cset w9, lo
2382 ; FAST-NEXT: bic w8, w8, w9
2383 ; FAST-NEXT: and w0, w8, #0x1
2386 ; GISEL-LABEL: usubo.br.i64:
2387 ; GISEL: // %bb.0: // %entry
2388 ; GISEL-NEXT: cmp x0, x1
2389 ; GISEL-NEXT: cset w8, lo
2390 ; GISEL-NEXT: eor w0, w8, #0x1
2393 %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2)
2394 %val = extractvalue {i64, i1} %t, 0
2395 %obit = extractvalue {i64, i1} %t, 1
2396 br i1 %obit, label %overflow, label %continue
2405 define zeroext i1 @smulo.br.i32(i32 %v1, i32 %v2) {
2406 ; SDAG-LABEL: smulo.br.i32:
2407 ; SDAG: // %bb.0: // %entry
2408 ; SDAG-NEXT: smull x8, w0, w1
2409 ; SDAG-NEXT: cmp x8, w8, sxtw
2410 ; SDAG-NEXT: cset w0, eq
2413 ; FAST-LABEL: smulo.br.i32:
2414 ; FAST: // %bb.0: // %entry
2415 ; FAST-NEXT: smull x9, w0, w1
2416 ; FAST-NEXT: mov w8, #1 // =0x1
2417 ; FAST-NEXT: cmp x9, w9, sxtw
2418 ; FAST-NEXT: cset w9, ne
2419 ; FAST-NEXT: bic w8, w8, w9
2420 ; FAST-NEXT: and w0, w8, #0x1
2423 ; GISEL-LABEL: smulo.br.i32:
2424 ; GISEL: // %bb.0: // %entry
2425 ; GISEL-NEXT: smull x8, w0, w1
2426 ; GISEL-NEXT: mul w9, w0, w1
2427 ; GISEL-NEXT: asr x8, x8, #32
2428 ; GISEL-NEXT: cmp w8, w9, asr #31
2429 ; GISEL-NEXT: cset w8, ne
2430 ; GISEL-NEXT: eor w0, w8, #0x1
2433 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
2434 %val = extractvalue {i32, i1} %t, 0
2435 %obit = extractvalue {i32, i1} %t, 1
2436 br i1 %obit, label %overflow, label %continue
2445 define zeroext i1 @smulo.br.i64(i64 %v1, i64 %v2) {
2446 ; SDAG-LABEL: smulo.br.i64:
2447 ; SDAG: // %bb.0: // %entry
2448 ; SDAG-NEXT: mul x8, x0, x1
2449 ; SDAG-NEXT: smulh x9, x0, x1
2450 ; SDAG-NEXT: cmp x9, x8, asr #63
2451 ; SDAG-NEXT: cset w0, eq
2454 ; FAST-LABEL: smulo.br.i64:
2455 ; FAST: // %bb.0: // %entry
2456 ; FAST-NEXT: mul x9, x0, x1
2457 ; FAST-NEXT: mov w8, #1 // =0x1
2458 ; FAST-NEXT: smulh x10, x0, x1
2459 ; FAST-NEXT: cmp x10, x9, asr #63
2460 ; FAST-NEXT: cset w9, ne
2461 ; FAST-NEXT: bic w8, w8, w9
2462 ; FAST-NEXT: and w0, w8, #0x1
2465 ; GISEL-LABEL: smulo.br.i64:
2466 ; GISEL: // %bb.0: // %entry
2467 ; GISEL-NEXT: smulh x8, x0, x1
2468 ; GISEL-NEXT: mul x9, x0, x1
2469 ; GISEL-NEXT: cmp x8, x9, asr #63
2470 ; GISEL-NEXT: cset w8, ne
2471 ; GISEL-NEXT: eor w0, w8, #0x1
2474 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
2475 %val = extractvalue {i64, i1} %t, 0
2476 %obit = extractvalue {i64, i1} %t, 1
2477 br i1 %obit, label %overflow, label %continue
2486 define zeroext i1 @smulo2.br.i64(i64 %v1) {
2487 ; SDAG-LABEL: smulo2.br.i64:
2488 ; SDAG: // %bb.0: // %entry
2489 ; SDAG-NEXT: cmn x0, x0
2490 ; SDAG-NEXT: cset w0, vc
2493 ; FAST-LABEL: smulo2.br.i64:
2494 ; FAST: // %bb.0: // %entry
2495 ; FAST-NEXT: cmn x0, x0
2496 ; FAST-NEXT: mov w8, #1 // =0x1
2497 ; FAST-NEXT: cset w9, vs
2498 ; FAST-NEXT: bic w8, w8, w9
2499 ; FAST-NEXT: and w0, w8, #0x1
2502 ; GISEL-LABEL: smulo2.br.i64:
2503 ; GISEL: // %bb.0: // %entry
2504 ; GISEL-NEXT: cmn x0, x0
2505 ; GISEL-NEXT: cset w8, vs
2506 ; GISEL-NEXT: eor w0, w8, #0x1
2509 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 2)
2510 %val = extractvalue {i64, i1} %t, 0
2511 %obit = extractvalue {i64, i1} %t, 1
2512 br i1 %obit, label %overflow, label %continue
2521 define zeroext i1 @umulo.br.i32(i32 %v1, i32 %v2) {
2522 ; SDAG-LABEL: umulo.br.i32:
2523 ; SDAG: // %bb.0: // %entry
2524 ; SDAG-NEXT: umull x8, w0, w1
2525 ; SDAG-NEXT: tst x8, #0xffffffff00000000
2526 ; SDAG-NEXT: cset w0, eq
2529 ; FAST-LABEL: umulo.br.i32:
2530 ; FAST: // %bb.0: // %entry
2531 ; FAST-NEXT: umull x9, w0, w1
2532 ; FAST-NEXT: mov w8, #1 // =0x1
2533 ; FAST-NEXT: tst x9, #0xffffffff00000000
2534 ; FAST-NEXT: cset w9, ne
2535 ; FAST-NEXT: bic w8, w8, w9
2536 ; FAST-NEXT: and w0, w8, #0x1
2539 ; GISEL-LABEL: umulo.br.i32:
2540 ; GISEL: // %bb.0: // %entry
2541 ; GISEL-NEXT: umull x8, w0, w1
2542 ; GISEL-NEXT: lsr x8, x8, #32
2543 ; GISEL-NEXT: cmp w8, #0
2544 ; GISEL-NEXT: cset w8, ne
2545 ; GISEL-NEXT: eor w0, w8, #0x1
2548 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
2549 %val = extractvalue {i32, i1} %t, 0
2550 %obit = extractvalue {i32, i1} %t, 1
2551 br i1 %obit, label %overflow, label %continue
2560 define zeroext i1 @umulo.br.i64(i64 %v1, i64 %v2) {
2561 ; SDAG-LABEL: umulo.br.i64:
2562 ; SDAG: // %bb.0: // %entry
2563 ; SDAG-NEXT: umulh x8, x0, x1
2564 ; SDAG-NEXT: cmp xzr, x8
2565 ; SDAG-NEXT: cset w0, eq
2568 ; FAST-LABEL: umulo.br.i64:
2569 ; FAST: // %bb.0: // %entry
2570 ; FAST-NEXT: umulh x9, x0, x1
2571 ; FAST-NEXT: mov w8, #1 // =0x1
2572 ; FAST-NEXT: cmp xzr, x9
2573 ; FAST-NEXT: cset w9, ne
2574 ; FAST-NEXT: bic w8, w8, w9
2575 ; FAST-NEXT: and w0, w8, #0x1
2578 ; GISEL-LABEL: umulo.br.i64:
2579 ; GISEL: // %bb.0: // %entry
2580 ; GISEL-NEXT: umulh x8, x0, x1
2581 ; GISEL-NEXT: cmp x8, #0
2582 ; GISEL-NEXT: cset w8, ne
2583 ; GISEL-NEXT: eor w0, w8, #0x1
2586 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
2587 %val = extractvalue {i64, i1} %t, 0
2588 %obit = extractvalue {i64, i1} %t, 1
2589 br i1 %obit, label %overflow, label %continue
2598 define zeroext i1 @umulo2.br.i64(i64 %v1) {
2599 ; SDAG-LABEL: umulo2.br.i64:
2600 ; SDAG: // %bb.0: // %entry
2601 ; SDAG-NEXT: cmn x0, x0
2602 ; SDAG-NEXT: cset w0, lo
2605 ; FAST-LABEL: umulo2.br.i64:
2606 ; FAST: // %bb.0: // %entry
2607 ; FAST-NEXT: cmn x0, x0
2608 ; FAST-NEXT: mov w8, #1 // =0x1
2609 ; FAST-NEXT: cset w9, hs
2610 ; FAST-NEXT: bic w8, w8, w9
2611 ; FAST-NEXT: and w0, w8, #0x1
2614 ; GISEL-LABEL: umulo2.br.i64:
2615 ; GISEL: // %bb.0: // %entry
2616 ; GISEL-NEXT: cmn x0, x0
2617 ; GISEL-NEXT: cset w8, hs
2618 ; GISEL-NEXT: eor w0, w8, #0x1
2621 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 2)
2622 %val = extractvalue {i64, i1} %t, 0
2623 %obit = extractvalue {i64, i1} %t, 1
2624 br i1 %obit, label %overflow, label %continue
2633 define i8 @pr60530() {
2634 ; SDAG-LABEL: pr60530:
2636 ; SDAG-NEXT: mov w0, #-1 // =0xffffffff
2639 ; FAST-LABEL: pr60530:
2641 ; FAST-NEXT: mov w0, #-1 // =0xffffffff
2644 ; GISEL-LABEL: pr60530:
2646 ; GISEL-NEXT: mov w0, #255 // =0xff
2648 %1 = call { i8, i1 } @llvm.uadd.with.overflow.i8(i8 0, i8 1)
2649 %2 = extractvalue { i8, i1 } %1, 1
2650 %3 = zext i1 %2 to i8
2653 %6 = icmp uge i8 %5, 1
2654 %7 = sext i1 %6 to i8
2655 %8 = zext i1 %2 to i8
2656 %9 = icmp uge i8 %7, %8
2657 %10 = sext i1 %9 to i8
2661 declare {i8, i1} @llvm.sadd.with.overflow.i8(i8, i8) nounwind readnone
2662 declare {i16, i1} @llvm.sadd.with.overflow.i16(i16, i16) nounwind readnone
2663 declare {i32, i1} @llvm.sadd.with.overflow.i32(i32, i32) nounwind readnone
2664 declare {i64, i1} @llvm.sadd.with.overflow.i64(i64, i64) nounwind readnone
2665 declare {i8, i1} @llvm.uadd.with.overflow.i8(i8, i8) nounwind readnone
2666 declare {i16, i1} @llvm.uadd.with.overflow.i16(i16, i16) nounwind readnone
2667 declare {i32, i1} @llvm.uadd.with.overflow.i32(i32, i32) nounwind readnone
2668 declare {i64, i1} @llvm.uadd.with.overflow.i64(i64, i64) nounwind readnone
2669 declare {i8, i1} @llvm.ssub.with.overflow.i8(i8, i8) nounwind readnone
2670 declare {i16, i1} @llvm.ssub.with.overflow.i16(i16, i16) nounwind readnone
2671 declare {i32, i1} @llvm.ssub.with.overflow.i32(i32, i32) nounwind readnone
2672 declare {i64, i1} @llvm.ssub.with.overflow.i64(i64, i64) nounwind readnone
2673 declare {i8, i1} @llvm.usub.with.overflow.i8(i8, i8) nounwind readnone
2674 declare {i16, i1} @llvm.usub.with.overflow.i16(i16, i16) nounwind readnone
2675 declare {i32, i1} @llvm.usub.with.overflow.i32(i32, i32) nounwind readnone
2676 declare {i64, i1} @llvm.usub.with.overflow.i64(i64, i64) nounwind readnone
2677 declare {i8, i1} @llvm.smul.with.overflow.i8(i8, i8) nounwind readnone
2678 declare {i16, i1} @llvm.smul.with.overflow.i16(i16, i16) nounwind readnone
2679 declare {i32, i1} @llvm.smul.with.overflow.i32(i32, i32) nounwind readnone
2680 declare {i64, i1} @llvm.smul.with.overflow.i64(i64, i64) nounwind readnone
2681 declare {i8, i1} @llvm.umul.with.overflow.i8(i8, i8) nounwind readnone
2682 declare {i16, i1} @llvm.umul.with.overflow.i16(i16, i16) nounwind readnone
2683 declare {i32, i1} @llvm.umul.with.overflow.i32(i32, i32) nounwind readnone
2684 declare {i64, i1} @llvm.umul.with.overflow.i64(i64, i64) nounwind readnone