1 ; RUN: llc < %s -mtriple=arm64-eabi -aarch64-enable-atomic-cfg-tidy=0 -disable-post-ra -verify-machineinstrs | FileCheck %s
2 ; RUN: llc < %s -mtriple=arm64-eabi -aarch64-enable-atomic-cfg-tidy=0 -fast-isel -fast-isel-abort=1 -disable-post-ra -verify-machineinstrs | FileCheck %s
3 ; RUN: llc < %s -mtriple=arm64-eabi -aarch64-enable-atomic-cfg-tidy=0 -global-isel -global-isel-abort=2 -pass-remarks-missed=gisel* -disable-post-ra -verify-machineinstrs | FileCheck %s --check-prefixes=GISEL,FALLBACK
6 ; Get the actual value of the overflow bit.
8 define zeroext i1 @saddo1.i32(i32 %v1, i32 %v2, i32* %res) {
10 ; CHECK-LABEL: saddo1.i32
11 ; CHECK: adds {{w[0-9]+}}, w0, w1
12 ; CHECK-NEXT: cset {{w[0-9]+}}, vs
13 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2)
14 %val = extractvalue {i32, i1} %t, 0
15 %obit = extractvalue {i32, i1} %t, 1
16 store i32 %val, i32* %res
20 ; Test the immediate version.
21 define zeroext i1 @saddo2.i32(i32 %v1, i32* %res) {
23 ; CHECK-LABEL: saddo2.i32
24 ; CHECK: adds {{w[0-9]+}}, w0, #4
25 ; CHECK-NEXT: cset {{w[0-9]+}}, vs
26 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 4)
27 %val = extractvalue {i32, i1} %t, 0
28 %obit = extractvalue {i32, i1} %t, 1
29 store i32 %val, i32* %res
33 ; Test negative immediates.
34 define zeroext i1 @saddo3.i32(i32 %v1, i32* %res) {
36 ; CHECK-LABEL: saddo3.i32
37 ; CHECK: subs {{w[0-9]+}}, w0, #4
38 ; CHECK-NEXT: cset {{w[0-9]+}}, vs
39 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 -4)
40 %val = extractvalue {i32, i1} %t, 0
41 %obit = extractvalue {i32, i1} %t, 1
42 store i32 %val, i32* %res
46 ; Test immediates that are too large to be encoded.
47 define zeroext i1 @saddo4.i32(i32 %v1, i32* %res) {
49 ; CHECK-LABEL: saddo4.i32
50 ; CHECK: adds {{w[0-9]+}}, w0, {{w[0-9]+}}
51 ; CHECK-NEXT: cset {{w[0-9]+}}, vs
52 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 16777215)
53 %val = extractvalue {i32, i1} %t, 0
54 %obit = extractvalue {i32, i1} %t, 1
55 store i32 %val, i32* %res
60 define zeroext i1 @saddo5.i32(i32 %v1, i32 %v2, i32* %res) {
62 ; CHECK-LABEL: saddo5.i32
63 ; CHECK: adds {{w[0-9]+}}, w0, w1
64 ; CHECK-NEXT: cset {{w[0-9]+}}, vs
65 %lsl = shl i32 %v2, 16
66 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %lsl)
67 %val = extractvalue {i32, i1} %t, 0
68 %obit = extractvalue {i32, i1} %t, 1
69 store i32 %val, i32* %res
73 define zeroext i1 @saddo1.i64(i64 %v1, i64 %v2, i64* %res) {
75 ; CHECK-LABEL: saddo1.i64
76 ; CHECK: adds {{x[0-9]+}}, x0, x1
77 ; CHECK-NEXT: cset {{w[0-9]+}}, vs
78 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2)
79 %val = extractvalue {i64, i1} %t, 0
80 %obit = extractvalue {i64, i1} %t, 1
81 store i64 %val, i64* %res
85 define zeroext i1 @saddo2.i64(i64 %v1, i64* %res) {
87 ; CHECK-LABEL: saddo2.i64
88 ; CHECK: adds {{x[0-9]+}}, x0, #4
89 ; CHECK-NEXT: cset {{w[0-9]+}}, vs
90 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 4)
91 %val = extractvalue {i64, i1} %t, 0
92 %obit = extractvalue {i64, i1} %t, 1
93 store i64 %val, i64* %res
97 define zeroext i1 @saddo3.i64(i64 %v1, i64* %res) {
99 ; CHECK-LABEL: saddo3.i64
100 ; CHECK: subs {{x[0-9]+}}, x0, #4
101 ; CHECK-NEXT: cset {{w[0-9]+}}, vs
102 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 -4)
103 %val = extractvalue {i64, i1} %t, 0
104 %obit = extractvalue {i64, i1} %t, 1
105 store i64 %val, i64* %res
109 ; FALLBACK-NOT: remark{{.*}}uaddo.i32
110 define zeroext i1 @uaddo.i32(i32 %v1, i32 %v2, i32* %res) {
112 ; CHECK-LABEL: uaddo.i32
113 ; CHECK: adds {{w[0-9]+}}, w0, w1
114 ; CHECK-NEXT: cset {{w[0-9]+}}, hs
115 ; GISEL-LABEL: uaddo.i32
116 ; GISEL: adds {{w[0-9]+}}, w0, w1
117 ; GISEL-NEXT: cset {{w[0-9]+}}, hs
118 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)
119 %val = extractvalue {i32, i1} %t, 0
120 %obit = extractvalue {i32, i1} %t, 1
121 store i32 %val, i32* %res
125 ; FALLBACK-NOT: remark{{.*}}uaddo.i64
126 define zeroext i1 @uaddo.i64(i64 %v1, i64 %v2, i64* %res) {
128 ; CHECK-LABEL: uaddo.i64
129 ; CHECK: adds {{x[0-9]+}}, x0, x1
130 ; CHECK-NEXT: cset {{w[0-9]+}}, hs
131 ; GISEL-LABEL: uaddo.i64
132 ; GISEL: adds {{x[0-9]+}}, x0, x1
133 ; GISEL-NEXT: cset {{w[0-9]+}}, hs
134 %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2)
135 %val = extractvalue {i64, i1} %t, 0
136 %obit = extractvalue {i64, i1} %t, 1
137 store i64 %val, i64* %res
141 define zeroext i1 @ssubo1.i32(i32 %v1, i32 %v2, i32* %res) {
143 ; CHECK-LABEL: ssubo1.i32
144 ; CHECK: subs {{w[0-9]+}}, w0, w1
145 ; CHECK-NEXT: cset {{w[0-9]+}}, vs
146 %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2)
147 %val = extractvalue {i32, i1} %t, 0
148 %obit = extractvalue {i32, i1} %t, 1
149 store i32 %val, i32* %res
153 define zeroext i1 @ssubo2.i32(i32 %v1, i32* %res) {
155 ; CHECK-LABEL: ssubo2.i32
156 ; CHECK: adds {{w[0-9]+}}, w0, #4
157 ; CHECK-NEXT: cset {{w[0-9]+}}, vs
158 %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 -4)
159 %val = extractvalue {i32, i1} %t, 0
160 %obit = extractvalue {i32, i1} %t, 1
161 store i32 %val, i32* %res
165 define zeroext i1 @ssubo.i64(i64 %v1, i64 %v2, i64* %res) {
167 ; CHECK-LABEL: ssubo.i64
168 ; CHECK: subs {{x[0-9]+}}, x0, x1
169 ; CHECK-NEXT: cset {{w[0-9]+}}, vs
170 %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2)
171 %val = extractvalue {i64, i1} %t, 0
172 %obit = extractvalue {i64, i1} %t, 1
173 store i64 %val, i64* %res
177 define zeroext i1 @usubo.i32(i32 %v1, i32 %v2, i32* %res) {
179 ; CHECK-LABEL: usubo.i32
180 ; CHECK: subs {{w[0-9]+}}, w0, w1
181 ; CHECK-NEXT: cset {{w[0-9]+}}, lo
182 %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2)
183 %val = extractvalue {i32, i1} %t, 0
184 %obit = extractvalue {i32, i1} %t, 1
185 store i32 %val, i32* %res
189 define zeroext i1 @usubo.i64(i64 %v1, i64 %v2, i64* %res) {
191 ; CHECK-LABEL: usubo.i64
192 ; CHECK: subs {{x[0-9]+}}, x0, x1
193 ; CHECK-NEXT: cset {{w[0-9]+}}, lo
194 %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2)
195 %val = extractvalue {i64, i1} %t, 0
196 %obit = extractvalue {i64, i1} %t, 1
197 store i64 %val, i64* %res
201 define zeroext i1 @smulo.i32(i32 %v1, i32 %v2, i32* %res) {
203 ; CHECK-LABEL: smulo.i32
204 ; CHECK: smull x[[MREG:[0-9]+]], w0, w1
205 ; CHECK-NEXT: cmp x[[MREG]], w[[MREG]], sxtw
206 ; CHECK-NEXT: cset {{w[0-9]+}}, ne
207 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
208 %val = extractvalue {i32, i1} %t, 0
209 %obit = extractvalue {i32, i1} %t, 1
210 store i32 %val, i32* %res
214 define zeroext i1 @smulo.i64(i64 %v1, i64 %v2, i64* %res) {
216 ; CHECK-LABEL: smulo.i64
217 ; CHECK: mul [[MREG:x[0-9]+]], x0, x1
218 ; CHECK-NEXT: smulh [[HREG:x[0-9]+]], x0, x1
219 ; CHECK-NEXT: cmp [[HREG]], [[MREG]], asr #63
220 ; CHECK-NEXT: cset {{w[0-9]+}}, ne
221 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
222 %val = extractvalue {i64, i1} %t, 0
223 %obit = extractvalue {i64, i1} %t, 1
224 store i64 %val, i64* %res
228 define zeroext i1 @smulo2.i64(i64 %v1, i64* %res) {
230 ; CHECK-LABEL: smulo2.i64
231 ; CHECK: adds [[MREG:x[0-9]+]], x0, x0
232 ; CHECK-NEXT: cset {{w[0-9]+}}, vs
233 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 2)
234 %val = extractvalue {i64, i1} %t, 0
235 %obit = extractvalue {i64, i1} %t, 1
236 store i64 %val, i64* %res
240 define zeroext i1 @umulo.i32(i32 %v1, i32 %v2, i32* %res) {
242 ; CHECK-LABEL: umulo.i32
243 ; CHECK: umull [[MREG:x[0-9]+]], w0, w1
244 ; CHECK-NEXT: tst [[MREG]], #0xffffffff00000000
245 ; CHECK-NEXT: cset {{w[0-9]+}}, ne
246 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
247 %val = extractvalue {i32, i1} %t, 0
248 %obit = extractvalue {i32, i1} %t, 1
249 store i32 %val, i32* %res
253 define zeroext i1 @umulo.i64(i64 %v1, i64 %v2, i64* %res) {
255 ; CHECK-LABEL: umulo.i64
256 ; CHECK: umulh [[MREG:x[0-9]+]], x0, x1
257 ; CHECK-NEXT: cmp xzr, [[MREG]]
258 ; CHECK-NEXT: cset {{w[0-9]+}}, ne
259 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
260 %val = extractvalue {i64, i1} %t, 0
261 %obit = extractvalue {i64, i1} %t, 1
262 store i64 %val, i64* %res
266 define zeroext i1 @umulo2.i64(i64 %v1, i64* %res) {
268 ; CHECK-LABEL: umulo2.i64
269 ; CHECK: adds [[MREG:x[0-9]+]], x0, x0
270 ; CHECK-NEXT: cset {{w[0-9]+}}, hs
271 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 2)
272 %val = extractvalue {i64, i1} %t, 0
273 %obit = extractvalue {i64, i1} %t, 1
274 store i64 %val, i64* %res
280 ; Check the use of the overflow bit in combination with a select instruction.
282 define i32 @saddo.select.i32(i32 %v1, i32 %v2) {
284 ; CHECK-LABEL: saddo.select.i32
286 ; CHECK-NEXT: csel w0, w0, w1, vs
287 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2)
288 %obit = extractvalue {i32, i1} %t, 1
289 %ret = select i1 %obit, i32 %v1, i32 %v2
293 define i1 @saddo.not.i32(i32 %v1, i32 %v2) {
295 ; CHECK-LABEL: saddo.not.i32
297 ; CHECK-NEXT: cset w0, vc
298 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2)
299 %obit = extractvalue {i32, i1} %t, 1
300 %ret = xor i1 %obit, true
304 define i64 @saddo.select.i64(i64 %v1, i64 %v2) {
306 ; CHECK-LABEL: saddo.select.i64
308 ; CHECK-NEXT: csel x0, x0, x1, vs
309 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2)
310 %obit = extractvalue {i64, i1} %t, 1
311 %ret = select i1 %obit, i64 %v1, i64 %v2
315 define i1 @saddo.not.i64(i64 %v1, i64 %v2) {
317 ; CHECK-LABEL: saddo.not.i64
319 ; CHECK-NEXT: cset w0, vc
320 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2)
321 %obit = extractvalue {i64, i1} %t, 1
322 %ret = xor i1 %obit, true
326 define i32 @uaddo.select.i32(i32 %v1, i32 %v2) {
328 ; CHECK-LABEL: uaddo.select.i32
330 ; CHECK-NEXT: csel w0, w0, w1, hs
331 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)
332 %obit = extractvalue {i32, i1} %t, 1
333 %ret = select i1 %obit, i32 %v1, i32 %v2
337 define i1 @uaddo.not.i32(i32 %v1, i32 %v2) {
339 ; CHECK-LABEL: uaddo.not.i32
341 ; CHECK-NEXT: cset w0, lo
342 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)
343 %obit = extractvalue {i32, i1} %t, 1
344 %ret = xor i1 %obit, true
348 define i64 @uaddo.select.i64(i64 %v1, i64 %v2) {
350 ; CHECK-LABEL: uaddo.select.i64
352 ; CHECK-NEXT: csel x0, x0, x1, hs
353 %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2)
354 %obit = extractvalue {i64, i1} %t, 1
355 %ret = select i1 %obit, i64 %v1, i64 %v2
359 define i1 @uaddo.not.i64(i64 %v1, i64 %v2) {
361 ; CHECK-LABEL: uaddo.not.i64
363 ; CHECK-NEXT: cset w0, lo
364 %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2)
365 %obit = extractvalue {i64, i1} %t, 1
366 %ret = xor i1 %obit, true
370 define i32 @ssubo.select.i32(i32 %v1, i32 %v2) {
372 ; CHECK-LABEL: ssubo.select.i32
374 ; CHECK-NEXT: csel w0, w0, w1, vs
375 %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2)
376 %obit = extractvalue {i32, i1} %t, 1
377 %ret = select i1 %obit, i32 %v1, i32 %v2
381 define i1 @ssubo.not.i32(i32 %v1, i32 %v2) {
383 ; CHECK-LABEL: ssubo.not.i32
385 ; CHECK-NEXT: cset w0, vc
386 %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2)
387 %obit = extractvalue {i32, i1} %t, 1
388 %ret = xor i1 %obit, true
392 define i64 @ssubo.select.i64(i64 %v1, i64 %v2) {
394 ; CHECK-LABEL: ssubo.select.i64
396 ; CHECK-NEXT: csel x0, x0, x1, vs
397 %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2)
398 %obit = extractvalue {i64, i1} %t, 1
399 %ret = select i1 %obit, i64 %v1, i64 %v2
403 define i1 @ssub.not.i64(i64 %v1, i64 %v2) {
405 ; CHECK-LABEL: ssub.not.i64
407 ; CHECK-NEXT: cset w0, vc
408 %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2)
409 %obit = extractvalue {i64, i1} %t, 1
410 %ret = xor i1 %obit, true
414 define i32 @usubo.select.i32(i32 %v1, i32 %v2) {
416 ; CHECK-LABEL: usubo.select.i32
418 ; CHECK-NEXT: csel w0, w0, w1, lo
419 %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2)
420 %obit = extractvalue {i32, i1} %t, 1
421 %ret = select i1 %obit, i32 %v1, i32 %v2
425 define i1 @usubo.not.i32(i32 %v1, i32 %v2) {
427 ; CHECK-LABEL: usubo.not.i32
429 ; CHECK-NEXT: cset w0, hs
430 %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2)
431 %obit = extractvalue {i32, i1} %t, 1
432 %ret = xor i1 %obit, true
436 define i64 @usubo.select.i64(i64 %v1, i64 %v2) {
438 ; CHECK-LABEL: usubo.select.i64
440 ; CHECK-NEXT: csel x0, x0, x1, lo
441 %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2)
442 %obit = extractvalue {i64, i1} %t, 1
443 %ret = select i1 %obit, i64 %v1, i64 %v2
447 define i1 @usubo.not.i64(i64 %v1, i64 %v2) {
449 ; CHECK-LABEL: usubo.not.i64
451 ; CHECK-NEXT: cset w0, hs
452 %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2)
453 %obit = extractvalue {i64, i1} %t, 1
454 %ret = xor i1 %obit, true
458 define i32 @smulo.select.i32(i32 %v1, i32 %v2) {
460 ; CHECK-LABEL: smulo.select.i32
461 ; CHECK: smull x[[MREG:[0-9]+]], w0, w1
462 ; CHECK-NEXT: cmp x[[MREG]], w[[MREG]], sxtw
463 ; CHECK-NEXT: csel w0, w0, w1, ne
464 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
465 %obit = extractvalue {i32, i1} %t, 1
466 %ret = select i1 %obit, i32 %v1, i32 %v2
470 define i1 @smulo.not.i32(i32 %v1, i32 %v2) {
472 ; CHECK-LABEL: smulo.not.i32
473 ; CHECK: smull x[[MREG:[0-9]+]], w0, w1
474 ; CHECK-NEXT: cmp x[[MREG]], w[[MREG]], sxtw
475 ; CHECK-NEXT: cset w0, eq
476 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
477 %obit = extractvalue {i32, i1} %t, 1
478 %ret = xor i1 %obit, true
482 define i64 @smulo.select.i64(i64 %v1, i64 %v2) {
484 ; CHECK-LABEL: smulo.select.i64
485 ; CHECK: mul [[MREG:x[0-9]+]], x0, x1
486 ; CHECK-NEXT: smulh [[HREG:x[0-9]+]], x0, x1
487 ; CHECK-NEXT: cmp [[HREG]], [[MREG]], asr #63
488 ; CHECK-NEXT: csel x0, x0, x1, ne
489 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
490 %obit = extractvalue {i64, i1} %t, 1
491 %ret = select i1 %obit, i64 %v1, i64 %v2
495 define i1 @smulo.not.i64(i64 %v1, i64 %v2) {
497 ; CHECK-LABEL: smulo.not.i64
498 ; CHECK: mul [[MREG:x[0-9]+]], x0, x1
499 ; CHECK-NEXT: smulh [[HREG:x[0-9]+]], x0, x1
500 ; CHECK-NEXT: cmp [[HREG]], [[MREG]], asr #63
501 ; CHECK-NEXT: cset w0, eq
502 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
503 %obit = extractvalue {i64, i1} %t, 1
504 %ret = xor i1 %obit, true
508 define i32 @umulo.select.i32(i32 %v1, i32 %v2) {
510 ; CHECK-LABEL: umulo.select.i32
511 ; CHECK: umull [[MREG:x[0-9]+]], w0, w1
512 ; CHECK-NEXT: tst [[MREG]], #0xffffffff00000000
513 ; CHECK-NEXT: csel w0, w0, w1, ne
514 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
515 %obit = extractvalue {i32, i1} %t, 1
516 %ret = select i1 %obit, i32 %v1, i32 %v2
520 define i1 @umulo.not.i32(i32 %v1, i32 %v2) {
522 ; CHECK-LABEL: umulo.not.i32
523 ; CHECK: umull [[MREG:x[0-9]+]], w0, w1
524 ; CHECK-NEXT: tst [[MREG]], #0xffffffff00000000
525 ; CHECK-NEXT: cset w0, eq
526 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
527 %obit = extractvalue {i32, i1} %t, 1
528 %ret = xor i1 %obit, true
532 define i64 @umulo.select.i64(i64 %v1, i64 %v2) {
534 ; CHECK-LABEL: umulo.select.i64
535 ; CHECK: umulh [[MREG:x[0-9]+]], x0, x1
536 ; CHECK-NEXT: cmp xzr, [[MREG]]
537 ; CHECK-NEXT: csel x0, x0, x1, ne
538 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
539 %obit = extractvalue {i64, i1} %t, 1
540 %ret = select i1 %obit, i64 %v1, i64 %v2
544 define i1 @umulo.not.i64(i64 %v1, i64 %v2) {
546 ; CHECK-LABEL: umulo.not.i64
547 ; CHECK: umulh [[MREG:x[0-9]+]], x0, x1
548 ; CHECK-NEXT: cmp xzr, [[MREG]]
549 ; CHECK-NEXT: cset w0, eq
550 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
551 %obit = extractvalue {i64, i1} %t, 1
552 %ret = xor i1 %obit, true
558 ; Check the use of the overflow bit in combination with a branch instruction.
560 define zeroext i1 @saddo.br.i32(i32 %v1, i32 %v2) {
562 ; CHECK-LABEL: saddo.br.i32
565 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2)
566 %val = extractvalue {i32, i1} %t, 0
567 %obit = extractvalue {i32, i1} %t, 1
568 br i1 %obit, label %overflow, label %continue
577 define zeroext i1 @saddo.br.i64(i64 %v1, i64 %v2) {
579 ; CHECK-LABEL: saddo.br.i64
582 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2)
583 %val = extractvalue {i64, i1} %t, 0
584 %obit = extractvalue {i64, i1} %t, 1
585 br i1 %obit, label %overflow, label %continue
594 define zeroext i1 @uaddo.br.i32(i32 %v1, i32 %v2) {
596 ; CHECK-LABEL: uaddo.br.i32
599 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)
600 %val = extractvalue {i32, i1} %t, 0
601 %obit = extractvalue {i32, i1} %t, 1
602 br i1 %obit, label %overflow, label %continue
611 define zeroext i1 @uaddo.br.i64(i64 %v1, i64 %v2) {
613 ; CHECK-LABEL: uaddo.br.i64
616 %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2)
617 %val = extractvalue {i64, i1} %t, 0
618 %obit = extractvalue {i64, i1} %t, 1
619 br i1 %obit, label %overflow, label %continue
628 define zeroext i1 @ssubo.br.i32(i32 %v1, i32 %v2) {
630 ; CHECK-LABEL: ssubo.br.i32
633 %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2)
634 %val = extractvalue {i32, i1} %t, 0
635 %obit = extractvalue {i32, i1} %t, 1
636 br i1 %obit, label %overflow, label %continue
645 define zeroext i1 @ssubo.br.i64(i64 %v1, i64 %v2) {
647 ; CHECK-LABEL: ssubo.br.i64
650 %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2)
651 %val = extractvalue {i64, i1} %t, 0
652 %obit = extractvalue {i64, i1} %t, 1
653 br i1 %obit, label %overflow, label %continue
662 define zeroext i1 @usubo.br.i32(i32 %v1, i32 %v2) {
664 ; CHECK-LABEL: usubo.br.i32
667 %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2)
668 %val = extractvalue {i32, i1} %t, 0
669 %obit = extractvalue {i32, i1} %t, 1
670 br i1 %obit, label %overflow, label %continue
679 define zeroext i1 @usubo.br.i64(i64 %v1, i64 %v2) {
681 ; CHECK-LABEL: usubo.br.i64
684 %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2)
685 %val = extractvalue {i64, i1} %t, 0
686 %obit = extractvalue {i64, i1} %t, 1
687 br i1 %obit, label %overflow, label %continue
696 define zeroext i1 @smulo.br.i32(i32 %v1, i32 %v2) {
698 ; CHECK-LABEL: smulo.br.i32
699 ; CHECK: smull x[[MREG:[0-9]+]], w0, w1
700 ; CHECK-NEXT: cmp x[[MREG]], w[[MREG]], sxtw
702 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
703 %val = extractvalue {i32, i1} %t, 0
704 %obit = extractvalue {i32, i1} %t, 1
705 br i1 %obit, label %overflow, label %continue
714 define zeroext i1 @smulo.br.i64(i64 %v1, i64 %v2) {
716 ; CHECK-LABEL: smulo.br.i64
717 ; CHECK: mul [[MREG:x[0-9]+]], x0, x1
718 ; CHECK-NEXT: smulh [[HREG:x[0-9]+]], x0, x1
719 ; CHECK-NEXT: cmp [[HREG]], [[MREG]], asr #63
721 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
722 %val = extractvalue {i64, i1} %t, 0
723 %obit = extractvalue {i64, i1} %t, 1
724 br i1 %obit, label %overflow, label %continue
733 define zeroext i1 @smulo2.br.i64(i64 %v1) {
735 ; CHECK-LABEL: smulo2.br.i64
738 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 2)
739 %val = extractvalue {i64, i1} %t, 0
740 %obit = extractvalue {i64, i1} %t, 1
741 br i1 %obit, label %overflow, label %continue
750 define zeroext i1 @umulo.br.i32(i32 %v1, i32 %v2) {
752 ; CHECK-LABEL: umulo.br.i32
753 ; CHECK: umull [[MREG:x[0-9]+]], w0, w1
754 ; CHECK-NEXT: tst [[MREG]], #0xffffffff00000000
756 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
757 %val = extractvalue {i32, i1} %t, 0
758 %obit = extractvalue {i32, i1} %t, 1
759 br i1 %obit, label %overflow, label %continue
768 define zeroext i1 @umulo.br.i64(i64 %v1, i64 %v2) {
770 ; CHECK-LABEL: umulo.br.i64
771 ; CHECK: umulh [[REG:x[0-9]+]], x0, x1
772 ; CHECK-NEXT: {{cbz|cmp}}
773 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
774 %val = extractvalue {i64, i1} %t, 0
775 %obit = extractvalue {i64, i1} %t, 1
776 br i1 %obit, label %overflow, label %continue
785 define zeroext i1 @umulo2.br.i64(i64 %v1) {
787 ; CHECK-LABEL: umulo2.br.i64
790 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 2)
791 %val = extractvalue {i64, i1} %t, 0
792 %obit = extractvalue {i64, i1} %t, 1
793 br i1 %obit, label %overflow, label %continue
802 declare {i32, i1} @llvm.sadd.with.overflow.i32(i32, i32) nounwind readnone
803 declare {i64, i1} @llvm.sadd.with.overflow.i64(i64, i64) nounwind readnone
804 declare {i32, i1} @llvm.uadd.with.overflow.i32(i32, i32) nounwind readnone
805 declare {i64, i1} @llvm.uadd.with.overflow.i64(i64, i64) nounwind readnone
806 declare {i32, i1} @llvm.ssub.with.overflow.i32(i32, i32) nounwind readnone
807 declare {i64, i1} @llvm.ssub.with.overflow.i64(i64, i64) nounwind readnone
808 declare {i32, i1} @llvm.usub.with.overflow.i32(i32, i32) nounwind readnone
809 declare {i64, i1} @llvm.usub.with.overflow.i64(i64, i64) nounwind readnone
810 declare {i32, i1} @llvm.smul.with.overflow.i32(i32, i32) nounwind readnone
811 declare {i64, i1} @llvm.smul.with.overflow.i64(i64, i64) nounwind readnone
812 declare {i32, i1} @llvm.umul.with.overflow.i32(i32, i32) nounwind readnone
813 declare {i64, i1} @llvm.umul.with.overflow.i64(i64, i64) nounwind readnone