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: lsr x[[SREG:[0-9]+]], x[[MREG]], #32
206 ; CHECK-NEXT: cmp w[[SREG]], w[[MREG]], asr #31
207 ; CHECK-NEXT: cset {{w[0-9]+}}, ne
208 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
209 %val = extractvalue {i32, i1} %t, 0
210 %obit = extractvalue {i32, i1} %t, 1
211 store i32 %val, i32* %res
215 define zeroext i1 @smulo.i64(i64 %v1, i64 %v2, i64* %res) {
217 ; CHECK-LABEL: smulo.i64
218 ; CHECK: mul [[MREG:x[0-9]+]], x0, x1
219 ; CHECK-NEXT: smulh [[HREG:x[0-9]+]], x0, x1
220 ; CHECK-NEXT: cmp [[HREG]], [[MREG]], asr #63
221 ; CHECK-NEXT: cset {{w[0-9]+}}, ne
222 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
223 %val = extractvalue {i64, i1} %t, 0
224 %obit = extractvalue {i64, i1} %t, 1
225 store i64 %val, i64* %res
229 define zeroext i1 @smulo2.i64(i64 %v1, i64* %res) {
231 ; CHECK-LABEL: smulo2.i64
232 ; CHECK: adds [[MREG:x[0-9]+]], x0, x0
233 ; CHECK-NEXT: cset {{w[0-9]+}}, vs
234 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 2)
235 %val = extractvalue {i64, i1} %t, 0
236 %obit = extractvalue {i64, i1} %t, 1
237 store i64 %val, i64* %res
241 define zeroext i1 @umulo.i32(i32 %v1, i32 %v2, i32* %res) {
243 ; CHECK-LABEL: umulo.i32
244 ; CHECK: umull [[MREG:x[0-9]+]], w0, w1
245 ; CHECK-NEXT: cmp xzr, [[MREG]], lsr #32
246 ; CHECK-NEXT: cset {{w[0-9]+}}, ne
247 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
248 %val = extractvalue {i32, i1} %t, 0
249 %obit = extractvalue {i32, i1} %t, 1
250 store i32 %val, i32* %res
254 define zeroext i1 @umulo.i64(i64 %v1, i64 %v2, i64* %res) {
256 ; CHECK-LABEL: umulo.i64
257 ; CHECK: umulh [[MREG:x[0-9]+]], x0, x1
258 ; CHECK-NEXT: cmp xzr, [[MREG]]
259 ; CHECK-NEXT: cset {{w[0-9]+}}, ne
260 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
261 %val = extractvalue {i64, i1} %t, 0
262 %obit = extractvalue {i64, i1} %t, 1
263 store i64 %val, i64* %res
267 define zeroext i1 @umulo2.i64(i64 %v1, i64* %res) {
269 ; CHECK-LABEL: umulo2.i64
270 ; CHECK: adds [[MREG:x[0-9]+]], x0, x0
271 ; CHECK-NEXT: cset {{w[0-9]+}}, hs
272 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 2)
273 %val = extractvalue {i64, i1} %t, 0
274 %obit = extractvalue {i64, i1} %t, 1
275 store i64 %val, i64* %res
281 ; Check the use of the overflow bit in combination with a select instruction.
283 define i32 @saddo.select.i32(i32 %v1, i32 %v2) {
285 ; CHECK-LABEL: saddo.select.i32
287 ; CHECK-NEXT: csel w0, w0, w1, vs
288 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2)
289 %obit = extractvalue {i32, i1} %t, 1
290 %ret = select i1 %obit, i32 %v1, i32 %v2
294 define i1 @saddo.not.i32(i32 %v1, i32 %v2) {
296 ; CHECK-LABEL: saddo.not.i32
298 ; CHECK-NEXT: cset w0, vc
299 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2)
300 %obit = extractvalue {i32, i1} %t, 1
301 %ret = xor i1 %obit, true
305 define i64 @saddo.select.i64(i64 %v1, i64 %v2) {
307 ; CHECK-LABEL: saddo.select.i64
309 ; CHECK-NEXT: csel x0, x0, x1, vs
310 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2)
311 %obit = extractvalue {i64, i1} %t, 1
312 %ret = select i1 %obit, i64 %v1, i64 %v2
316 define i1 @saddo.not.i64(i64 %v1, i64 %v2) {
318 ; CHECK-LABEL: saddo.not.i64
320 ; CHECK-NEXT: cset w0, vc
321 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2)
322 %obit = extractvalue {i64, i1} %t, 1
323 %ret = xor i1 %obit, true
327 define i32 @uaddo.select.i32(i32 %v1, i32 %v2) {
329 ; CHECK-LABEL: uaddo.select.i32
331 ; CHECK-NEXT: csel w0, w0, w1, hs
332 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)
333 %obit = extractvalue {i32, i1} %t, 1
334 %ret = select i1 %obit, i32 %v1, i32 %v2
338 define i1 @uaddo.not.i32(i32 %v1, i32 %v2) {
340 ; CHECK-LABEL: uaddo.not.i32
342 ; CHECK-NEXT: cset w0, lo
343 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)
344 %obit = extractvalue {i32, i1} %t, 1
345 %ret = xor i1 %obit, true
349 define i64 @uaddo.select.i64(i64 %v1, i64 %v2) {
351 ; CHECK-LABEL: uaddo.select.i64
353 ; CHECK-NEXT: csel x0, x0, x1, hs
354 %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2)
355 %obit = extractvalue {i64, i1} %t, 1
356 %ret = select i1 %obit, i64 %v1, i64 %v2
360 define i1 @uaddo.not.i64(i64 %v1, i64 %v2) {
362 ; CHECK-LABEL: uaddo.not.i64
364 ; CHECK-NEXT: cset w0, lo
365 %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2)
366 %obit = extractvalue {i64, i1} %t, 1
367 %ret = xor i1 %obit, true
371 define i32 @ssubo.select.i32(i32 %v1, i32 %v2) {
373 ; CHECK-LABEL: ssubo.select.i32
375 ; CHECK-NEXT: csel w0, w0, w1, vs
376 %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2)
377 %obit = extractvalue {i32, i1} %t, 1
378 %ret = select i1 %obit, i32 %v1, i32 %v2
382 define i1 @ssubo.not.i32(i32 %v1, i32 %v2) {
384 ; CHECK-LABEL: ssubo.not.i32
386 ; CHECK-NEXT: cset w0, vc
387 %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2)
388 %obit = extractvalue {i32, i1} %t, 1
389 %ret = xor i1 %obit, true
393 define i64 @ssubo.select.i64(i64 %v1, i64 %v2) {
395 ; CHECK-LABEL: ssubo.select.i64
397 ; CHECK-NEXT: csel x0, x0, x1, vs
398 %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2)
399 %obit = extractvalue {i64, i1} %t, 1
400 %ret = select i1 %obit, i64 %v1, i64 %v2
404 define i1 @ssub.not.i64(i64 %v1, i64 %v2) {
406 ; CHECK-LABEL: ssub.not.i64
408 ; CHECK-NEXT: cset w0, vc
409 %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2)
410 %obit = extractvalue {i64, i1} %t, 1
411 %ret = xor i1 %obit, true
415 define i32 @usubo.select.i32(i32 %v1, i32 %v2) {
417 ; CHECK-LABEL: usubo.select.i32
419 ; CHECK-NEXT: csel w0, w0, w1, lo
420 %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2)
421 %obit = extractvalue {i32, i1} %t, 1
422 %ret = select i1 %obit, i32 %v1, i32 %v2
426 define i1 @usubo.not.i32(i32 %v1, i32 %v2) {
428 ; CHECK-LABEL: usubo.not.i32
430 ; CHECK-NEXT: cset w0, hs
431 %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2)
432 %obit = extractvalue {i32, i1} %t, 1
433 %ret = xor i1 %obit, true
437 define i64 @usubo.select.i64(i64 %v1, i64 %v2) {
439 ; CHECK-LABEL: usubo.select.i64
441 ; CHECK-NEXT: csel x0, x0, x1, lo
442 %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2)
443 %obit = extractvalue {i64, i1} %t, 1
444 %ret = select i1 %obit, i64 %v1, i64 %v2
448 define i1 @usubo.not.i64(i64 %v1, i64 %v2) {
450 ; CHECK-LABEL: usubo.not.i64
452 ; CHECK-NEXT: cset w0, hs
453 %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2)
454 %obit = extractvalue {i64, i1} %t, 1
455 %ret = xor i1 %obit, true
459 define i32 @smulo.select.i32(i32 %v1, i32 %v2) {
461 ; CHECK-LABEL: smulo.select.i32
462 ; CHECK: smull x[[MREG:[0-9]+]], w0, w1
463 ; CHECK-NEXT: lsr x[[SREG:[0-9]+]], x[[MREG]], #32
464 ; CHECK-NEXT: cmp w[[SREG]], w[[MREG]], asr #31
465 ; CHECK-NEXT: csel w0, w0, w1, ne
466 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
467 %obit = extractvalue {i32, i1} %t, 1
468 %ret = select i1 %obit, i32 %v1, i32 %v2
472 define i1 @smulo.not.i32(i32 %v1, i32 %v2) {
474 ; CHECK-LABEL: smulo.not.i32
475 ; CHECK: smull x[[MREG:[0-9]+]], w0, w1
476 ; CHECK-NEXT: lsr x[[SREG:[0-9]+]], x[[MREG]], #32
477 ; CHECK-NEXT: cmp w[[SREG]], w[[MREG]], asr #31
478 ; CHECK-NEXT: cset w0, eq
479 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
480 %obit = extractvalue {i32, i1} %t, 1
481 %ret = xor i1 %obit, true
485 define i64 @smulo.select.i64(i64 %v1, i64 %v2) {
487 ; CHECK-LABEL: smulo.select.i64
488 ; CHECK: mul [[MREG:x[0-9]+]], x0, x1
489 ; CHECK-NEXT: smulh [[HREG:x[0-9]+]], x0, x1
490 ; CHECK-NEXT: cmp [[HREG]], [[MREG]], asr #63
491 ; CHECK-NEXT: csel x0, x0, x1, ne
492 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
493 %obit = extractvalue {i64, i1} %t, 1
494 %ret = select i1 %obit, i64 %v1, i64 %v2
498 define i1 @smulo.not.i64(i64 %v1, i64 %v2) {
500 ; CHECK-LABEL: smulo.not.i64
501 ; CHECK: mul [[MREG:x[0-9]+]], x0, x1
502 ; CHECK-NEXT: smulh [[HREG:x[0-9]+]], x0, x1
503 ; CHECK-NEXT: cmp [[HREG]], [[MREG]], asr #63
504 ; CHECK-NEXT: cset w0, eq
505 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
506 %obit = extractvalue {i64, i1} %t, 1
507 %ret = xor i1 %obit, true
511 define i32 @umulo.select.i32(i32 %v1, i32 %v2) {
513 ; CHECK-LABEL: umulo.select.i32
514 ; CHECK: umull [[MREG:x[0-9]+]], w0, w1
515 ; CHECK-NEXT: cmp xzr, [[MREG]], lsr #32
516 ; CHECK-NEXT: csel w0, w0, w1, ne
517 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
518 %obit = extractvalue {i32, i1} %t, 1
519 %ret = select i1 %obit, i32 %v1, i32 %v2
523 define i1 @umulo.not.i32(i32 %v1, i32 %v2) {
525 ; CHECK-LABEL: umulo.not.i32
526 ; CHECK: umull [[MREG:x[0-9]+]], w0, w1
527 ; CHECK-NEXT: cmp xzr, [[MREG]], lsr #32
528 ; CHECK-NEXT: cset w0, eq
529 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
530 %obit = extractvalue {i32, i1} %t, 1
531 %ret = xor i1 %obit, true
535 define i64 @umulo.select.i64(i64 %v1, i64 %v2) {
537 ; CHECK-LABEL: umulo.select.i64
538 ; CHECK: umulh [[MREG:x[0-9]+]], x0, x1
539 ; CHECK-NEXT: cmp xzr, [[MREG]]
540 ; CHECK-NEXT: csel x0, x0, x1, ne
541 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
542 %obit = extractvalue {i64, i1} %t, 1
543 %ret = select i1 %obit, i64 %v1, i64 %v2
547 define i1 @umulo.not.i64(i64 %v1, i64 %v2) {
549 ; CHECK-LABEL: umulo.not.i64
550 ; CHECK: umulh [[MREG:x[0-9]+]], x0, x1
551 ; CHECK-NEXT: cmp xzr, [[MREG]]
552 ; CHECK-NEXT: cset w0, eq
553 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
554 %obit = extractvalue {i64, i1} %t, 1
555 %ret = xor i1 %obit, true
561 ; Check the use of the overflow bit in combination with a branch instruction.
563 define zeroext i1 @saddo.br.i32(i32 %v1, i32 %v2) {
565 ; CHECK-LABEL: saddo.br.i32
568 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2)
569 %val = extractvalue {i32, i1} %t, 0
570 %obit = extractvalue {i32, i1} %t, 1
571 br i1 %obit, label %overflow, label %continue
580 define zeroext i1 @saddo.br.i64(i64 %v1, i64 %v2) {
582 ; CHECK-LABEL: saddo.br.i64
585 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2)
586 %val = extractvalue {i64, i1} %t, 0
587 %obit = extractvalue {i64, i1} %t, 1
588 br i1 %obit, label %overflow, label %continue
597 define zeroext i1 @uaddo.br.i32(i32 %v1, i32 %v2) {
599 ; CHECK-LABEL: uaddo.br.i32
602 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)
603 %val = extractvalue {i32, i1} %t, 0
604 %obit = extractvalue {i32, i1} %t, 1
605 br i1 %obit, label %overflow, label %continue
614 define zeroext i1 @uaddo.br.i64(i64 %v1, i64 %v2) {
616 ; CHECK-LABEL: uaddo.br.i64
619 %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2)
620 %val = extractvalue {i64, i1} %t, 0
621 %obit = extractvalue {i64, i1} %t, 1
622 br i1 %obit, label %overflow, label %continue
631 define zeroext i1 @ssubo.br.i32(i32 %v1, i32 %v2) {
633 ; CHECK-LABEL: ssubo.br.i32
636 %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2)
637 %val = extractvalue {i32, i1} %t, 0
638 %obit = extractvalue {i32, i1} %t, 1
639 br i1 %obit, label %overflow, label %continue
648 define zeroext i1 @ssubo.br.i64(i64 %v1, i64 %v2) {
650 ; CHECK-LABEL: ssubo.br.i64
653 %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2)
654 %val = extractvalue {i64, i1} %t, 0
655 %obit = extractvalue {i64, i1} %t, 1
656 br i1 %obit, label %overflow, label %continue
665 define zeroext i1 @usubo.br.i32(i32 %v1, i32 %v2) {
667 ; CHECK-LABEL: usubo.br.i32
670 %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2)
671 %val = extractvalue {i32, i1} %t, 0
672 %obit = extractvalue {i32, i1} %t, 1
673 br i1 %obit, label %overflow, label %continue
682 define zeroext i1 @usubo.br.i64(i64 %v1, i64 %v2) {
684 ; CHECK-LABEL: usubo.br.i64
687 %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2)
688 %val = extractvalue {i64, i1} %t, 0
689 %obit = extractvalue {i64, i1} %t, 1
690 br i1 %obit, label %overflow, label %continue
699 define zeroext i1 @smulo.br.i32(i32 %v1, i32 %v2) {
701 ; CHECK-LABEL: smulo.br.i32
702 ; CHECK: smull x[[MREG:[0-9]+]], w0, w1
703 ; CHECK-NEXT: lsr x[[SREG:[0-9]+]], x8, #32
704 ; CHECK-NEXT: cmp w[[SREG]], w[[MREG]], asr #31
706 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
707 %val = extractvalue {i32, i1} %t, 0
708 %obit = extractvalue {i32, i1} %t, 1
709 br i1 %obit, label %overflow, label %continue
718 define zeroext i1 @smulo.br.i64(i64 %v1, i64 %v2) {
720 ; CHECK-LABEL: smulo.br.i64
721 ; CHECK: mul [[MREG:x[0-9]+]], x0, x1
722 ; CHECK-NEXT: smulh [[HREG:x[0-9]+]], x0, x1
723 ; CHECK-NEXT: cmp [[HREG]], [[MREG]], asr #63
725 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
726 %val = extractvalue {i64, i1} %t, 0
727 %obit = extractvalue {i64, i1} %t, 1
728 br i1 %obit, label %overflow, label %continue
737 define zeroext i1 @smulo2.br.i64(i64 %v1) {
739 ; CHECK-LABEL: smulo2.br.i64
742 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 2)
743 %val = extractvalue {i64, i1} %t, 0
744 %obit = extractvalue {i64, i1} %t, 1
745 br i1 %obit, label %overflow, label %continue
754 define zeroext i1 @umulo.br.i32(i32 %v1, i32 %v2) {
756 ; CHECK-LABEL: umulo.br.i32
757 ; CHECK: umull [[MREG:x[0-9]+]], w0, w1
758 ; CHECK-NEXT: cmp xzr, [[MREG]], lsr #32
760 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
761 %val = extractvalue {i32, i1} %t, 0
762 %obit = extractvalue {i32, i1} %t, 1
763 br i1 %obit, label %overflow, label %continue
772 define zeroext i1 @umulo.br.i64(i64 %v1, i64 %v2) {
774 ; CHECK-LABEL: umulo.br.i64
775 ; CHECK: umulh [[REG:x[0-9]+]], x0, x1
776 ; CHECK-NEXT: {{cbz|cmp}}
777 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
778 %val = extractvalue {i64, i1} %t, 0
779 %obit = extractvalue {i64, i1} %t, 1
780 br i1 %obit, label %overflow, label %continue
789 define zeroext i1 @umulo2.br.i64(i64 %v1) {
791 ; CHECK-LABEL: umulo2.br.i64
794 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 2)
795 %val = extractvalue {i64, i1} %t, 0
796 %obit = extractvalue {i64, i1} %t, 1
797 br i1 %obit, label %overflow, label %continue
806 declare {i32, i1} @llvm.sadd.with.overflow.i32(i32, i32) nounwind readnone
807 declare {i64, i1} @llvm.sadd.with.overflow.i64(i64, i64) nounwind readnone
808 declare {i32, i1} @llvm.uadd.with.overflow.i32(i32, i32) nounwind readnone
809 declare {i64, i1} @llvm.uadd.with.overflow.i64(i64, i64) nounwind readnone
810 declare {i32, i1} @llvm.ssub.with.overflow.i32(i32, i32) nounwind readnone
811 declare {i64, i1} @llvm.ssub.with.overflow.i64(i64, i64) nounwind readnone
812 declare {i32, i1} @llvm.usub.with.overflow.i32(i32, i32) nounwind readnone
813 declare {i64, i1} @llvm.usub.with.overflow.i64(i64, i64) nounwind readnone
814 declare {i32, i1} @llvm.smul.with.overflow.i32(i32, i32) nounwind readnone
815 declare {i64, i1} @llvm.smul.with.overflow.i64(i64, i64) nounwind readnone
816 declare {i32, i1} @llvm.umul.with.overflow.i32(i32, i32) nounwind readnone
817 declare {i64, i1} @llvm.umul.with.overflow.i64(i64, i64) nounwind readnone