[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / CodeGen / AArch64 / arm64-xaluo.ll
blobd8f5db89954f6d7871c06c03ba0b39be2623ae05
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) {
9 entry:
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
17   ret i1 %obit
20 ; Test the immediate version.
21 define zeroext i1 @saddo2.i32(i32 %v1, i32* %res) {
22 entry:
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
30   ret i1 %obit
33 ; Test negative immediates.
34 define zeroext i1 @saddo3.i32(i32 %v1, i32* %res) {
35 entry:
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
43   ret i1 %obit
46 ; Test immediates that are too large to be encoded.
47 define zeroext i1 @saddo4.i32(i32 %v1, i32* %res) {
48 entry:
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
56   ret i1 %obit
59 ; Test shift folding.
60 define zeroext i1 @saddo5.i32(i32 %v1, i32 %v2, i32* %res) {
61 entry:
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
70   ret i1 %obit
73 define zeroext i1 @saddo1.i64(i64 %v1, i64 %v2, i64* %res) {
74 entry:
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
82   ret i1 %obit
85 define zeroext i1 @saddo2.i64(i64 %v1, i64* %res) {
86 entry:
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
94   ret i1 %obit
97 define zeroext i1 @saddo3.i64(i64 %v1, i64* %res) {
98 entry:
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
106   ret i1 %obit
109 ; FALLBACK-NOT: remark{{.*}}uaddo.i32
110 define zeroext i1 @uaddo.i32(i32 %v1, i32 %v2, i32* %res) {
111 entry:
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
122   ret i1 %obit
125 ; FALLBACK-NOT: remark{{.*}}uaddo.i64
126 define zeroext i1 @uaddo.i64(i64 %v1, i64 %v2, i64* %res) {
127 entry:
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
138   ret i1 %obit
141 define zeroext i1 @ssubo1.i32(i32 %v1, i32 %v2, i32* %res) {
142 entry:
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
150   ret i1 %obit
153 define zeroext i1 @ssubo2.i32(i32 %v1, i32* %res) {
154 entry:
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
162   ret i1 %obit
165 define zeroext i1 @ssubo.i64(i64 %v1, i64 %v2, i64* %res) {
166 entry:
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
174   ret i1 %obit
177 define zeroext i1 @usubo.i32(i32 %v1, i32 %v2, i32* %res) {
178 entry:
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
186   ret i1 %obit
189 define zeroext i1 @usubo.i64(i64 %v1, i64 %v2, i64* %res) {
190 entry:
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
198   ret i1 %obit
201 define zeroext i1 @smulo.i32(i32 %v1, i32 %v2, i32* %res) {
202 entry:
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
211   ret i1 %obit
214 define zeroext i1 @smulo.i64(i64 %v1, i64 %v2, i64* %res) {
215 entry:
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
225   ret i1 %obit
228 define zeroext i1 @smulo2.i64(i64 %v1, i64* %res) {
229 entry:
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
237   ret i1 %obit
240 define zeroext i1 @umulo.i32(i32 %v1, i32 %v2, i32* %res) {
241 entry:
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
250   ret i1 %obit
253 define zeroext i1 @umulo.i64(i64 %v1, i64 %v2, i64* %res) {
254 entry:
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
263   ret i1 %obit
266 define zeroext i1 @umulo2.i64(i64 %v1, i64* %res) {
267 entry:
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
275   ret i1 %obit
280 ; Check the use of the overflow bit in combination with a select instruction.
282 define i32 @saddo.select.i32(i32 %v1, i32 %v2) {
283 entry:
284 ; CHECK-LABEL:  saddo.select.i32
285 ; CHECK:        cmn w0, w1
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
290   ret i32 %ret
293 define i1 @saddo.not.i32(i32 %v1, i32 %v2) {
294 entry:
295 ; CHECK-LABEL:  saddo.not.i32
296 ; CHECK:        cmn w0, w1
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
301   ret i1 %ret
304 define i64 @saddo.select.i64(i64 %v1, i64 %v2) {
305 entry:
306 ; CHECK-LABEL:  saddo.select.i64
307 ; CHECK:        cmn x0, x1
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
312   ret i64 %ret
315 define i1 @saddo.not.i64(i64 %v1, i64 %v2) {
316 entry:
317 ; CHECK-LABEL:  saddo.not.i64
318 ; CHECK:        cmn x0, x1
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
323   ret i1 %ret
326 define i32 @uaddo.select.i32(i32 %v1, i32 %v2) {
327 entry:
328 ; CHECK-LABEL:  uaddo.select.i32
329 ; CHECK:        cmn w0, w1
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
334   ret i32 %ret
337 define i1 @uaddo.not.i32(i32 %v1, i32 %v2) {
338 entry:
339 ; CHECK-LABEL:  uaddo.not.i32
340 ; CHECK:        cmn w0, w1
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
345   ret i1 %ret
348 define i64 @uaddo.select.i64(i64 %v1, i64 %v2) {
349 entry:
350 ; CHECK-LABEL:  uaddo.select.i64
351 ; CHECK:        cmn x0, x1
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
356   ret i64 %ret
359 define i1 @uaddo.not.i64(i64 %v1, i64 %v2) {
360 entry:
361 ; CHECK-LABEL:  uaddo.not.i64
362 ; CHECK:        cmn x0, x1
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
367   ret i1 %ret
370 define i32 @ssubo.select.i32(i32 %v1, i32 %v2) {
371 entry:
372 ; CHECK-LABEL:  ssubo.select.i32
373 ; CHECK:        cmp w0, w1
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
378   ret i32 %ret
381 define i1 @ssubo.not.i32(i32 %v1, i32 %v2) {
382 entry:
383 ; CHECK-LABEL:  ssubo.not.i32
384 ; CHECK:        cmp w0, w1
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
389   ret i1 %ret
392 define i64 @ssubo.select.i64(i64 %v1, i64 %v2) {
393 entry:
394 ; CHECK-LABEL:  ssubo.select.i64
395 ; CHECK:        cmp x0, x1
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
400   ret i64 %ret
403 define i1 @ssub.not.i64(i64 %v1, i64 %v2) {
404 entry:
405 ; CHECK-LABEL:  ssub.not.i64
406 ; CHECK:        cmp x0, x1
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
411   ret i1 %ret
414 define i32 @usubo.select.i32(i32 %v1, i32 %v2) {
415 entry:
416 ; CHECK-LABEL:  usubo.select.i32
417 ; CHECK:        cmp w0, w1
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
422   ret i32 %ret
425 define i1 @usubo.not.i32(i32 %v1, i32 %v2) {
426 entry:
427 ; CHECK-LABEL:  usubo.not.i32
428 ; CHECK:        cmp w0, w1
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
433   ret i1 %ret
436 define i64 @usubo.select.i64(i64 %v1, i64 %v2) {
437 entry:
438 ; CHECK-LABEL:  usubo.select.i64
439 ; CHECK:        cmp x0, x1
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
444   ret i64 %ret
447 define i1 @usubo.not.i64(i64 %v1, i64 %v2) {
448 entry:
449 ; CHECK-LABEL:  usubo.not.i64
450 ; CHECK:        cmp x0, x1
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
455   ret i1 %ret
458 define i32 @smulo.select.i32(i32 %v1, i32 %v2) {
459 entry:
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
467   ret i32 %ret
470 define i1 @smulo.not.i32(i32 %v1, i32 %v2) {
471 entry:
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
479   ret i1 %ret
482 define i64 @smulo.select.i64(i64 %v1, i64 %v2) {
483 entry:
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
492   ret i64 %ret
495 define i1 @smulo.not.i64(i64 %v1, i64 %v2) {
496 entry:
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
505   ret i1 %ret
508 define i32 @umulo.select.i32(i32 %v1, i32 %v2) {
509 entry:
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
517   ret i32 %ret
520 define i1 @umulo.not.i32(i32 %v1, i32 %v2) {
521 entry:
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
529   ret i1 %ret
532 define i64 @umulo.select.i64(i64 %v1, i64 %v2) {
533 entry:
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
541   ret i64 %ret
544 define i1 @umulo.not.i64(i64 %v1, i64 %v2) {
545 entry:
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
553   ret i1 %ret
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) {
561 entry:
562 ; CHECK-LABEL:  saddo.br.i32
563 ; CHECK:        cmn w0, w1
564 ; CHECK-NEXT:   b.vc
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
570 overflow:
571   ret i1 false
573 continue:
574   ret i1 true
577 define zeroext i1 @saddo.br.i64(i64 %v1, i64 %v2) {
578 entry:
579 ; CHECK-LABEL:  saddo.br.i64
580 ; CHECK:        cmn x0, x1
581 ; CHECK-NEXT:   b.vc
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
587 overflow:
588   ret i1 false
590 continue:
591   ret i1 true
594 define zeroext i1 @uaddo.br.i32(i32 %v1, i32 %v2) {
595 entry:
596 ; CHECK-LABEL:  uaddo.br.i32
597 ; CHECK:        cmn w0, w1
598 ; CHECK-NEXT:   b.lo
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
604 overflow:
605   ret i1 false
607 continue:
608   ret i1 true
611 define zeroext i1 @uaddo.br.i64(i64 %v1, i64 %v2) {
612 entry:
613 ; CHECK-LABEL:  uaddo.br.i64
614 ; CHECK:        cmn x0, x1
615 ; CHECK-NEXT:   b.lo
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
621 overflow:
622   ret i1 false
624 continue:
625   ret i1 true
628 define zeroext i1 @ssubo.br.i32(i32 %v1, i32 %v2) {
629 entry:
630 ; CHECK-LABEL:  ssubo.br.i32
631 ; CHECK:        cmp w0, w1
632 ; CHECK-NEXT:   b.vc
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
638 overflow:
639   ret i1 false
641 continue:
642   ret i1 true
645 define zeroext i1 @ssubo.br.i64(i64 %v1, i64 %v2) {
646 entry:
647 ; CHECK-LABEL:  ssubo.br.i64
648 ; CHECK:        cmp x0, x1
649 ; CHECK-NEXT:   b.vc
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
655 overflow:
656   ret i1 false
658 continue:
659   ret i1 true
662 define zeroext i1 @usubo.br.i32(i32 %v1, i32 %v2) {
663 entry:
664 ; CHECK-LABEL:  usubo.br.i32
665 ; CHECK:        cmp w0, w1
666 ; CHECK-NEXT:   b.hs
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
672 overflow:
673   ret i1 false
675 continue:
676   ret i1 true
679 define zeroext i1 @usubo.br.i64(i64 %v1, i64 %v2) {
680 entry:
681 ; CHECK-LABEL:  usubo.br.i64
682 ; CHECK:        cmp x0, x1
683 ; CHECK-NEXT:   b.hs
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
689 overflow:
690   ret i1 false
692 continue:
693   ret i1 true
696 define zeroext i1 @smulo.br.i32(i32 %v1, i32 %v2) {
697 entry:
698 ; CHECK-LABEL:  smulo.br.i32
699 ; CHECK:        smull   x[[MREG:[0-9]+]], w0, w1
700 ; CHECK-NEXT:   cmp     x[[MREG]], w[[MREG]], sxtw
701 ; CHECK-NEXT:   b.eq
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
707 overflow:
708   ret i1 false
710 continue:
711   ret i1 true
714 define zeroext i1 @smulo.br.i64(i64 %v1, i64 %v2) {
715 entry:
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
720 ; CHECK-NEXT:   b.eq
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
726 overflow:
727   ret i1 false
729 continue:
730   ret i1 true
733 define zeroext i1 @smulo2.br.i64(i64 %v1) {
734 entry:
735 ; CHECK-LABEL:  smulo2.br.i64
736 ; CHECK:        cmn  x0, x0
737 ; CHECK-NEXT:   b.vc
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
743 overflow:
744   ret i1 false
746 continue:
747   ret i1 true
750 define zeroext i1 @umulo.br.i32(i32 %v1, i32 %v2) {
751 entry:
752 ; CHECK-LABEL:  umulo.br.i32
753 ; CHECK:        umull   [[MREG:x[0-9]+]], w0, w1
754 ; CHECK-NEXT:   tst     [[MREG]], #0xffffffff00000000
755 ; CHECK-NEXT:   b.eq
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
761 overflow:
762   ret i1 false
764 continue:
765   ret i1 true
768 define zeroext i1 @umulo.br.i64(i64 %v1, i64 %v2) {
769 entry:
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
778 overflow:
779   ret i1 false
781 continue:
782   ret i1 true
785 define zeroext i1 @umulo2.br.i64(i64 %v1) {
786 entry:
787 ; CHECK-LABEL:  umulo2.br.i64
788 ; CHECK:        cmn  x0, x0
789 ; CHECK-NEXT:   b.lo
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
795 overflow:
796   ret i1 false
798 continue:
799   ret i1 true
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