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
4
5;
6; Get the actual value of the overflow bit.
7;
8define zeroext i1 @saddo1.i32(i32 %v1, i32 %v2, i32* %res) {
9entry:
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
18}
19
20; Test the immediate version.
21define zeroext i1 @saddo2.i32(i32 %v1, i32* %res) {
22entry:
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
31}
32
33; Test negative immediates.
34define zeroext i1 @saddo3.i32(i32 %v1, i32* %res) {
35entry:
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
44}
45
46; Test immediates that are too large to be encoded.
47define zeroext i1 @saddo4.i32(i32 %v1, i32* %res) {
48entry:
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
57}
58
59; Test shift folding.
60define zeroext i1 @saddo5.i32(i32 %v1, i32 %v2, i32* %res) {
61entry:
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
71}
72
73define zeroext i1 @saddo1.i64(i64 %v1, i64 %v2, i64* %res) {
74entry:
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
83}
84
85define zeroext i1 @saddo2.i64(i64 %v1, i64* %res) {
86entry:
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
95}
96
97define zeroext i1 @saddo3.i64(i64 %v1, i64* %res) {
98entry:
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
107}
108
109; FALLBACK-NOT: remark{{.*}}uaddo.i32
110define zeroext i1 @uaddo.i32(i32 %v1, i32 %v2, i32* %res) {
111entry:
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
123}
124
125; FALLBACK-NOT: remark{{.*}}uaddo.i64
126define zeroext i1 @uaddo.i64(i64 %v1, i64 %v2, i64* %res) {
127entry:
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
139}
140
141define zeroext i1 @ssubo1.i32(i32 %v1, i32 %v2, i32* %res) {
142entry:
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
151}
152
153define zeroext i1 @ssubo2.i32(i32 %v1, i32* %res) {
154entry:
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
163}
164
165define zeroext i1 @ssubo.i64(i64 %v1, i64 %v2, i64* %res) {
166entry:
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
175}
176
177define zeroext i1 @usubo.i32(i32 %v1, i32 %v2, i32* %res) {
178entry:
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
187}
188
189define zeroext i1 @usubo.i64(i64 %v1, i64 %v2, i64* %res) {
190entry:
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
199}
200
201define zeroext i1 @smulo.i32(i32 %v1, i32 %v2, i32* %res) {
202entry:
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
212  ret i1 %obit
213}
214
215define zeroext i1 @smulo.i64(i64 %v1, i64 %v2, i64* %res) {
216entry:
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
226  ret i1 %obit
227}
228
229define zeroext i1 @smulo2.i64(i64 %v1, i64* %res) {
230entry:
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
238  ret i1 %obit
239}
240
241define zeroext i1 @umulo.i32(i32 %v1, i32 %v2, i32* %res) {
242entry:
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
251  ret i1 %obit
252}
253
254define zeroext i1 @umulo.i64(i64 %v1, i64 %v2, i64* %res) {
255entry:
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
264  ret i1 %obit
265}
266
267define zeroext i1 @umulo2.i64(i64 %v1, i64* %res) {
268entry:
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
276  ret i1 %obit
277}
278
279
280;
281; Check the use of the overflow bit in combination with a select instruction.
282;
283define i32 @saddo.select.i32(i32 %v1, i32 %v2) {
284entry:
285; CHECK-LABEL:  saddo.select.i32
286; CHECK:        cmn w0, w1
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
291  ret i32 %ret
292}
293
294define i1 @saddo.not.i32(i32 %v1, i32 %v2) {
295entry:
296; CHECK-LABEL:  saddo.not.i32
297; CHECK:        cmn w0, w1
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
302  ret i1 %ret
303}
304
305define i64 @saddo.select.i64(i64 %v1, i64 %v2) {
306entry:
307; CHECK-LABEL:  saddo.select.i64
308; CHECK:        cmn x0, x1
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
313  ret i64 %ret
314}
315
316define i1 @saddo.not.i64(i64 %v1, i64 %v2) {
317entry:
318; CHECK-LABEL:  saddo.not.i64
319; CHECK:        cmn x0, x1
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
324  ret i1 %ret
325}
326
327define i32 @uaddo.select.i32(i32 %v1, i32 %v2) {
328entry:
329; CHECK-LABEL:  uaddo.select.i32
330; CHECK:        cmn w0, w1
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
335  ret i32 %ret
336}
337
338define i1 @uaddo.not.i32(i32 %v1, i32 %v2) {
339entry:
340; CHECK-LABEL:  uaddo.not.i32
341; CHECK:        cmn w0, w1
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
346  ret i1 %ret
347}
348
349define i64 @uaddo.select.i64(i64 %v1, i64 %v2) {
350entry:
351; CHECK-LABEL:  uaddo.select.i64
352; CHECK:        cmn x0, x1
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
357  ret i64 %ret
358}
359
360define i1 @uaddo.not.i64(i64 %v1, i64 %v2) {
361entry:
362; CHECK-LABEL:  uaddo.not.i64
363; CHECK:        cmn x0, x1
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
368  ret i1 %ret
369}
370
371define i32 @ssubo.select.i32(i32 %v1, i32 %v2) {
372entry:
373; CHECK-LABEL:  ssubo.select.i32
374; CHECK:        cmp w0, w1
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
379  ret i32 %ret
380}
381
382define i1 @ssubo.not.i32(i32 %v1, i32 %v2) {
383entry:
384; CHECK-LABEL:  ssubo.not.i32
385; CHECK:        cmp w0, w1
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
390  ret i1 %ret
391}
392
393define i64 @ssubo.select.i64(i64 %v1, i64 %v2) {
394entry:
395; CHECK-LABEL:  ssubo.select.i64
396; CHECK:        cmp x0, x1
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
401  ret i64 %ret
402}
403
404define i1 @ssub.not.i64(i64 %v1, i64 %v2) {
405entry:
406; CHECK-LABEL:  ssub.not.i64
407; CHECK:        cmp x0, x1
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
412  ret i1 %ret
413}
414
415define i32 @usubo.select.i32(i32 %v1, i32 %v2) {
416entry:
417; CHECK-LABEL:  usubo.select.i32
418; CHECK:        cmp w0, w1
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
423  ret i32 %ret
424}
425
426define i1 @usubo.not.i32(i32 %v1, i32 %v2) {
427entry:
428; CHECK-LABEL:  usubo.not.i32
429; CHECK:        cmp w0, w1
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
434  ret i1 %ret
435}
436
437define i64 @usubo.select.i64(i64 %v1, i64 %v2) {
438entry:
439; CHECK-LABEL:  usubo.select.i64
440; CHECK:        cmp x0, x1
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
445  ret i64 %ret
446}
447
448define i1 @usubo.not.i64(i64 %v1, i64 %v2) {
449entry:
450; CHECK-LABEL:  usubo.not.i64
451; CHECK:        cmp x0, x1
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
456  ret i1 %ret
457}
458
459define i32 @smulo.select.i32(i32 %v1, i32 %v2) {
460entry:
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
469  ret i32 %ret
470}
471
472define i1 @smulo.not.i32(i32 %v1, i32 %v2) {
473entry:
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
482  ret i1 %ret
483}
484
485define i64 @smulo.select.i64(i64 %v1, i64 %v2) {
486entry:
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
495  ret i64 %ret
496}
497
498define i1 @smulo.not.i64(i64 %v1, i64 %v2) {
499entry:
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
508  ret i1 %ret
509}
510
511define i32 @umulo.select.i32(i32 %v1, i32 %v2) {
512entry:
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
520  ret i32 %ret
521}
522
523define i1 @umulo.not.i32(i32 %v1, i32 %v2) {
524entry:
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
532  ret i1 %ret
533}
534
535define i64 @umulo.select.i64(i64 %v1, i64 %v2) {
536entry:
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
544  ret i64 %ret
545}
546
547define i1 @umulo.not.i64(i64 %v1, i64 %v2) {
548entry:
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
556  ret i1 %ret
557}
558
559
560;
561; Check the use of the overflow bit in combination with a branch instruction.
562;
563define zeroext i1 @saddo.br.i32(i32 %v1, i32 %v2) {
564entry:
565; CHECK-LABEL:  saddo.br.i32
566; CHECK:        cmn w0, w1
567; CHECK-NEXT:   b.vc
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
572
573overflow:
574  ret i1 false
575
576continue:
577  ret i1 true
578}
579
580define zeroext i1 @saddo.br.i64(i64 %v1, i64 %v2) {
581entry:
582; CHECK-LABEL:  saddo.br.i64
583; CHECK:        cmn x0, x1
584; CHECK-NEXT:   b.vc
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
589
590overflow:
591  ret i1 false
592
593continue:
594  ret i1 true
595}
596
597define zeroext i1 @uaddo.br.i32(i32 %v1, i32 %v2) {
598entry:
599; CHECK-LABEL:  uaddo.br.i32
600; CHECK:        cmn w0, w1
601; CHECK-NEXT:   b.lo
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
606
607overflow:
608  ret i1 false
609
610continue:
611  ret i1 true
612}
613
614define zeroext i1 @uaddo.br.i64(i64 %v1, i64 %v2) {
615entry:
616; CHECK-LABEL:  uaddo.br.i64
617; CHECK:        cmn x0, x1
618; CHECK-NEXT:   b.lo
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
623
624overflow:
625  ret i1 false
626
627continue:
628  ret i1 true
629}
630
631define zeroext i1 @ssubo.br.i32(i32 %v1, i32 %v2) {
632entry:
633; CHECK-LABEL:  ssubo.br.i32
634; CHECK:        cmp w0, w1
635; CHECK-NEXT:   b.vc
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
640
641overflow:
642  ret i1 false
643
644continue:
645  ret i1 true
646}
647
648define zeroext i1 @ssubo.br.i64(i64 %v1, i64 %v2) {
649entry:
650; CHECK-LABEL:  ssubo.br.i64
651; CHECK:        cmp x0, x1
652; CHECK-NEXT:   b.vc
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
657
658overflow:
659  ret i1 false
660
661continue:
662  ret i1 true
663}
664
665define zeroext i1 @usubo.br.i32(i32 %v1, i32 %v2) {
666entry:
667; CHECK-LABEL:  usubo.br.i32
668; CHECK:        cmp w0, w1
669; CHECK-NEXT:   b.hs
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
674
675overflow:
676  ret i1 false
677
678continue:
679  ret i1 true
680}
681
682define zeroext i1 @usubo.br.i64(i64 %v1, i64 %v2) {
683entry:
684; CHECK-LABEL:  usubo.br.i64
685; CHECK:        cmp x0, x1
686; CHECK-NEXT:   b.hs
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
691
692overflow:
693  ret i1 false
694
695continue:
696  ret i1 true
697}
698
699define zeroext i1 @smulo.br.i32(i32 %v1, i32 %v2) {
700entry:
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
705; CHECK-NEXT:   b.eq
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
710
711overflow:
712  ret i1 false
713
714continue:
715  ret i1 true
716}
717
718define zeroext i1 @smulo.br.i64(i64 %v1, i64 %v2) {
719entry:
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
724; CHECK-NEXT:   b.eq
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
729
730overflow:
731  ret i1 false
732
733continue:
734  ret i1 true
735}
736
737define zeroext i1 @smulo2.br.i64(i64 %v1) {
738entry:
739; CHECK-LABEL:  smulo2.br.i64
740; CHECK:        cmn  x0, x0
741; CHECK-NEXT:   b.vc
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
746
747overflow:
748  ret i1 false
749
750continue:
751  ret i1 true
752}
753
754define zeroext i1 @umulo.br.i32(i32 %v1, i32 %v2) {
755entry:
756; CHECK-LABEL:  umulo.br.i32
757; CHECK:        umull   [[MREG:x[0-9]+]], w0, w1
758; CHECK-NEXT:   cmp     xzr, [[MREG]], lsr #32
759; CHECK-NEXT:   b.eq
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
764
765overflow:
766  ret i1 false
767
768continue:
769  ret i1 true
770}
771
772define zeroext i1 @umulo.br.i64(i64 %v1, i64 %v2) {
773entry:
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
781
782overflow:
783  ret i1 false
784
785continue:
786  ret i1 true
787}
788
789define zeroext i1 @umulo2.br.i64(i64 %v1) {
790entry:
791; CHECK-LABEL:  umulo2.br.i64
792; CHECK:        cmn  x0, x0
793; CHECK-NEXT:   b.lo
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
798
799overflow:
800  ret i1 false
801
802continue:
803  ret i1 true
804}
805
806declare {i32, i1} @llvm.sadd.with.overflow.i32(i32, i32) nounwind readnone
807declare {i64, i1} @llvm.sadd.with.overflow.i64(i64, i64) nounwind readnone
808declare {i32, i1} @llvm.uadd.with.overflow.i32(i32, i32) nounwind readnone
809declare {i64, i1} @llvm.uadd.with.overflow.i64(i64, i64) nounwind readnone
810declare {i32, i1} @llvm.ssub.with.overflow.i32(i32, i32) nounwind readnone
811declare {i64, i1} @llvm.ssub.with.overflow.i64(i64, i64) nounwind readnone
812declare {i32, i1} @llvm.usub.with.overflow.i32(i32, i32) nounwind readnone
813declare {i64, i1} @llvm.usub.with.overflow.i64(i64, i64) nounwind readnone
814declare {i32, i1} @llvm.smul.with.overflow.i32(i32, i32) nounwind readnone
815declare {i64, i1} @llvm.smul.with.overflow.i64(i64, i64) nounwind readnone
816declare {i32, i1} @llvm.umul.with.overflow.i32(i32, i32) nounwind readnone
817declare {i64, i1} @llvm.umul.with.overflow.i64(i64, i64) nounwind readnone
818
819