1; RUN: llc -march=arm64 -aarch64-atomic-cfg-tidy=0                             -verify-machineinstrs < %s | FileCheck %s
2; RUN: llc -march=arm64 -aarch64-atomic-cfg-tidy=0 -fast-isel -fast-isel-abort -verify-machineinstrs < %s | FileCheck %s
3
4;
5; Get the actual value of the overflow bit.
6;
7define zeroext i1 @saddo1.i32(i32 %v1, i32 %v2, i32* %res) {
8entry:
9; CHECK-LABEL:  saddo1.i32
10; CHECK:        adds {{w[0-9]+}}, w0, w1
11; CHECK-NEXT:   cset {{w[0-9]+}}, vs
12  %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2)
13  %val = extractvalue {i32, i1} %t, 0
14  %obit = extractvalue {i32, i1} %t, 1
15  store i32 %val, i32* %res
16  ret i1 %obit
17}
18
19; Test the immediate version.
20define zeroext i1 @saddo2.i32(i32 %v1, i32* %res) {
21entry:
22; CHECK-LABEL:  saddo2.i32
23; CHECK:        adds {{w[0-9]+}}, w0, #4
24; CHECK-NEXT:   cset {{w[0-9]+}}, vs
25  %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 4)
26  %val = extractvalue {i32, i1} %t, 0
27  %obit = extractvalue {i32, i1} %t, 1
28  store i32 %val, i32* %res
29  ret i1 %obit
30}
31
32; Test negative immediates.
33define zeroext i1 @saddo3.i32(i32 %v1, i32* %res) {
34entry:
35; CHECK-LABEL:  saddo3.i32
36; CHECK:        subs {{w[0-9]+}}, w0, #4
37; CHECK-NEXT:   cset {{w[0-9]+}}, vs
38  %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 -4)
39  %val = extractvalue {i32, i1} %t, 0
40  %obit = extractvalue {i32, i1} %t, 1
41  store i32 %val, i32* %res
42  ret i1 %obit
43}
44
45; Test immediates that are too large to be encoded.
46define zeroext i1 @saddo4.i32(i32 %v1, i32* %res) {
47entry:
48; CHECK-LABEL:  saddo4.i32
49; CHECK:        adds {{w[0-9]+}}, w0, {{w[0-9]+}}
50; CHECK-NEXT:   cset {{w[0-9]+}}, vs
51  %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 16777215)
52  %val = extractvalue {i32, i1} %t, 0
53  %obit = extractvalue {i32, i1} %t, 1
54  store i32 %val, i32* %res
55  ret i1 %obit
56}
57
58; Test shift folding.
59define zeroext i1 @saddo5.i32(i32 %v1, i32 %v2, i32* %res) {
60entry:
61; CHECK-LABEL:  saddo5.i32
62; CHECK:        adds {{w[0-9]+}}, w0, w1
63; CHECK-NEXT:   cset {{w[0-9]+}}, vs
64  %lsl = shl i32 %v2, 16
65  %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %lsl)
66  %val = extractvalue {i32, i1} %t, 0
67  %obit = extractvalue {i32, i1} %t, 1
68  store i32 %val, i32* %res
69  ret i1 %obit
70}
71
72define zeroext i1 @saddo1.i64(i64 %v1, i64 %v2, i64* %res) {
73entry:
74; CHECK-LABEL:  saddo1.i64
75; CHECK:        adds {{x[0-9]+}}, x0, x1
76; CHECK-NEXT:   cset {{w[0-9]+}}, vs
77  %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2)
78  %val = extractvalue {i64, i1} %t, 0
79  %obit = extractvalue {i64, i1} %t, 1
80  store i64 %val, i64* %res
81  ret i1 %obit
82}
83
84define zeroext i1 @saddo2.i64(i64 %v1, i64* %res) {
85entry:
86; CHECK-LABEL:  saddo2.i64
87; CHECK:        adds {{x[0-9]+}}, x0, #4
88; CHECK-NEXT:   cset {{w[0-9]+}}, vs
89  %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 4)
90  %val = extractvalue {i64, i1} %t, 0
91  %obit = extractvalue {i64, i1} %t, 1
92  store i64 %val, i64* %res
93  ret i1 %obit
94}
95
96define zeroext i1 @saddo3.i64(i64 %v1, i64* %res) {
97entry:
98; CHECK-LABEL:  saddo3.i64
99; CHECK:        subs {{x[0-9]+}}, x0, #4
100; CHECK-NEXT:   cset {{w[0-9]+}}, vs
101  %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 -4)
102  %val = extractvalue {i64, i1} %t, 0
103  %obit = extractvalue {i64, i1} %t, 1
104  store i64 %val, i64* %res
105  ret i1 %obit
106}
107
108define zeroext i1 @uaddo.i32(i32 %v1, i32 %v2, i32* %res) {
109entry:
110; CHECK-LABEL:  uaddo.i32
111; CHECK:        adds {{w[0-9]+}}, w0, w1
112; CHECK-NEXT:   cset {{w[0-9]+}}, hs
113  %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)
114  %val = extractvalue {i32, i1} %t, 0
115  %obit = extractvalue {i32, i1} %t, 1
116  store i32 %val, i32* %res
117  ret i1 %obit
118}
119
120define zeroext i1 @uaddo.i64(i64 %v1, i64 %v2, i64* %res) {
121entry:
122; CHECK-LABEL:  uaddo.i64
123; CHECK:        adds {{x[0-9]+}}, x0, x1
124; CHECK-NEXT:   cset {{w[0-9]+}}, hs
125  %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2)
126  %val = extractvalue {i64, i1} %t, 0
127  %obit = extractvalue {i64, i1} %t, 1
128  store i64 %val, i64* %res
129  ret i1 %obit
130}
131
132define zeroext i1 @ssubo1.i32(i32 %v1, i32 %v2, i32* %res) {
133entry:
134; CHECK-LABEL:  ssubo1.i32
135; CHECK:        subs {{w[0-9]+}}, w0, w1
136; CHECK-NEXT:   cset {{w[0-9]+}}, vs
137  %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2)
138  %val = extractvalue {i32, i1} %t, 0
139  %obit = extractvalue {i32, i1} %t, 1
140  store i32 %val, i32* %res
141  ret i1 %obit
142}
143
144define zeroext i1 @ssubo2.i32(i32 %v1, i32* %res) {
145entry:
146; CHECK-LABEL:  ssubo2.i32
147; CHECK:        adds {{w[0-9]+}}, w0, #4
148; CHECK-NEXT:   cset {{w[0-9]+}}, vs
149  %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 -4)
150  %val = extractvalue {i32, i1} %t, 0
151  %obit = extractvalue {i32, i1} %t, 1
152  store i32 %val, i32* %res
153  ret i1 %obit
154}
155
156define zeroext i1 @ssubo.i64(i64 %v1, i64 %v2, i64* %res) {
157entry:
158; CHECK-LABEL:  ssubo.i64
159; CHECK:        subs {{x[0-9]+}}, x0, x1
160; CHECK-NEXT:   cset {{w[0-9]+}}, vs
161  %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2)
162  %val = extractvalue {i64, i1} %t, 0
163  %obit = extractvalue {i64, i1} %t, 1
164  store i64 %val, i64* %res
165  ret i1 %obit
166}
167
168define zeroext i1 @usubo.i32(i32 %v1, i32 %v2, i32* %res) {
169entry:
170; CHECK-LABEL:  usubo.i32
171; CHECK:        subs {{w[0-9]+}}, w0, w1
172; CHECK-NEXT:   cset {{w[0-9]+}}, lo
173  %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2)
174  %val = extractvalue {i32, i1} %t, 0
175  %obit = extractvalue {i32, i1} %t, 1
176  store i32 %val, i32* %res
177  ret i1 %obit
178}
179
180define zeroext i1 @usubo.i64(i64 %v1, i64 %v2, i64* %res) {
181entry:
182; CHECK-LABEL:  usubo.i64
183; CHECK:        subs {{x[0-9]+}}, x0, x1
184; CHECK-NEXT:   cset {{w[0-9]+}}, lo
185  %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2)
186  %val = extractvalue {i64, i1} %t, 0
187  %obit = extractvalue {i64, i1} %t, 1
188  store i64 %val, i64* %res
189  ret i1 %obit
190}
191
192define zeroext i1 @smulo.i32(i32 %v1, i32 %v2, i32* %res) {
193entry:
194; CHECK-LABEL:  smulo.i32
195; CHECK:        smull x[[MREG:[0-9]+]], w0, w1
196; CHECK-NEXT:   lsr x[[SREG:[0-9]+]], x[[MREG]], #32
197; CHECK-NEXT:   cmp w[[SREG]], w[[MREG]], asr #31
198; CHECK-NEXT:   cset {{w[0-9]+}}, ne
199  %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
200  %val = extractvalue {i32, i1} %t, 0
201  %obit = extractvalue {i32, i1} %t, 1
202  store i32 %val, i32* %res
203  ret i1 %obit
204}
205
206define zeroext i1 @smulo.i64(i64 %v1, i64 %v2, i64* %res) {
207entry:
208; CHECK-LABEL:  smulo.i64
209; CHECK:        mul [[MREG:x[0-9]+]], x0, x1
210; CHECK-NEXT:   smulh [[HREG:x[0-9]+]], x0, x1
211; CHECK-NEXT:   cmp [[HREG]], [[MREG]], asr #63
212; CHECK-NEXT:   cset {{w[0-9]+}}, ne
213  %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
214  %val = extractvalue {i64, i1} %t, 0
215  %obit = extractvalue {i64, i1} %t, 1
216  store i64 %val, i64* %res
217  ret i1 %obit
218}
219
220define zeroext i1 @smulo2.i64(i64 %v1, i64* %res) {
221entry:
222; CHECK-LABEL:  smulo2.i64
223; CHECK:        adds [[MREG:x[0-9]+]], x0, x0
224; CHECK-NEXT:   cset {{w[0-9]+}}, vs
225  %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 2)
226  %val = extractvalue {i64, i1} %t, 0
227  %obit = extractvalue {i64, i1} %t, 1
228  store i64 %val, i64* %res
229  ret i1 %obit
230}
231
232define zeroext i1 @umulo.i32(i32 %v1, i32 %v2, i32* %res) {
233entry:
234; CHECK-LABEL:  umulo.i32
235; CHECK:        umull [[MREG:x[0-9]+]], w0, w1
236; CHECK-NEXT:   cmp xzr, [[MREG]], lsr #32
237; CHECK-NEXT:   cset {{w[0-9]+}}, ne
238  %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
239  %val = extractvalue {i32, i1} %t, 0
240  %obit = extractvalue {i32, i1} %t, 1
241  store i32 %val, i32* %res
242  ret i1 %obit
243}
244
245define zeroext i1 @umulo.i64(i64 %v1, i64 %v2, i64* %res) {
246entry:
247; CHECK-LABEL:  umulo.i64
248; CHECK:        umulh [[MREG:x[0-9]+]], x0, x1
249; CHECK-NEXT:   cmp xzr, [[MREG]]
250; CHECK-NEXT:   cset {{w[0-9]+}}, ne
251  %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
252  %val = extractvalue {i64, i1} %t, 0
253  %obit = extractvalue {i64, i1} %t, 1
254  store i64 %val, i64* %res
255  ret i1 %obit
256}
257
258define zeroext i1 @umulo2.i64(i64 %v1, i64* %res) {
259entry:
260; CHECK-LABEL:  umulo2.i64
261; CHECK:        adds [[MREG:x[0-9]+]], x0, x0
262; CHECK-NEXT:   cset {{w[0-9]+}}, hs
263  %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 2)
264  %val = extractvalue {i64, i1} %t, 0
265  %obit = extractvalue {i64, i1} %t, 1
266  store i64 %val, i64* %res
267  ret i1 %obit
268}
269
270
271;
272; Check the use of the overflow bit in combination with a select instruction.
273;
274define i32 @saddo.select.i32(i32 %v1, i32 %v2) {
275entry:
276; CHECK-LABEL:  saddo.select.i32
277; CHECK:        cmn w0, w1
278; CHECK-NEXT:   csel w0, w0, w1, vs
279  %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2)
280  %obit = extractvalue {i32, i1} %t, 1
281  %ret = select i1 %obit, i32 %v1, i32 %v2
282  ret i32 %ret
283}
284
285define i64 @saddo.select.i64(i64 %v1, i64 %v2) {
286entry:
287; CHECK-LABEL:  saddo.select.i64
288; CHECK:        cmn x0, x1
289; CHECK-NEXT:   csel x0, x0, x1, vs
290  %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2)
291  %obit = extractvalue {i64, i1} %t, 1
292  %ret = select i1 %obit, i64 %v1, i64 %v2
293  ret i64 %ret
294}
295
296define i32 @uaddo.select.i32(i32 %v1, i32 %v2) {
297entry:
298; CHECK-LABEL:  uaddo.select.i32
299; CHECK:        cmn w0, w1
300; CHECK-NEXT:   csel w0, w0, w1, hs
301  %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)
302  %obit = extractvalue {i32, i1} %t, 1
303  %ret = select i1 %obit, i32 %v1, i32 %v2
304  ret i32 %ret
305}
306
307define i64 @uaddo.select.i64(i64 %v1, i64 %v2) {
308entry:
309; CHECK-LABEL:  uaddo.select.i64
310; CHECK:        cmn x0, x1
311; CHECK-NEXT:   csel x0, x0, x1, hs
312  %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2)
313  %obit = extractvalue {i64, i1} %t, 1
314  %ret = select i1 %obit, i64 %v1, i64 %v2
315  ret i64 %ret
316}
317
318define i32 @ssubo.select.i32(i32 %v1, i32 %v2) {
319entry:
320; CHECK-LABEL:  ssubo.select.i32
321; CHECK:        cmp w0, w1
322; CHECK-NEXT:   csel w0, w0, w1, vs
323  %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2)
324  %obit = extractvalue {i32, i1} %t, 1
325  %ret = select i1 %obit, i32 %v1, i32 %v2
326  ret i32 %ret
327}
328
329define i64 @ssubo.select.i64(i64 %v1, i64 %v2) {
330entry:
331; CHECK-LABEL:  ssubo.select.i64
332; CHECK:        cmp x0, x1
333; CHECK-NEXT:   csel x0, x0, x1, vs
334  %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2)
335  %obit = extractvalue {i64, i1} %t, 1
336  %ret = select i1 %obit, i64 %v1, i64 %v2
337  ret i64 %ret
338}
339
340define i32 @usubo.select.i32(i32 %v1, i32 %v2) {
341entry:
342; CHECK-LABEL:  usubo.select.i32
343; CHECK:        cmp w0, w1
344; CHECK-NEXT:   csel w0, w0, w1, lo
345  %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2)
346  %obit = extractvalue {i32, i1} %t, 1
347  %ret = select i1 %obit, i32 %v1, i32 %v2
348  ret i32 %ret
349}
350
351define i64 @usubo.select.i64(i64 %v1, i64 %v2) {
352entry:
353; CHECK-LABEL:  usubo.select.i64
354; CHECK:        cmp x0, x1
355; CHECK-NEXT:   csel x0, x0, x1, lo
356  %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2)
357  %obit = extractvalue {i64, i1} %t, 1
358  %ret = select i1 %obit, i64 %v1, i64 %v2
359  ret i64 %ret
360}
361
362define i32 @smulo.select.i32(i32 %v1, i32 %v2) {
363entry:
364; CHECK-LABEL:  smulo.select.i32
365; CHECK:        smull   x[[MREG:[0-9]+]], w0, w1
366; CHECK-NEXT:   lsr     x[[SREG:[0-9]+]], x[[MREG]], #32
367; CHECK-NEXT:   cmp     w[[SREG]], w[[MREG]], asr #31
368; CHECK-NEXT:   csel    w0, w0, w1, ne
369  %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
370  %obit = extractvalue {i32, i1} %t, 1
371  %ret = select i1 %obit, i32 %v1, i32 %v2
372  ret i32 %ret
373}
374
375define i64 @smulo.select.i64(i64 %v1, i64 %v2) {
376entry:
377; CHECK-LABEL:  smulo.select.i64
378; CHECK:        mul     [[MREG:x[0-9]+]], x0, x1
379; CHECK-NEXT:   smulh   [[HREG:x[0-9]+]], x0, x1
380; CHECK-NEXT:   cmp     [[HREG]], [[MREG]], asr #63
381; CHECK-NEXT:   csel    x0, x0, x1, ne
382  %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
383  %obit = extractvalue {i64, i1} %t, 1
384  %ret = select i1 %obit, i64 %v1, i64 %v2
385  ret i64 %ret
386}
387
388define i32 @umulo.select.i32(i32 %v1, i32 %v2) {
389entry:
390; CHECK-LABEL:  umulo.select.i32
391; CHECK:        umull   [[MREG:x[0-9]+]], w0, w1
392; CHECK-NEXT:   cmp     xzr, [[MREG]], lsr #32
393; CHECK-NEXT:   csel    w0, w0, w1, ne
394  %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
395  %obit = extractvalue {i32, i1} %t, 1
396  %ret = select i1 %obit, i32 %v1, i32 %v2
397  ret i32 %ret
398}
399
400define i64 @umulo.select.i64(i64 %v1, i64 %v2) {
401entry:
402; CHECK-LABEL:  umulo.select.i64
403; CHECK:        umulh   [[MREG:x[0-9]+]], x0, x1
404; CHECK-NEXT:   cmp     xzr, [[MREG]]
405; CHECK-NEXT:   csel    x0, x0, x1, ne
406  %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
407  %obit = extractvalue {i64, i1} %t, 1
408  %ret = select i1 %obit, i64 %v1, i64 %v2
409  ret i64 %ret
410}
411
412
413;
414; Check the use of the overflow bit in combination with a branch instruction.
415;
416define zeroext i1 @saddo.br.i32(i32 %v1, i32 %v2) {
417entry:
418; CHECK-LABEL:  saddo.br.i32
419; CHECK:        cmn w0, w1
420; CHECK-NEXT:   b.vc
421  %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2)
422  %val = extractvalue {i32, i1} %t, 0
423  %obit = extractvalue {i32, i1} %t, 1
424  br i1 %obit, label %overflow, label %continue
425
426overflow:
427  ret i1 false
428
429continue:
430  ret i1 true
431}
432
433define zeroext i1 @saddo.br.i64(i64 %v1, i64 %v2) {
434entry:
435; CHECK-LABEL:  saddo.br.i64
436; CHECK:        cmn x0, x1
437; CHECK-NEXT:   b.vc
438  %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2)
439  %val = extractvalue {i64, i1} %t, 0
440  %obit = extractvalue {i64, i1} %t, 1
441  br i1 %obit, label %overflow, label %continue
442
443overflow:
444  ret i1 false
445
446continue:
447  ret i1 true
448}
449
450define zeroext i1 @uaddo.br.i32(i32 %v1, i32 %v2) {
451entry:
452; CHECK-LABEL:  uaddo.br.i32
453; CHECK:        cmn w0, w1
454; CHECK-NEXT:   b.lo
455  %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)
456  %val = extractvalue {i32, i1} %t, 0
457  %obit = extractvalue {i32, i1} %t, 1
458  br i1 %obit, label %overflow, label %continue
459
460overflow:
461  ret i1 false
462
463continue:
464  ret i1 true
465}
466
467define zeroext i1 @uaddo.br.i64(i64 %v1, i64 %v2) {
468entry:
469; CHECK-LABEL:  uaddo.br.i64
470; CHECK:        cmn x0, x1
471; CHECK-NEXT:   b.lo
472  %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2)
473  %val = extractvalue {i64, i1} %t, 0
474  %obit = extractvalue {i64, i1} %t, 1
475  br i1 %obit, label %overflow, label %continue
476
477overflow:
478  ret i1 false
479
480continue:
481  ret i1 true
482}
483
484define zeroext i1 @ssubo.br.i32(i32 %v1, i32 %v2) {
485entry:
486; CHECK-LABEL:  ssubo.br.i32
487; CHECK:        cmp w0, w1
488; CHECK-NEXT:   b.vc
489  %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2)
490  %val = extractvalue {i32, i1} %t, 0
491  %obit = extractvalue {i32, i1} %t, 1
492  br i1 %obit, label %overflow, label %continue
493
494overflow:
495  ret i1 false
496
497continue:
498  ret i1 true
499}
500
501define zeroext i1 @ssubo.br.i64(i64 %v1, i64 %v2) {
502entry:
503; CHECK-LABEL:  ssubo.br.i64
504; CHECK:        cmp x0, x1
505; CHECK-NEXT:   b.vc
506  %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2)
507  %val = extractvalue {i64, i1} %t, 0
508  %obit = extractvalue {i64, i1} %t, 1
509  br i1 %obit, label %overflow, label %continue
510
511overflow:
512  ret i1 false
513
514continue:
515  ret i1 true
516}
517
518define zeroext i1 @usubo.br.i32(i32 %v1, i32 %v2) {
519entry:
520; CHECK-LABEL:  usubo.br.i32
521; CHECK:        cmp w0, w1
522; CHECK-NEXT:   b.hs
523  %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2)
524  %val = extractvalue {i32, i1} %t, 0
525  %obit = extractvalue {i32, i1} %t, 1
526  br i1 %obit, label %overflow, label %continue
527
528overflow:
529  ret i1 false
530
531continue:
532  ret i1 true
533}
534
535define zeroext i1 @usubo.br.i64(i64 %v1, i64 %v2) {
536entry:
537; CHECK-LABEL:  usubo.br.i64
538; CHECK:        cmp x0, x1
539; CHECK-NEXT:   b.hs
540  %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2)
541  %val = extractvalue {i64, i1} %t, 0
542  %obit = extractvalue {i64, i1} %t, 1
543  br i1 %obit, label %overflow, label %continue
544
545overflow:
546  ret i1 false
547
548continue:
549  ret i1 true
550}
551
552define zeroext i1 @smulo.br.i32(i32 %v1, i32 %v2) {
553entry:
554; CHECK-LABEL:  smulo.br.i32
555; CHECK:        smull   x[[MREG:[0-9]+]], w0, w1
556; CHECK-NEXT:   lsr     x[[SREG:[0-9]+]], x8, #32
557; CHECK-NEXT:   cmp     w[[SREG]], w[[MREG]], asr #31
558; CHECK-NEXT:   b.eq
559  %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
560  %val = extractvalue {i32, i1} %t, 0
561  %obit = extractvalue {i32, i1} %t, 1
562  br i1 %obit, label %overflow, label %continue
563
564overflow:
565  ret i1 false
566
567continue:
568  ret i1 true
569}
570
571define zeroext i1 @smulo.br.i64(i64 %v1, i64 %v2) {
572entry:
573; CHECK-LABEL:  smulo.br.i64
574; CHECK:        mul     [[MREG:x[0-9]+]], x0, x1
575; CHECK-NEXT:   smulh   [[HREG:x[0-9]+]], x0, x1
576; CHECK-NEXT:   cmp     [[HREG]], [[MREG]], asr #63
577; CHECK-NEXT:   b.eq
578  %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
579  %val = extractvalue {i64, i1} %t, 0
580  %obit = extractvalue {i64, i1} %t, 1
581  br i1 %obit, label %overflow, label %continue
582
583overflow:
584  ret i1 false
585
586continue:
587  ret i1 true
588}
589
590define zeroext i1 @smulo2.br.i64(i64 %v1) {
591entry:
592; CHECK-LABEL:  smulo2.br.i64
593; CHECK:        cmn  x0, x0
594; CHECK-NEXT:   b.vc
595  %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 2)
596  %val = extractvalue {i64, i1} %t, 0
597  %obit = extractvalue {i64, i1} %t, 1
598  br i1 %obit, label %overflow, label %continue
599
600overflow:
601  ret i1 false
602
603continue:
604  ret i1 true
605}
606
607define zeroext i1 @umulo.br.i32(i32 %v1, i32 %v2) {
608entry:
609; CHECK-LABEL:  umulo.br.i32
610; CHECK:        umull   [[MREG:x[0-9]+]], w0, w1
611; CHECK-NEXT:   cmp     xzr, [[MREG]], lsr #32
612; CHECK-NEXT:   b.eq
613  %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
614  %val = extractvalue {i32, i1} %t, 0
615  %obit = extractvalue {i32, i1} %t, 1
616  br i1 %obit, label %overflow, label %continue
617
618overflow:
619  ret i1 false
620
621continue:
622  ret i1 true
623}
624
625define zeroext i1 @umulo.br.i64(i64 %v1, i64 %v2) {
626entry:
627; CHECK-LABEL:  umulo.br.i64
628; CHECK:        umulh   [[REG:x[0-9]+]], x0, x1
629; CHECK-NEXT:   {{cbz|cmp}}
630  %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
631  %val = extractvalue {i64, i1} %t, 0
632  %obit = extractvalue {i64, i1} %t, 1
633  br i1 %obit, label %overflow, label %continue
634
635overflow:
636  ret i1 false
637
638continue:
639  ret i1 true
640}
641
642define zeroext i1 @umulo2.br.i64(i64 %v1) {
643entry:
644; CHECK-LABEL:  umulo2.br.i64
645; CHECK:        cmn  x0, x0
646; CHECK-NEXT:   b.lo
647  %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 2)
648  %val = extractvalue {i64, i1} %t, 0
649  %obit = extractvalue {i64, i1} %t, 1
650  br i1 %obit, label %overflow, label %continue
651
652overflow:
653  ret i1 false
654
655continue:
656  ret i1 true
657}
658
659declare {i32, i1} @llvm.sadd.with.overflow.i32(i32, i32) nounwind readnone
660declare {i64, i1} @llvm.sadd.with.overflow.i64(i64, i64) nounwind readnone
661declare {i32, i1} @llvm.uadd.with.overflow.i32(i32, i32) nounwind readnone
662declare {i64, i1} @llvm.uadd.with.overflow.i64(i64, i64) nounwind readnone
663declare {i32, i1} @llvm.ssub.with.overflow.i32(i32, i32) nounwind readnone
664declare {i64, i1} @llvm.ssub.with.overflow.i64(i64, i64) nounwind readnone
665declare {i32, i1} @llvm.usub.with.overflow.i32(i32, i32) nounwind readnone
666declare {i64, i1} @llvm.usub.with.overflow.i64(i64, i64) nounwind readnone
667declare {i32, i1} @llvm.smul.with.overflow.i32(i32, i32) nounwind readnone
668declare {i64, i1} @llvm.smul.with.overflow.i64(i64, i64) nounwind readnone
669declare {i32, i1} @llvm.umul.with.overflow.i32(i32, i32) nounwind readnone
670declare {i64, i1} @llvm.umul.with.overflow.i64(i64, i64) nounwind readnone
671
672