xref: /llvm-project/llvm/test/CodeGen/AArch64/arm64-xaluo.ll (revision deefe3fbc93b3bdc77fbaf718403a45dae983d12)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=arm64-eabi -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK,SDAG
3; RUN: llc < %s -mtriple=arm64-eabi -fast-isel -fast-isel-abort=1 -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK,FAST
4; RUN: llc < %s -mtriple=arm64-eabi -global-isel -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK,GISEL
5
6;
7; Get the actual value of the overflow bit.
8;
9define zeroext i1 @saddo1.i32(i32 %v1, i32 %v2, ptr %res) {
10; SDAG-LABEL: saddo1.i32:
11; SDAG:       // %bb.0: // %entry
12; SDAG-NEXT:    adds w8, w0, w1
13; SDAG-NEXT:    cset w0, vs
14; SDAG-NEXT:    str w8, [x2]
15; SDAG-NEXT:    ret
16;
17; FAST-LABEL: saddo1.i32:
18; FAST:       // %bb.0: // %entry
19; FAST-NEXT:    adds w8, w0, w1
20; FAST-NEXT:    cset w9, vs
21; FAST-NEXT:    str w8, [x2]
22; FAST-NEXT:    and w0, w9, #0x1
23; FAST-NEXT:    ret
24;
25; GISEL-LABEL: saddo1.i32:
26; GISEL:       // %bb.0: // %entry
27; GISEL-NEXT:    adds w8, w0, w1
28; GISEL-NEXT:    cset w0, vs
29; GISEL-NEXT:    str w8, [x2]
30; GISEL-NEXT:    ret
31entry:
32  %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2)
33  %val = extractvalue {i32, i1} %t, 0
34  %obit = extractvalue {i32, i1} %t, 1
35  store i32 %val, ptr %res
36  ret i1 %obit
37}
38
39; Test the immediate version.
40define zeroext i1 @saddo2.i32(i32 %v1, ptr %res) {
41; SDAG-LABEL: saddo2.i32:
42; SDAG:       // %bb.0: // %entry
43; SDAG-NEXT:    adds w8, w0, #4
44; SDAG-NEXT:    cset w0, vs
45; SDAG-NEXT:    str w8, [x1]
46; SDAG-NEXT:    ret
47;
48; FAST-LABEL: saddo2.i32:
49; FAST:       // %bb.0: // %entry
50; FAST-NEXT:    adds w8, w0, #4
51; FAST-NEXT:    cset w9, vs
52; FAST-NEXT:    str w8, [x1]
53; FAST-NEXT:    and w0, w9, #0x1
54; FAST-NEXT:    ret
55;
56; GISEL-LABEL: saddo2.i32:
57; GISEL:       // %bb.0: // %entry
58; GISEL-NEXT:    adds w8, w0, #4
59; GISEL-NEXT:    cset w0, vs
60; GISEL-NEXT:    str w8, [x1]
61; GISEL-NEXT:    ret
62entry:
63  %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 4)
64  %val = extractvalue {i32, i1} %t, 0
65  %obit = extractvalue {i32, i1} %t, 1
66  store i32 %val, ptr %res
67  ret i1 %obit
68}
69
70; Test negative immediates.
71define zeroext i1 @saddo3.i32(i32 %v1, ptr %res) {
72; SDAG-LABEL: saddo3.i32:
73; SDAG:       // %bb.0: // %entry
74; SDAG-NEXT:    subs w8, w0, #4
75; SDAG-NEXT:    cset w0, vs
76; SDAG-NEXT:    str w8, [x1]
77; SDAG-NEXT:    ret
78;
79; FAST-LABEL: saddo3.i32:
80; FAST:       // %bb.0: // %entry
81; FAST-NEXT:    subs w8, w0, #4
82; FAST-NEXT:    cset w9, vs
83; FAST-NEXT:    str w8, [x1]
84; FAST-NEXT:    and w0, w9, #0x1
85; FAST-NEXT:    ret
86;
87; GISEL-LABEL: saddo3.i32:
88; GISEL:       // %bb.0: // %entry
89; GISEL-NEXT:    subs w8, w0, #4
90; GISEL-NEXT:    cset w0, vs
91; GISEL-NEXT:    str w8, [x1]
92; GISEL-NEXT:    ret
93entry:
94  %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 -4)
95  %val = extractvalue {i32, i1} %t, 0
96  %obit = extractvalue {i32, i1} %t, 1
97  store i32 %val, ptr %res
98  ret i1 %obit
99}
100
101; Test immediates that are too large to be encoded.
102define zeroext i1 @saddo4.i32(i32 %v1, ptr %res) {
103; SDAG-LABEL: saddo4.i32:
104; SDAG:       // %bb.0: // %entry
105; SDAG-NEXT:    mov w8, #16777215 // =0xffffff
106; SDAG-NEXT:    adds w8, w0, w8
107; SDAG-NEXT:    cset w0, vs
108; SDAG-NEXT:    str w8, [x1]
109; SDAG-NEXT:    ret
110;
111; FAST-LABEL: saddo4.i32:
112; FAST:       // %bb.0: // %entry
113; FAST-NEXT:    mov w8, #16777215 // =0xffffff
114; FAST-NEXT:    adds w8, w0, w8
115; FAST-NEXT:    cset w9, vs
116; FAST-NEXT:    str w8, [x1]
117; FAST-NEXT:    and w0, w9, #0x1
118; FAST-NEXT:    ret
119;
120; GISEL-LABEL: saddo4.i32:
121; GISEL:       // %bb.0: // %entry
122; GISEL-NEXT:    mov w8, #16777215 // =0xffffff
123; GISEL-NEXT:    adds w8, w0, w8
124; GISEL-NEXT:    cset w0, vs
125; GISEL-NEXT:    str w8, [x1]
126; GISEL-NEXT:    ret
127entry:
128  %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 16777215)
129  %val = extractvalue {i32, i1} %t, 0
130  %obit = extractvalue {i32, i1} %t, 1
131  store i32 %val, ptr %res
132  ret i1 %obit
133}
134
135; Test shift folding.
136define zeroext i1 @saddo5.i32(i32 %v1, i32 %v2, ptr %res) {
137; SDAG-LABEL: saddo5.i32:
138; SDAG:       // %bb.0: // %entry
139; SDAG-NEXT:    adds w8, w0, w1, lsl #16
140; SDAG-NEXT:    cset w0, vs
141; SDAG-NEXT:    str w8, [x2]
142; SDAG-NEXT:    ret
143;
144; FAST-LABEL: saddo5.i32:
145; FAST:       // %bb.0: // %entry
146; FAST-NEXT:    adds w8, w0, w1, lsl #16
147; FAST-NEXT:    cset w9, vs
148; FAST-NEXT:    and w0, w9, #0x1
149; FAST-NEXT:    str w8, [x2]
150; FAST-NEXT:    ret
151;
152; GISEL-LABEL: saddo5.i32:
153; GISEL:       // %bb.0: // %entry
154; GISEL-NEXT:    adds w8, w0, w1, lsl #16
155; GISEL-NEXT:    cset w0, vs
156; GISEL-NEXT:    str w8, [x2]
157; GISEL-NEXT:    ret
158entry:
159  %lsl = shl i32 %v2, 16
160  %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %lsl)
161  %val = extractvalue {i32, i1} %t, 0
162  %obit = extractvalue {i32, i1} %t, 1
163  store i32 %val, ptr %res
164  ret i1 %obit
165}
166
167define zeroext i1 @saddo1.i64(i64 %v1, i64 %v2, ptr %res) {
168; SDAG-LABEL: saddo1.i64:
169; SDAG:       // %bb.0: // %entry
170; SDAG-NEXT:    adds x8, x0, x1
171; SDAG-NEXT:    cset w0, vs
172; SDAG-NEXT:    str x8, [x2]
173; SDAG-NEXT:    ret
174;
175; FAST-LABEL: saddo1.i64:
176; FAST:       // %bb.0: // %entry
177; FAST-NEXT:    adds x8, x0, x1
178; FAST-NEXT:    cset w9, vs
179; FAST-NEXT:    str x8, [x2]
180; FAST-NEXT:    and w0, w9, #0x1
181; FAST-NEXT:    ret
182;
183; GISEL-LABEL: saddo1.i64:
184; GISEL:       // %bb.0: // %entry
185; GISEL-NEXT:    adds x8, x0, x1
186; GISEL-NEXT:    cset w0, vs
187; GISEL-NEXT:    str x8, [x2]
188; GISEL-NEXT:    ret
189entry:
190  %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2)
191  %val = extractvalue {i64, i1} %t, 0
192  %obit = extractvalue {i64, i1} %t, 1
193  store i64 %val, ptr %res
194  ret i1 %obit
195}
196
197define zeroext i1 @saddo2.i64(i64 %v1, ptr %res) {
198; SDAG-LABEL: saddo2.i64:
199; SDAG:       // %bb.0: // %entry
200; SDAG-NEXT:    adds x8, x0, #4
201; SDAG-NEXT:    cset w0, vs
202; SDAG-NEXT:    str x8, [x1]
203; SDAG-NEXT:    ret
204;
205; FAST-LABEL: saddo2.i64:
206; FAST:       // %bb.0: // %entry
207; FAST-NEXT:    adds x8, x0, #4
208; FAST-NEXT:    cset w9, vs
209; FAST-NEXT:    str x8, [x1]
210; FAST-NEXT:    and w0, w9, #0x1
211; FAST-NEXT:    ret
212;
213; GISEL-LABEL: saddo2.i64:
214; GISEL:       // %bb.0: // %entry
215; GISEL-NEXT:    adds x8, x0, #4
216; GISEL-NEXT:    cset w0, vs
217; GISEL-NEXT:    str x8, [x1]
218; GISEL-NEXT:    ret
219entry:
220  %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 4)
221  %val = extractvalue {i64, i1} %t, 0
222  %obit = extractvalue {i64, i1} %t, 1
223  store i64 %val, ptr %res
224  ret i1 %obit
225}
226
227define zeroext i1 @saddo3.i64(i64 %v1, ptr %res) {
228; SDAG-LABEL: saddo3.i64:
229; SDAG:       // %bb.0: // %entry
230; SDAG-NEXT:    subs x8, x0, #4
231; SDAG-NEXT:    cset w0, vs
232; SDAG-NEXT:    str x8, [x1]
233; SDAG-NEXT:    ret
234;
235; FAST-LABEL: saddo3.i64:
236; FAST:       // %bb.0: // %entry
237; FAST-NEXT:    subs x8, x0, #4
238; FAST-NEXT:    cset w9, vs
239; FAST-NEXT:    str x8, [x1]
240; FAST-NEXT:    and w0, w9, #0x1
241; FAST-NEXT:    ret
242;
243; GISEL-LABEL: saddo3.i64:
244; GISEL:       // %bb.0: // %entry
245; GISEL-NEXT:    subs x8, x0, #4
246; GISEL-NEXT:    cset w0, vs
247; GISEL-NEXT:    str x8, [x1]
248; GISEL-NEXT:    ret
249entry:
250  %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 -4)
251  %val = extractvalue {i64, i1} %t, 0
252  %obit = extractvalue {i64, i1} %t, 1
253  store i64 %val, ptr %res
254  ret i1 %obit
255}
256
257define zeroext i1 @uaddo.i32(i32 %v1, i32 %v2, ptr %res) {
258; SDAG-LABEL: uaddo.i32:
259; SDAG:       // %bb.0: // %entry
260; SDAG-NEXT:    adds w8, w0, w1
261; SDAG-NEXT:    cset w0, hs
262; SDAG-NEXT:    str w8, [x2]
263; SDAG-NEXT:    ret
264;
265; FAST-LABEL: uaddo.i32:
266; FAST:       // %bb.0: // %entry
267; FAST-NEXT:    adds w8, w0, w1
268; FAST-NEXT:    cset w9, hs
269; FAST-NEXT:    str w8, [x2]
270; FAST-NEXT:    and w0, w9, #0x1
271; FAST-NEXT:    ret
272;
273; GISEL-LABEL: uaddo.i32:
274; GISEL:       // %bb.0: // %entry
275; GISEL-NEXT:    adds w8, w0, w1
276; GISEL-NEXT:    cset w0, hs
277; GISEL-NEXT:    str w8, [x2]
278; GISEL-NEXT:    ret
279entry:
280  %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)
281  %val = extractvalue {i32, i1} %t, 0
282  %obit = extractvalue {i32, i1} %t, 1
283  store i32 %val, ptr %res
284  ret i1 %obit
285}
286
287define zeroext i1 @uaddo.i64(i64 %v1, i64 %v2, ptr %res) {
288; SDAG-LABEL: uaddo.i64:
289; SDAG:       // %bb.0: // %entry
290; SDAG-NEXT:    adds x8, x0, x1
291; SDAG-NEXT:    cset w0, hs
292; SDAG-NEXT:    str x8, [x2]
293; SDAG-NEXT:    ret
294;
295; FAST-LABEL: uaddo.i64:
296; FAST:       // %bb.0: // %entry
297; FAST-NEXT:    adds x8, x0, x1
298; FAST-NEXT:    cset w9, hs
299; FAST-NEXT:    str x8, [x2]
300; FAST-NEXT:    and w0, w9, #0x1
301; FAST-NEXT:    ret
302;
303; GISEL-LABEL: uaddo.i64:
304; GISEL:       // %bb.0: // %entry
305; GISEL-NEXT:    adds x8, x0, x1
306; GISEL-NEXT:    cset w0, hs
307; GISEL-NEXT:    str x8, [x2]
308; GISEL-NEXT:    ret
309entry:
310  %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2)
311  %val = extractvalue {i64, i1} %t, 0
312  %obit = extractvalue {i64, i1} %t, 1
313  store i64 %val, ptr %res
314  ret i1 %obit
315}
316
317define zeroext i1 @ssubo1.i32(i32 %v1, i32 %v2, ptr %res) {
318; SDAG-LABEL: ssubo1.i32:
319; SDAG:       // %bb.0: // %entry
320; SDAG-NEXT:    subs w8, w0, w1
321; SDAG-NEXT:    cset w0, vs
322; SDAG-NEXT:    str w8, [x2]
323; SDAG-NEXT:    ret
324;
325; FAST-LABEL: ssubo1.i32:
326; FAST:       // %bb.0: // %entry
327; FAST-NEXT:    subs w8, w0, w1
328; FAST-NEXT:    cset w9, vs
329; FAST-NEXT:    str w8, [x2]
330; FAST-NEXT:    and w0, w9, #0x1
331; FAST-NEXT:    ret
332;
333; GISEL-LABEL: ssubo1.i32:
334; GISEL:       // %bb.0: // %entry
335; GISEL-NEXT:    subs w8, w0, w1
336; GISEL-NEXT:    cset w0, vs
337; GISEL-NEXT:    str w8, [x2]
338; GISEL-NEXT:    ret
339entry:
340  %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2)
341  %val = extractvalue {i32, i1} %t, 0
342  %obit = extractvalue {i32, i1} %t, 1
343  store i32 %val, ptr %res
344  ret i1 %obit
345}
346
347define zeroext i1 @ssubo2.i32(i32 %v1, ptr %res) {
348; SDAG-LABEL: ssubo2.i32:
349; SDAG:       // %bb.0: // %entry
350; SDAG-NEXT:    adds w8, w0, #4
351; SDAG-NEXT:    cset w0, vs
352; SDAG-NEXT:    str w8, [x1]
353; SDAG-NEXT:    ret
354;
355; FAST-LABEL: ssubo2.i32:
356; FAST:       // %bb.0: // %entry
357; FAST-NEXT:    adds w8, w0, #4
358; FAST-NEXT:    cset w9, vs
359; FAST-NEXT:    str w8, [x1]
360; FAST-NEXT:    and w0, w9, #0x1
361; FAST-NEXT:    ret
362;
363; GISEL-LABEL: ssubo2.i32:
364; GISEL:       // %bb.0: // %entry
365; GISEL-NEXT:    adds w8, w0, #4
366; GISEL-NEXT:    cset w0, vs
367; GISEL-NEXT:    str w8, [x1]
368; GISEL-NEXT:    ret
369entry:
370  %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 -4)
371  %val = extractvalue {i32, i1} %t, 0
372  %obit = extractvalue {i32, i1} %t, 1
373  store i32 %val, ptr %res
374  ret i1 %obit
375}
376
377define zeroext i1 @ssubo.i64(i64 %v1, i64 %v2, ptr %res) {
378; SDAG-LABEL: ssubo.i64:
379; SDAG:       // %bb.0: // %entry
380; SDAG-NEXT:    subs x8, x0, x1
381; SDAG-NEXT:    cset w0, vs
382; SDAG-NEXT:    str x8, [x2]
383; SDAG-NEXT:    ret
384;
385; FAST-LABEL: ssubo.i64:
386; FAST:       // %bb.0: // %entry
387; FAST-NEXT:    subs x8, x0, x1
388; FAST-NEXT:    cset w9, vs
389; FAST-NEXT:    str x8, [x2]
390; FAST-NEXT:    and w0, w9, #0x1
391; FAST-NEXT:    ret
392;
393; GISEL-LABEL: ssubo.i64:
394; GISEL:       // %bb.0: // %entry
395; GISEL-NEXT:    subs x8, x0, x1
396; GISEL-NEXT:    cset w0, vs
397; GISEL-NEXT:    str x8, [x2]
398; GISEL-NEXT:    ret
399entry:
400  %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2)
401  %val = extractvalue {i64, i1} %t, 0
402  %obit = extractvalue {i64, i1} %t, 1
403  store i64 %val, ptr %res
404  ret i1 %obit
405}
406
407define zeroext i1 @usubo.i32(i32 %v1, i32 %v2, ptr %res) {
408; SDAG-LABEL: usubo.i32:
409; SDAG:       // %bb.0: // %entry
410; SDAG-NEXT:    subs w8, w0, w1
411; SDAG-NEXT:    cset w0, lo
412; SDAG-NEXT:    str w8, [x2]
413; SDAG-NEXT:    ret
414;
415; FAST-LABEL: usubo.i32:
416; FAST:       // %bb.0: // %entry
417; FAST-NEXT:    subs w8, w0, w1
418; FAST-NEXT:    cset w9, lo
419; FAST-NEXT:    str w8, [x2]
420; FAST-NEXT:    and w0, w9, #0x1
421; FAST-NEXT:    ret
422;
423; GISEL-LABEL: usubo.i32:
424; GISEL:       // %bb.0: // %entry
425; GISEL-NEXT:    subs w8, w0, w1
426; GISEL-NEXT:    cset w0, lo
427; GISEL-NEXT:    str w8, [x2]
428; GISEL-NEXT:    ret
429entry:
430  %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2)
431  %val = extractvalue {i32, i1} %t, 0
432  %obit = extractvalue {i32, i1} %t, 1
433  store i32 %val, ptr %res
434  ret i1 %obit
435}
436
437define zeroext i1 @usubo.i64(i64 %v1, i64 %v2, ptr %res) {
438; SDAG-LABEL: usubo.i64:
439; SDAG:       // %bb.0: // %entry
440; SDAG-NEXT:    subs x8, x0, x1
441; SDAG-NEXT:    cset w0, lo
442; SDAG-NEXT:    str x8, [x2]
443; SDAG-NEXT:    ret
444;
445; FAST-LABEL: usubo.i64:
446; FAST:       // %bb.0: // %entry
447; FAST-NEXT:    subs x8, x0, x1
448; FAST-NEXT:    cset w9, lo
449; FAST-NEXT:    str x8, [x2]
450; FAST-NEXT:    and w0, w9, #0x1
451; FAST-NEXT:    ret
452;
453; GISEL-LABEL: usubo.i64:
454; GISEL:       // %bb.0: // %entry
455; GISEL-NEXT:    subs x8, x0, x1
456; GISEL-NEXT:    cset w0, lo
457; GISEL-NEXT:    str x8, [x2]
458; GISEL-NEXT:    ret
459entry:
460  %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2)
461  %val = extractvalue {i64, i1} %t, 0
462  %obit = extractvalue {i64, i1} %t, 1
463  store i64 %val, ptr %res
464  ret i1 %obit
465}
466
467define zeroext i1 @smulo.i32(i32 %v1, i32 %v2, ptr %res) {
468; SDAG-LABEL: smulo.i32:
469; SDAG:       // %bb.0: // %entry
470; SDAG-NEXT:    smull x8, w0, w1
471; SDAG-NEXT:    cmp x8, w8, sxtw
472; SDAG-NEXT:    str w8, [x2]
473; SDAG-NEXT:    cset w0, ne
474; SDAG-NEXT:    ret
475;
476; FAST-LABEL: smulo.i32:
477; FAST:       // %bb.0: // %entry
478; FAST-NEXT:    smull x8, w0, w1
479; FAST-NEXT:    cmp x8, w8, sxtw
480; FAST-NEXT:    str w8, [x2]
481; FAST-NEXT:    cset w9, ne
482; FAST-NEXT:    and w0, w9, #0x1
483; FAST-NEXT:    ret
484;
485; GISEL-LABEL: smulo.i32:
486; GISEL:       // %bb.0: // %entry
487; GISEL-NEXT:    smull x8, w0, w1
488; GISEL-NEXT:    mul w9, w0, w1
489; GISEL-NEXT:    asr x8, x8, #32
490; GISEL-NEXT:    str w9, [x2]
491; GISEL-NEXT:    cmp w8, w9, asr #31
492; GISEL-NEXT:    cset w0, ne
493; GISEL-NEXT:    ret
494entry:
495  %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
496  %val = extractvalue {i32, i1} %t, 0
497  %obit = extractvalue {i32, i1} %t, 1
498  store i32 %val, ptr %res
499  ret i1 %obit
500}
501
502define zeroext i1 @smulo.i64(i64 %v1, i64 %v2, ptr %res) {
503; SDAG-LABEL: smulo.i64:
504; SDAG:       // %bb.0: // %entry
505; SDAG-NEXT:    mul x8, x0, x1
506; SDAG-NEXT:    smulh x9, x0, x1
507; SDAG-NEXT:    str x8, [x2]
508; SDAG-NEXT:    cmp x9, x8, asr #63
509; SDAG-NEXT:    cset w0, ne
510; SDAG-NEXT:    ret
511;
512; FAST-LABEL: smulo.i64:
513; FAST:       // %bb.0: // %entry
514; FAST-NEXT:    mul x8, x0, x1
515; FAST-NEXT:    smulh x9, x0, x1
516; FAST-NEXT:    str x8, [x2]
517; FAST-NEXT:    cmp x9, x8, asr #63
518; FAST-NEXT:    cset w9, ne
519; FAST-NEXT:    and w0, w9, #0x1
520; FAST-NEXT:    ret
521;
522; GISEL-LABEL: smulo.i64:
523; GISEL:       // %bb.0: // %entry
524; GISEL-NEXT:    smulh x8, x0, x1
525; GISEL-NEXT:    mul x9, x0, x1
526; GISEL-NEXT:    cmp x8, x9, asr #63
527; GISEL-NEXT:    str x9, [x2]
528; GISEL-NEXT:    cset w0, ne
529; GISEL-NEXT:    ret
530entry:
531  %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
532  %val = extractvalue {i64, i1} %t, 0
533  %obit = extractvalue {i64, i1} %t, 1
534  store i64 %val, ptr %res
535  ret i1 %obit
536}
537
538define zeroext i1 @smulo2.i64(i64 %v1, ptr %res) {
539; SDAG-LABEL: smulo2.i64:
540; SDAG:       // %bb.0: // %entry
541; SDAG-NEXT:    adds x8, x0, x0
542; SDAG-NEXT:    cset w0, vs
543; SDAG-NEXT:    str x8, [x1]
544; SDAG-NEXT:    ret
545;
546; FAST-LABEL: smulo2.i64:
547; FAST:       // %bb.0: // %entry
548; FAST-NEXT:    adds x8, x0, x0
549; FAST-NEXT:    cset w9, vs
550; FAST-NEXT:    str x8, [x1]
551; FAST-NEXT:    and w0, w9, #0x1
552; FAST-NEXT:    ret
553;
554; GISEL-LABEL: smulo2.i64:
555; GISEL:       // %bb.0: // %entry
556; GISEL-NEXT:    adds x8, x0, x0
557; GISEL-NEXT:    cset w0, vs
558; GISEL-NEXT:    str x8, [x1]
559; GISEL-NEXT:    ret
560entry:
561  %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 2)
562  %val = extractvalue {i64, i1} %t, 0
563  %obit = extractvalue {i64, i1} %t, 1
564  store i64 %val, ptr %res
565  ret i1 %obit
566}
567
568define zeroext i1 @umulo.i32(i32 %v1, i32 %v2, ptr %res) {
569; SDAG-LABEL: umulo.i32:
570; SDAG:       // %bb.0: // %entry
571; SDAG-NEXT:    umull x8, w0, w1
572; SDAG-NEXT:    tst x8, #0xffffffff00000000
573; SDAG-NEXT:    str w8, [x2]
574; SDAG-NEXT:    cset w0, ne
575; SDAG-NEXT:    ret
576;
577; FAST-LABEL: umulo.i32:
578; FAST:       // %bb.0: // %entry
579; FAST-NEXT:    umull x8, w0, w1
580; FAST-NEXT:    tst x8, #0xffffffff00000000
581; FAST-NEXT:    str w8, [x2]
582; FAST-NEXT:    cset w9, ne
583; FAST-NEXT:    and w0, w9, #0x1
584; FAST-NEXT:    ret
585;
586; GISEL-LABEL: umulo.i32:
587; GISEL:       // %bb.0: // %entry
588; GISEL-NEXT:    umull x8, w0, w1
589; GISEL-NEXT:    mul w9, w0, w1
590; GISEL-NEXT:    lsr x8, x8, #32
591; GISEL-NEXT:    str w9, [x2]
592; GISEL-NEXT:    cmp w8, #0
593; GISEL-NEXT:    cset w0, ne
594; GISEL-NEXT:    ret
595entry:
596  %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
597  %val = extractvalue {i32, i1} %t, 0
598  %obit = extractvalue {i32, i1} %t, 1
599  store i32 %val, ptr %res
600  ret i1 %obit
601}
602
603define zeroext i1 @umulo.i64(i64 %v1, i64 %v2, ptr %res) {
604; SDAG-LABEL: umulo.i64:
605; SDAG:       // %bb.0: // %entry
606; SDAG-NEXT:    umulh x8, x0, x1
607; SDAG-NEXT:    mul x9, x0, x1
608; SDAG-NEXT:    cmp xzr, x8
609; SDAG-NEXT:    cset w0, ne
610; SDAG-NEXT:    str x9, [x2]
611; SDAG-NEXT:    ret
612;
613; FAST-LABEL: umulo.i64:
614; FAST:       // %bb.0: // %entry
615; FAST-NEXT:    umulh x8, x0, x1
616; FAST-NEXT:    mul x9, x0, x1
617; FAST-NEXT:    cmp xzr, x8
618; FAST-NEXT:    cset w8, ne
619; FAST-NEXT:    and w0, w8, #0x1
620; FAST-NEXT:    str x9, [x2]
621; FAST-NEXT:    ret
622;
623; GISEL-LABEL: umulo.i64:
624; GISEL:       // %bb.0: // %entry
625; GISEL-NEXT:    umulh x8, x0, x1
626; GISEL-NEXT:    mul x9, x0, x1
627; GISEL-NEXT:    cmp x8, #0
628; GISEL-NEXT:    cset w0, ne
629; GISEL-NEXT:    str x9, [x2]
630; GISEL-NEXT:    ret
631entry:
632  %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
633  %val = extractvalue {i64, i1} %t, 0
634  %obit = extractvalue {i64, i1} %t, 1
635  store i64 %val, ptr %res
636  ret i1 %obit
637}
638
639define zeroext i1 @umulo2.i64(i64 %v1, ptr %res) {
640; SDAG-LABEL: umulo2.i64:
641; SDAG:       // %bb.0: // %entry
642; SDAG-NEXT:    adds x8, x0, x0
643; SDAG-NEXT:    cset w0, hs
644; SDAG-NEXT:    str x8, [x1]
645; SDAG-NEXT:    ret
646;
647; FAST-LABEL: umulo2.i64:
648; FAST:       // %bb.0: // %entry
649; FAST-NEXT:    adds x8, x0, x0
650; FAST-NEXT:    cset w9, hs
651; FAST-NEXT:    str x8, [x1]
652; FAST-NEXT:    and w0, w9, #0x1
653; FAST-NEXT:    ret
654;
655; GISEL-LABEL: umulo2.i64:
656; GISEL:       // %bb.0: // %entry
657; GISEL-NEXT:    adds x8, x0, x0
658; GISEL-NEXT:    cset w0, hs
659; GISEL-NEXT:    str x8, [x1]
660; GISEL-NEXT:    ret
661entry:
662  %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 2)
663  %val = extractvalue {i64, i1} %t, 0
664  %obit = extractvalue {i64, i1} %t, 1
665  store i64 %val, ptr %res
666  ret i1 %obit
667}
668
669
670;
671; Check the use of the overflow bit in combination with a select instruction.
672;
673define i32 @saddo.select.i32(i32 %v1, i32 %v2) {
674; SDAG-LABEL: saddo.select.i32:
675; SDAG:       // %bb.0: // %entry
676; SDAG-NEXT:    cmn w0, w1
677; SDAG-NEXT:    csel w0, w0, w1, vs
678; SDAG-NEXT:    ret
679;
680; FAST-LABEL: saddo.select.i32:
681; FAST:       // %bb.0: // %entry
682; FAST-NEXT:    cmn w0, w1
683; FAST-NEXT:    csel w0, w0, w1, vs
684; FAST-NEXT:    ret
685;
686; GISEL-LABEL: saddo.select.i32:
687; GISEL:       // %bb.0: // %entry
688; GISEL-NEXT:    cmn w0, w1
689; GISEL-NEXT:    cset w8, vs
690; GISEL-NEXT:    tst w8, #0x1
691; GISEL-NEXT:    csel w0, w0, w1, ne
692; GISEL-NEXT:    ret
693entry:
694  %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2)
695  %obit = extractvalue {i32, i1} %t, 1
696  %ret = select i1 %obit, i32 %v1, i32 %v2
697  ret i32 %ret
698}
699
700define i1 @saddo.not.i32(i32 %v1, i32 %v2) {
701; SDAG-LABEL: saddo.not.i32:
702; SDAG:       // %bb.0: // %entry
703; SDAG-NEXT:    cmn w0, w1
704; SDAG-NEXT:    cset w0, vc
705; SDAG-NEXT:    ret
706;
707; FAST-LABEL: saddo.not.i32:
708; FAST:       // %bb.0: // %entry
709; FAST-NEXT:    cmn w0, w1
710; FAST-NEXT:    cset w0, vc
711; FAST-NEXT:    ret
712;
713; GISEL-LABEL: saddo.not.i32:
714; GISEL:       // %bb.0: // %entry
715; GISEL-NEXT:    cmn w0, w1
716; GISEL-NEXT:    cset w8, vs
717; GISEL-NEXT:    eor w0, w8, #0x1
718; GISEL-NEXT:    ret
719entry:
720  %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2)
721  %obit = extractvalue {i32, i1} %t, 1
722  %ret = xor i1 %obit, true
723  ret i1 %ret
724}
725
726define i64 @saddo.select.i64(i64 %v1, i64 %v2) {
727; SDAG-LABEL: saddo.select.i64:
728; SDAG:       // %bb.0: // %entry
729; SDAG-NEXT:    cmn x0, x1
730; SDAG-NEXT:    csel x0, x0, x1, vs
731; SDAG-NEXT:    ret
732;
733; FAST-LABEL: saddo.select.i64:
734; FAST:       // %bb.0: // %entry
735; FAST-NEXT:    cmn x0, x1
736; FAST-NEXT:    csel x0, x0, x1, vs
737; FAST-NEXT:    ret
738;
739; GISEL-LABEL: saddo.select.i64:
740; GISEL:       // %bb.0: // %entry
741; GISEL-NEXT:    cmn x0, x1
742; GISEL-NEXT:    cset w8, vs
743; GISEL-NEXT:    tst w8, #0x1
744; GISEL-NEXT:    csel x0, x0, x1, ne
745; GISEL-NEXT:    ret
746entry:
747  %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2)
748  %obit = extractvalue {i64, i1} %t, 1
749  %ret = select i1 %obit, i64 %v1, i64 %v2
750  ret i64 %ret
751}
752
753define i1 @saddo.not.i64(i64 %v1, i64 %v2) {
754; SDAG-LABEL: saddo.not.i64:
755; SDAG:       // %bb.0: // %entry
756; SDAG-NEXT:    cmn x0, x1
757; SDAG-NEXT:    cset w0, vc
758; SDAG-NEXT:    ret
759;
760; FAST-LABEL: saddo.not.i64:
761; FAST:       // %bb.0: // %entry
762; FAST-NEXT:    cmn x0, x1
763; FAST-NEXT:    cset w0, vc
764; FAST-NEXT:    ret
765;
766; GISEL-LABEL: saddo.not.i64:
767; GISEL:       // %bb.0: // %entry
768; GISEL-NEXT:    cmn x0, x1
769; GISEL-NEXT:    cset w8, vs
770; GISEL-NEXT:    eor w0, w8, #0x1
771; GISEL-NEXT:    ret
772entry:
773  %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2)
774  %obit = extractvalue {i64, i1} %t, 1
775  %ret = xor i1 %obit, true
776  ret i1 %ret
777}
778
779define i32 @uaddo.select.i32(i32 %v1, i32 %v2) {
780; SDAG-LABEL: uaddo.select.i32:
781; SDAG:       // %bb.0: // %entry
782; SDAG-NEXT:    cmn w0, w1
783; SDAG-NEXT:    csel w0, w0, w1, hs
784; SDAG-NEXT:    ret
785;
786; FAST-LABEL: uaddo.select.i32:
787; FAST:       // %bb.0: // %entry
788; FAST-NEXT:    cmn w0, w1
789; FAST-NEXT:    csel w0, w0, w1, hs
790; FAST-NEXT:    ret
791;
792; GISEL-LABEL: uaddo.select.i32:
793; GISEL:       // %bb.0: // %entry
794; GISEL-NEXT:    cmn w0, w1
795; GISEL-NEXT:    cset w8, hs
796; GISEL-NEXT:    tst w8, #0x1
797; GISEL-NEXT:    csel w0, w0, w1, ne
798; GISEL-NEXT:    ret
799entry:
800  %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)
801  %obit = extractvalue {i32, i1} %t, 1
802  %ret = select i1 %obit, i32 %v1, i32 %v2
803  ret i32 %ret
804}
805
806define i1 @uaddo.not.i32(i32 %v1, i32 %v2) {
807; SDAG-LABEL: uaddo.not.i32:
808; SDAG:       // %bb.0: // %entry
809; SDAG-NEXT:    cmn w0, w1
810; SDAG-NEXT:    cset w0, lo
811; SDAG-NEXT:    ret
812;
813; FAST-LABEL: uaddo.not.i32:
814; FAST:       // %bb.0: // %entry
815; FAST-NEXT:    cmn w0, w1
816; FAST-NEXT:    cset w0, lo
817; FAST-NEXT:    ret
818;
819; GISEL-LABEL: uaddo.not.i32:
820; GISEL:       // %bb.0: // %entry
821; GISEL-NEXT:    cmn w0, w1
822; GISEL-NEXT:    cset w8, hs
823; GISEL-NEXT:    eor w0, w8, #0x1
824; GISEL-NEXT:    ret
825entry:
826  %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)
827  %obit = extractvalue {i32, i1} %t, 1
828  %ret = xor i1 %obit, true
829  ret i1 %ret
830}
831
832define i64 @uaddo.select.i64(i64 %v1, i64 %v2) {
833; SDAG-LABEL: uaddo.select.i64:
834; SDAG:       // %bb.0: // %entry
835; SDAG-NEXT:    cmn x0, x1
836; SDAG-NEXT:    csel x0, x0, x1, hs
837; SDAG-NEXT:    ret
838;
839; FAST-LABEL: uaddo.select.i64:
840; FAST:       // %bb.0: // %entry
841; FAST-NEXT:    cmn x0, x1
842; FAST-NEXT:    csel x0, x0, x1, hs
843; FAST-NEXT:    ret
844;
845; GISEL-LABEL: uaddo.select.i64:
846; GISEL:       // %bb.0: // %entry
847; GISEL-NEXT:    cmn x0, x1
848; GISEL-NEXT:    cset w8, hs
849; GISEL-NEXT:    tst w8, #0x1
850; GISEL-NEXT:    csel x0, x0, x1, ne
851; GISEL-NEXT:    ret
852entry:
853  %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2)
854  %obit = extractvalue {i64, i1} %t, 1
855  %ret = select i1 %obit, i64 %v1, i64 %v2
856  ret i64 %ret
857}
858
859define i1 @uaddo.not.i64(i64 %v1, i64 %v2) {
860; SDAG-LABEL: uaddo.not.i64:
861; SDAG:       // %bb.0: // %entry
862; SDAG-NEXT:    cmn x0, x1
863; SDAG-NEXT:    cset w0, lo
864; SDAG-NEXT:    ret
865;
866; FAST-LABEL: uaddo.not.i64:
867; FAST:       // %bb.0: // %entry
868; FAST-NEXT:    cmn x0, x1
869; FAST-NEXT:    cset w0, lo
870; FAST-NEXT:    ret
871;
872; GISEL-LABEL: uaddo.not.i64:
873; GISEL:       // %bb.0: // %entry
874; GISEL-NEXT:    cmn x0, x1
875; GISEL-NEXT:    cset w8, hs
876; GISEL-NEXT:    eor w0, w8, #0x1
877; GISEL-NEXT:    ret
878entry:
879  %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2)
880  %obit = extractvalue {i64, i1} %t, 1
881  %ret = xor i1 %obit, true
882  ret i1 %ret
883}
884
885define i32 @ssubo.select.i32(i32 %v1, i32 %v2) {
886; SDAG-LABEL: ssubo.select.i32:
887; SDAG:       // %bb.0: // %entry
888; SDAG-NEXT:    cmp w0, w1
889; SDAG-NEXT:    csel w0, w0, w1, vs
890; SDAG-NEXT:    ret
891;
892; FAST-LABEL: ssubo.select.i32:
893; FAST:       // %bb.0: // %entry
894; FAST-NEXT:    cmp w0, w1
895; FAST-NEXT:    csel w0, w0, w1, vs
896; FAST-NEXT:    ret
897;
898; GISEL-LABEL: ssubo.select.i32:
899; GISEL:       // %bb.0: // %entry
900; GISEL-NEXT:    cmp w0, w1
901; GISEL-NEXT:    cset w8, vs
902; GISEL-NEXT:    tst w8, #0x1
903; GISEL-NEXT:    csel w0, w0, w1, ne
904; GISEL-NEXT:    ret
905entry:
906  %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2)
907  %obit = extractvalue {i32, i1} %t, 1
908  %ret = select i1 %obit, i32 %v1, i32 %v2
909  ret i32 %ret
910}
911
912define i1 @ssubo.not.i32(i32 %v1, i32 %v2) {
913; SDAG-LABEL: ssubo.not.i32:
914; SDAG:       // %bb.0: // %entry
915; SDAG-NEXT:    cmp w0, w1
916; SDAG-NEXT:    cset w0, vc
917; SDAG-NEXT:    ret
918;
919; FAST-LABEL: ssubo.not.i32:
920; FAST:       // %bb.0: // %entry
921; FAST-NEXT:    cmp w0, w1
922; FAST-NEXT:    cset w0, vc
923; FAST-NEXT:    ret
924;
925; GISEL-LABEL: ssubo.not.i32:
926; GISEL:       // %bb.0: // %entry
927; GISEL-NEXT:    cmp w0, w1
928; GISEL-NEXT:    cset w8, vs
929; GISEL-NEXT:    eor w0, w8, #0x1
930; GISEL-NEXT:    ret
931entry:
932  %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2)
933  %obit = extractvalue {i32, i1} %t, 1
934  %ret = xor i1 %obit, true
935  ret i1 %ret
936}
937
938define i64 @ssubo.select.i64(i64 %v1, i64 %v2) {
939; SDAG-LABEL: ssubo.select.i64:
940; SDAG:       // %bb.0: // %entry
941; SDAG-NEXT:    cmp x0, x1
942; SDAG-NEXT:    csel x0, x0, x1, vs
943; SDAG-NEXT:    ret
944;
945; FAST-LABEL: ssubo.select.i64:
946; FAST:       // %bb.0: // %entry
947; FAST-NEXT:    cmp x0, x1
948; FAST-NEXT:    csel x0, x0, x1, vs
949; FAST-NEXT:    ret
950;
951; GISEL-LABEL: ssubo.select.i64:
952; GISEL:       // %bb.0: // %entry
953; GISEL-NEXT:    cmp x0, x1
954; GISEL-NEXT:    cset w8, vs
955; GISEL-NEXT:    tst w8, #0x1
956; GISEL-NEXT:    csel x0, x0, x1, ne
957; GISEL-NEXT:    ret
958entry:
959  %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2)
960  %obit = extractvalue {i64, i1} %t, 1
961  %ret = select i1 %obit, i64 %v1, i64 %v2
962  ret i64 %ret
963}
964
965define i1 @ssub.not.i64(i64 %v1, i64 %v2) {
966; SDAG-LABEL: ssub.not.i64:
967; SDAG:       // %bb.0: // %entry
968; SDAG-NEXT:    cmp x0, x1
969; SDAG-NEXT:    cset w0, vc
970; SDAG-NEXT:    ret
971;
972; FAST-LABEL: ssub.not.i64:
973; FAST:       // %bb.0: // %entry
974; FAST-NEXT:    cmp x0, x1
975; FAST-NEXT:    cset w0, vc
976; FAST-NEXT:    ret
977;
978; GISEL-LABEL: ssub.not.i64:
979; GISEL:       // %bb.0: // %entry
980; GISEL-NEXT:    cmp x0, x1
981; GISEL-NEXT:    cset w8, vs
982; GISEL-NEXT:    eor w0, w8, #0x1
983; GISEL-NEXT:    ret
984entry:
985  %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2)
986  %obit = extractvalue {i64, i1} %t, 1
987  %ret = xor i1 %obit, true
988  ret i1 %ret
989}
990
991define i32 @usubo.select.i32(i32 %v1, i32 %v2) {
992; SDAG-LABEL: usubo.select.i32:
993; SDAG:       // %bb.0: // %entry
994; SDAG-NEXT:    cmp w0, w1
995; SDAG-NEXT:    csel w0, w0, w1, lo
996; SDAG-NEXT:    ret
997;
998; FAST-LABEL: usubo.select.i32:
999; FAST:       // %bb.0: // %entry
1000; FAST-NEXT:    cmp w0, w1
1001; FAST-NEXT:    csel w0, w0, w1, lo
1002; FAST-NEXT:    ret
1003;
1004; GISEL-LABEL: usubo.select.i32:
1005; GISEL:       // %bb.0: // %entry
1006; GISEL-NEXT:    cmp w0, w1
1007; GISEL-NEXT:    cset w8, lo
1008; GISEL-NEXT:    tst w8, #0x1
1009; GISEL-NEXT:    csel w0, w0, w1, ne
1010; GISEL-NEXT:    ret
1011entry:
1012  %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2)
1013  %obit = extractvalue {i32, i1} %t, 1
1014  %ret = select i1 %obit, i32 %v1, i32 %v2
1015  ret i32 %ret
1016}
1017
1018define i1 @usubo.not.i32(i32 %v1, i32 %v2) {
1019; SDAG-LABEL: usubo.not.i32:
1020; SDAG:       // %bb.0: // %entry
1021; SDAG-NEXT:    cmp w0, w1
1022; SDAG-NEXT:    cset w0, hs
1023; SDAG-NEXT:    ret
1024;
1025; FAST-LABEL: usubo.not.i32:
1026; FAST:       // %bb.0: // %entry
1027; FAST-NEXT:    cmp w0, w1
1028; FAST-NEXT:    cset w0, hs
1029; FAST-NEXT:    ret
1030;
1031; GISEL-LABEL: usubo.not.i32:
1032; GISEL:       // %bb.0: // %entry
1033; GISEL-NEXT:    cmp w0, w1
1034; GISEL-NEXT:    cset w8, lo
1035; GISEL-NEXT:    eor w0, w8, #0x1
1036; GISEL-NEXT:    ret
1037entry:
1038  %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2)
1039  %obit = extractvalue {i32, i1} %t, 1
1040  %ret = xor i1 %obit, true
1041  ret i1 %ret
1042}
1043
1044define i64 @usubo.select.i64(i64 %v1, i64 %v2) {
1045; SDAG-LABEL: usubo.select.i64:
1046; SDAG:       // %bb.0: // %entry
1047; SDAG-NEXT:    cmp x0, x1
1048; SDAG-NEXT:    csel x0, x0, x1, lo
1049; SDAG-NEXT:    ret
1050;
1051; FAST-LABEL: usubo.select.i64:
1052; FAST:       // %bb.0: // %entry
1053; FAST-NEXT:    cmp x0, x1
1054; FAST-NEXT:    csel x0, x0, x1, lo
1055; FAST-NEXT:    ret
1056;
1057; GISEL-LABEL: usubo.select.i64:
1058; GISEL:       // %bb.0: // %entry
1059; GISEL-NEXT:    cmp x0, x1
1060; GISEL-NEXT:    cset w8, lo
1061; GISEL-NEXT:    tst w8, #0x1
1062; GISEL-NEXT:    csel x0, x0, x1, ne
1063; GISEL-NEXT:    ret
1064entry:
1065  %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2)
1066  %obit = extractvalue {i64, i1} %t, 1
1067  %ret = select i1 %obit, i64 %v1, i64 %v2
1068  ret i64 %ret
1069}
1070
1071define i1 @usubo.not.i64(i64 %v1, i64 %v2) {
1072; SDAG-LABEL: usubo.not.i64:
1073; SDAG:       // %bb.0: // %entry
1074; SDAG-NEXT:    cmp x0, x1
1075; SDAG-NEXT:    cset w0, hs
1076; SDAG-NEXT:    ret
1077;
1078; FAST-LABEL: usubo.not.i64:
1079; FAST:       // %bb.0: // %entry
1080; FAST-NEXT:    cmp x0, x1
1081; FAST-NEXT:    cset w0, hs
1082; FAST-NEXT:    ret
1083;
1084; GISEL-LABEL: usubo.not.i64:
1085; GISEL:       // %bb.0: // %entry
1086; GISEL-NEXT:    cmp x0, x1
1087; GISEL-NEXT:    cset w8, lo
1088; GISEL-NEXT:    eor w0, w8, #0x1
1089; GISEL-NEXT:    ret
1090entry:
1091  %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2)
1092  %obit = extractvalue {i64, i1} %t, 1
1093  %ret = xor i1 %obit, true
1094  ret i1 %ret
1095}
1096
1097define i32 @smulo.select.i32(i32 %v1, i32 %v2) {
1098; SDAG-LABEL: smulo.select.i32:
1099; SDAG:       // %bb.0: // %entry
1100; SDAG-NEXT:    smull x8, w0, w1
1101; SDAG-NEXT:    cmp x8, w8, sxtw
1102; SDAG-NEXT:    csel w0, w0, w1, ne
1103; SDAG-NEXT:    ret
1104;
1105; FAST-LABEL: smulo.select.i32:
1106; FAST:       // %bb.0: // %entry
1107; FAST-NEXT:    smull x8, w0, w1
1108; FAST-NEXT:    cmp x8, w8, sxtw
1109; FAST-NEXT:    csel w0, w0, w1, ne
1110; FAST-NEXT:    ret
1111;
1112; GISEL-LABEL: smulo.select.i32:
1113; GISEL:       // %bb.0: // %entry
1114; GISEL-NEXT:    smull x8, w0, w1
1115; GISEL-NEXT:    mul w9, w0, w1
1116; GISEL-NEXT:    asr x8, x8, #32
1117; GISEL-NEXT:    cmp w8, w9, asr #31
1118; GISEL-NEXT:    csel w0, w0, w1, ne
1119; GISEL-NEXT:    ret
1120entry:
1121  %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
1122  %obit = extractvalue {i32, i1} %t, 1
1123  %ret = select i1 %obit, i32 %v1, i32 %v2
1124  ret i32 %ret
1125}
1126
1127define i1 @smulo.not.i32(i32 %v1, i32 %v2) {
1128; SDAG-LABEL: smulo.not.i32:
1129; SDAG:       // %bb.0: // %entry
1130; SDAG-NEXT:    smull x8, w0, w1
1131; SDAG-NEXT:    cmp x8, w8, sxtw
1132; SDAG-NEXT:    cset w0, eq
1133; SDAG-NEXT:    ret
1134;
1135; FAST-LABEL: smulo.not.i32:
1136; FAST:       // %bb.0: // %entry
1137; FAST-NEXT:    smull x8, w0, w1
1138; FAST-NEXT:    cmp x8, w8, sxtw
1139; FAST-NEXT:    cset w0, eq
1140; FAST-NEXT:    ret
1141;
1142; GISEL-LABEL: smulo.not.i32:
1143; GISEL:       // %bb.0: // %entry
1144; GISEL-NEXT:    smull x8, w0, w1
1145; GISEL-NEXT:    mul w9, w0, w1
1146; GISEL-NEXT:    asr x8, x8, #32
1147; GISEL-NEXT:    cmp w8, w9, asr #31
1148; GISEL-NEXT:    cset w8, ne
1149; GISEL-NEXT:    eor w0, w8, #0x1
1150; GISEL-NEXT:    ret
1151entry:
1152  %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
1153  %obit = extractvalue {i32, i1} %t, 1
1154  %ret = xor i1 %obit, true
1155  ret i1 %ret
1156}
1157
1158define i64 @smulo.select.i64(i64 %v1, i64 %v2) {
1159; SDAG-LABEL: smulo.select.i64:
1160; SDAG:       // %bb.0: // %entry
1161; SDAG-NEXT:    mul x8, x0, x1
1162; SDAG-NEXT:    smulh x9, x0, x1
1163; SDAG-NEXT:    cmp x9, x8, asr #63
1164; SDAG-NEXT:    csel x0, x0, x1, ne
1165; SDAG-NEXT:    ret
1166;
1167; FAST-LABEL: smulo.select.i64:
1168; FAST:       // %bb.0: // %entry
1169; FAST-NEXT:    mul x8, x0, x1
1170; FAST-NEXT:    smulh x9, x0, x1
1171; FAST-NEXT:    cmp x9, x8, asr #63
1172; FAST-NEXT:    csel x0, x0, x1, ne
1173; FAST-NEXT:    ret
1174;
1175; GISEL-LABEL: smulo.select.i64:
1176; GISEL:       // %bb.0: // %entry
1177; GISEL-NEXT:    smulh x8, x0, x1
1178; GISEL-NEXT:    mul x9, x0, x1
1179; GISEL-NEXT:    cmp x8, x9, asr #63
1180; GISEL-NEXT:    csel x0, x0, x1, ne
1181; GISEL-NEXT:    ret
1182entry:
1183  %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
1184  %obit = extractvalue {i64, i1} %t, 1
1185  %ret = select i1 %obit, i64 %v1, i64 %v2
1186  ret i64 %ret
1187}
1188
1189define i1 @smulo.not.i64(i64 %v1, i64 %v2) {
1190; SDAG-LABEL: smulo.not.i64:
1191; SDAG:       // %bb.0: // %entry
1192; SDAG-NEXT:    mul x8, x0, x1
1193; SDAG-NEXT:    smulh x9, x0, x1
1194; SDAG-NEXT:    cmp x9, x8, asr #63
1195; SDAG-NEXT:    cset w0, eq
1196; SDAG-NEXT:    ret
1197;
1198; FAST-LABEL: smulo.not.i64:
1199; FAST:       // %bb.0: // %entry
1200; FAST-NEXT:    mul x8, x0, x1
1201; FAST-NEXT:    smulh x9, x0, x1
1202; FAST-NEXT:    cmp x9, x8, asr #63
1203; FAST-NEXT:    cset w0, eq
1204; FAST-NEXT:    ret
1205;
1206; GISEL-LABEL: smulo.not.i64:
1207; GISEL:       // %bb.0: // %entry
1208; GISEL-NEXT:    smulh x8, x0, x1
1209; GISEL-NEXT:    mul x9, x0, x1
1210; GISEL-NEXT:    cmp x8, x9, asr #63
1211; GISEL-NEXT:    cset w8, ne
1212; GISEL-NEXT:    eor w0, w8, #0x1
1213; GISEL-NEXT:    ret
1214entry:
1215  %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
1216  %obit = extractvalue {i64, i1} %t, 1
1217  %ret = xor i1 %obit, true
1218  ret i1 %ret
1219}
1220
1221define i32 @umulo.select.i32(i32 %v1, i32 %v2) {
1222; SDAG-LABEL: umulo.select.i32:
1223; SDAG:       // %bb.0: // %entry
1224; SDAG-NEXT:    umull x8, w0, w1
1225; SDAG-NEXT:    tst x8, #0xffffffff00000000
1226; SDAG-NEXT:    csel w0, w0, w1, ne
1227; SDAG-NEXT:    ret
1228;
1229; FAST-LABEL: umulo.select.i32:
1230; FAST:       // %bb.0: // %entry
1231; FAST-NEXT:    umull x8, w0, w1
1232; FAST-NEXT:    tst x8, #0xffffffff00000000
1233; FAST-NEXT:    csel w0, w0, w1, ne
1234; FAST-NEXT:    ret
1235;
1236; GISEL-LABEL: umulo.select.i32:
1237; GISEL:       // %bb.0: // %entry
1238; GISEL-NEXT:    umull x8, w0, w1
1239; GISEL-NEXT:    lsr x8, x8, #32
1240; GISEL-NEXT:    cmp w8, #0
1241; GISEL-NEXT:    csel w0, w0, w1, ne
1242; GISEL-NEXT:    ret
1243entry:
1244  %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
1245  %obit = extractvalue {i32, i1} %t, 1
1246  %ret = select i1 %obit, i32 %v1, i32 %v2
1247  ret i32 %ret
1248}
1249
1250define i1 @umulo.not.i32(i32 %v1, i32 %v2) {
1251; SDAG-LABEL: umulo.not.i32:
1252; SDAG:       // %bb.0: // %entry
1253; SDAG-NEXT:    umull x8, w0, w1
1254; SDAG-NEXT:    tst x8, #0xffffffff00000000
1255; SDAG-NEXT:    cset w0, eq
1256; SDAG-NEXT:    ret
1257;
1258; FAST-LABEL: umulo.not.i32:
1259; FAST:       // %bb.0: // %entry
1260; FAST-NEXT:    umull x8, w0, w1
1261; FAST-NEXT:    tst x8, #0xffffffff00000000
1262; FAST-NEXT:    cset w0, eq
1263; FAST-NEXT:    ret
1264;
1265; GISEL-LABEL: umulo.not.i32:
1266; GISEL:       // %bb.0: // %entry
1267; GISEL-NEXT:    umull x8, w0, w1
1268; GISEL-NEXT:    lsr x8, x8, #32
1269; GISEL-NEXT:    cmp w8, #0
1270; GISEL-NEXT:    cset w8, ne
1271; GISEL-NEXT:    eor w0, w8, #0x1
1272; GISEL-NEXT:    ret
1273entry:
1274  %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
1275  %obit = extractvalue {i32, i1} %t, 1
1276  %ret = xor i1 %obit, true
1277  ret i1 %ret
1278}
1279
1280define i64 @umulo.select.i64(i64 %v1, i64 %v2) {
1281; SDAG-LABEL: umulo.select.i64:
1282; SDAG:       // %bb.0: // %entry
1283; SDAG-NEXT:    umulh x8, x0, x1
1284; SDAG-NEXT:    cmp xzr, x8
1285; SDAG-NEXT:    csel x0, x0, x1, ne
1286; SDAG-NEXT:    ret
1287;
1288; FAST-LABEL: umulo.select.i64:
1289; FAST:       // %bb.0: // %entry
1290; FAST-NEXT:    umulh x8, x0, x1
1291; FAST-NEXT:    cmp xzr, x8
1292; FAST-NEXT:    csel x0, x0, x1, ne
1293; FAST-NEXT:    ret
1294;
1295; GISEL-LABEL: umulo.select.i64:
1296; GISEL:       // %bb.0: // %entry
1297; GISEL-NEXT:    umulh x8, x0, x1
1298; GISEL-NEXT:    cmp x8, #0
1299; GISEL-NEXT:    csel x0, x0, x1, ne
1300; GISEL-NEXT:    ret
1301entry:
1302  %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
1303  %obit = extractvalue {i64, i1} %t, 1
1304  %ret = select i1 %obit, i64 %v1, i64 %v2
1305  ret i64 %ret
1306}
1307
1308define i1 @umulo.not.i64(i64 %v1, i64 %v2) {
1309; SDAG-LABEL: umulo.not.i64:
1310; SDAG:       // %bb.0: // %entry
1311; SDAG-NEXT:    umulh x8, x0, x1
1312; SDAG-NEXT:    cmp xzr, x8
1313; SDAG-NEXT:    cset w0, eq
1314; SDAG-NEXT:    ret
1315;
1316; FAST-LABEL: umulo.not.i64:
1317; FAST:       // %bb.0: // %entry
1318; FAST-NEXT:    umulh x8, x0, x1
1319; FAST-NEXT:    cmp xzr, x8
1320; FAST-NEXT:    cset w0, eq
1321; FAST-NEXT:    ret
1322;
1323; GISEL-LABEL: umulo.not.i64:
1324; GISEL:       // %bb.0: // %entry
1325; GISEL-NEXT:    umulh x8, x0, x1
1326; GISEL-NEXT:    cmp x8, #0
1327; GISEL-NEXT:    cset w8, ne
1328; GISEL-NEXT:    eor w0, w8, #0x1
1329; GISEL-NEXT:    ret
1330entry:
1331  %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
1332  %obit = extractvalue {i64, i1} %t, 1
1333  %ret = xor i1 %obit, true
1334  ret i1 %ret
1335}
1336
1337
1338define i8 @uaddo.selectboth.i8(i8 %a, i8 %b) {
1339; SDAG-LABEL: uaddo.selectboth.i8:
1340; SDAG:       // %bb.0: // %entry
1341; SDAG-NEXT:    and w9, w0, #0xff
1342; SDAG-NEXT:    mov w8, #10 // =0xa
1343; SDAG-NEXT:    add w9, w9, w1, uxtb
1344; SDAG-NEXT:    tst w9, #0x100
1345; SDAG-NEXT:    csel w0, w9, w8, ne
1346; SDAG-NEXT:    ret
1347;
1348; FAST-LABEL: uaddo.selectboth.i8:
1349; FAST:       // %bb.0: // %entry
1350; FAST-NEXT:    and w9, w0, #0xff
1351; FAST-NEXT:    mov w8, #10 // =0xa
1352; FAST-NEXT:    add w9, w9, w1, uxtb
1353; FAST-NEXT:    tst w9, #0x100
1354; FAST-NEXT:    csel w0, w9, w8, ne
1355; FAST-NEXT:    ret
1356;
1357; GISEL-LABEL: uaddo.selectboth.i8:
1358; GISEL:       // %bb.0: // %entry
1359; GISEL-NEXT:    and w9, w1, #0xff
1360; GISEL-NEXT:    mov w8, #10 // =0xa
1361; GISEL-NEXT:    add w9, w9, w0, uxtb
1362; GISEL-NEXT:    cmp w9, w9, uxtb
1363; GISEL-NEXT:    csel w0, w9, w8, ne
1364; GISEL-NEXT:    ret
1365entry:
1366  %m = call { i8, i1 } @llvm.uadd.with.overflow.i8(i8 %a, i8 %b)
1367  %m1 = extractvalue { i8, i1 } %m, 0
1368  %m2 = extractvalue { i8, i1 } %m, 1
1369  %r = select i1 %m2, i8 %m1, i8 10
1370  ret i8 %r
1371}
1372
1373define i8 @saddo.selectboth.i8(i8 %a, i8 %b) {
1374; SDAG-LABEL: saddo.selectboth.i8:
1375; SDAG:       // %bb.0: // %entry
1376; SDAG-NEXT:    sxtb w9, w0
1377; SDAG-NEXT:    mov w8, #10 // =0xa
1378; SDAG-NEXT:    add w9, w9, w1, sxtb
1379; SDAG-NEXT:    cmp w9, w9, sxtb
1380; SDAG-NEXT:    csel w0, w9, w8, ne
1381; SDAG-NEXT:    ret
1382;
1383; FAST-LABEL: saddo.selectboth.i8:
1384; FAST:       // %bb.0: // %entry
1385; FAST-NEXT:    sxtb w9, w0
1386; FAST-NEXT:    mov w8, #10 // =0xa
1387; FAST-NEXT:    add w9, w9, w1, sxtb
1388; FAST-NEXT:    cmp w9, w9, sxtb
1389; FAST-NEXT:    csel w0, w9, w8, ne
1390; FAST-NEXT:    ret
1391;
1392; GISEL-LABEL: saddo.selectboth.i8:
1393; GISEL:       // %bb.0: // %entry
1394; GISEL-NEXT:    sxtb w9, w1
1395; GISEL-NEXT:    mov w8, #10 // =0xa
1396; GISEL-NEXT:    add w9, w9, w0, sxtb
1397; GISEL-NEXT:    cmp w9, w9, sxtb
1398; GISEL-NEXT:    csel w0, w9, w8, ne
1399; GISEL-NEXT:    ret
1400entry:
1401  %m = call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 %a, i8 %b)
1402  %m1 = extractvalue { i8, i1 } %m, 0
1403  %m2 = extractvalue { i8, i1 } %m, 1
1404  %r = select i1 %m2, i8 %m1, i8 10
1405  ret i8 %r
1406}
1407
1408define i16 @uaddo.selectboth.i16(i16 %a, i16 %b) {
1409; SDAG-LABEL: uaddo.selectboth.i16:
1410; SDAG:       // %bb.0: // %entry
1411; SDAG-NEXT:    and w9, w0, #0xffff
1412; SDAG-NEXT:    mov w8, #10 // =0xa
1413; SDAG-NEXT:    add w9, w9, w1, uxth
1414; SDAG-NEXT:    tst w9, #0x10000
1415; SDAG-NEXT:    csel w0, w9, w8, ne
1416; SDAG-NEXT:    ret
1417;
1418; FAST-LABEL: uaddo.selectboth.i16:
1419; FAST:       // %bb.0: // %entry
1420; FAST-NEXT:    and w9, w0, #0xffff
1421; FAST-NEXT:    mov w8, #10 // =0xa
1422; FAST-NEXT:    add w9, w9, w1, uxth
1423; FAST-NEXT:    tst w9, #0x10000
1424; FAST-NEXT:    csel w0, w9, w8, ne
1425; FAST-NEXT:    ret
1426;
1427; GISEL-LABEL: uaddo.selectboth.i16:
1428; GISEL:       // %bb.0: // %entry
1429; GISEL-NEXT:    and w9, w1, #0xffff
1430; GISEL-NEXT:    mov w8, #10 // =0xa
1431; GISEL-NEXT:    add w9, w9, w0, uxth
1432; GISEL-NEXT:    cmp w9, w9, uxth
1433; GISEL-NEXT:    csel w0, w9, w8, ne
1434; GISEL-NEXT:    ret
1435entry:
1436  %m = call { i16, i1 } @llvm.uadd.with.overflow.i16(i16 %a, i16 %b)
1437  %m1 = extractvalue { i16, i1 } %m, 0
1438  %m2 = extractvalue { i16, i1 } %m, 1
1439  %r = select i1 %m2, i16 %m1, i16 10
1440  ret i16 %r
1441}
1442
1443define i16 @saddo.selectboth.i16(i16 %a, i16 %b) {
1444; SDAG-LABEL: saddo.selectboth.i16:
1445; SDAG:       // %bb.0: // %entry
1446; SDAG-NEXT:    sxth w9, w0
1447; SDAG-NEXT:    mov w8, #10 // =0xa
1448; SDAG-NEXT:    add w9, w9, w1, sxth
1449; SDAG-NEXT:    cmp w9, w9, sxth
1450; SDAG-NEXT:    csel w0, w9, w8, ne
1451; SDAG-NEXT:    ret
1452;
1453; FAST-LABEL: saddo.selectboth.i16:
1454; FAST:       // %bb.0: // %entry
1455; FAST-NEXT:    sxth w9, w0
1456; FAST-NEXT:    mov w8, #10 // =0xa
1457; FAST-NEXT:    add w9, w9, w1, sxth
1458; FAST-NEXT:    cmp w9, w9, sxth
1459; FAST-NEXT:    csel w0, w9, w8, ne
1460; FAST-NEXT:    ret
1461;
1462; GISEL-LABEL: saddo.selectboth.i16:
1463; GISEL:       // %bb.0: // %entry
1464; GISEL-NEXT:    sxth w9, w1
1465; GISEL-NEXT:    mov w8, #10 // =0xa
1466; GISEL-NEXT:    add w9, w9, w0, sxth
1467; GISEL-NEXT:    cmp w9, w9, sxth
1468; GISEL-NEXT:    csel w0, w9, w8, ne
1469; GISEL-NEXT:    ret
1470entry:
1471  %m = call { i16, i1 } @llvm.sadd.with.overflow.i16(i16 %a, i16 %b)
1472  %m1 = extractvalue { i16, i1 } %m, 0
1473  %m2 = extractvalue { i16, i1 } %m, 1
1474  %r = select i1 %m2, i16 %m1, i16 10
1475  ret i16 %r
1476}
1477
1478define i32 @uaddo.selectboth.i32(i32 %a, i32 %b) {
1479; SDAG-LABEL: uaddo.selectboth.i32:
1480; SDAG:       // %bb.0: // %entry
1481; SDAG-NEXT:    mov w8, #10 // =0xa
1482; SDAG-NEXT:    adds w9, w0, w1
1483; SDAG-NEXT:    csel w0, w9, w8, hs
1484; SDAG-NEXT:    ret
1485;
1486; FAST-LABEL: uaddo.selectboth.i32:
1487; FAST:       // %bb.0: // %entry
1488; FAST-NEXT:    mov w8, #10 // =0xa
1489; FAST-NEXT:    adds w9, w0, w1
1490; FAST-NEXT:    csel w0, w9, w8, hs
1491; FAST-NEXT:    ret
1492;
1493; GISEL-LABEL: uaddo.selectboth.i32:
1494; GISEL:       // %bb.0: // %entry
1495; GISEL-NEXT:    adds w9, w0, w1
1496; GISEL-NEXT:    mov w8, #10 // =0xa
1497; GISEL-NEXT:    cset w10, hs
1498; GISEL-NEXT:    tst w10, #0x1
1499; GISEL-NEXT:    csel w0, w9, w8, ne
1500; GISEL-NEXT:    ret
1501entry:
1502  %m = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %a, i32 %b)
1503  %m1 = extractvalue { i32, i1 } %m, 0
1504  %m2 = extractvalue { i32, i1 } %m, 1
1505  %r = select i1 %m2, i32 %m1, i32 10
1506  ret i32 %r
1507}
1508
1509define i32 @saddo.selectboth.i32(i32 %a, i32 %b) {
1510; SDAG-LABEL: saddo.selectboth.i32:
1511; SDAG:       // %bb.0: // %entry
1512; SDAG-NEXT:    mov w8, #10 // =0xa
1513; SDAG-NEXT:    adds w9, w0, w1
1514; SDAG-NEXT:    csel w0, w9, w8, vs
1515; SDAG-NEXT:    ret
1516;
1517; FAST-LABEL: saddo.selectboth.i32:
1518; FAST:       // %bb.0: // %entry
1519; FAST-NEXT:    mov w8, #10 // =0xa
1520; FAST-NEXT:    adds w9, w0, w1
1521; FAST-NEXT:    csel w0, w9, w8, vs
1522; FAST-NEXT:    ret
1523;
1524; GISEL-LABEL: saddo.selectboth.i32:
1525; GISEL:       // %bb.0: // %entry
1526; GISEL-NEXT:    adds w9, w0, w1
1527; GISEL-NEXT:    mov w8, #10 // =0xa
1528; GISEL-NEXT:    cset w10, vs
1529; GISEL-NEXT:    tst w10, #0x1
1530; GISEL-NEXT:    csel w0, w9, w8, ne
1531; GISEL-NEXT:    ret
1532entry:
1533  %m = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %a, i32 %b)
1534  %m1 = extractvalue { i32, i1 } %m, 0
1535  %m2 = extractvalue { i32, i1 } %m, 1
1536  %r = select i1 %m2, i32 %m1, i32 10
1537  ret i32 %r
1538}
1539
1540define i64 @uaddo.selectboth.i64(i64 %a, i64 %b) {
1541; SDAG-LABEL: uaddo.selectboth.i64:
1542; SDAG:       // %bb.0: // %entry
1543; SDAG-NEXT:    mov w8, #10 // =0xa
1544; SDAG-NEXT:    adds x9, x0, x1
1545; SDAG-NEXT:    csel x0, x9, x8, hs
1546; SDAG-NEXT:    ret
1547;
1548; FAST-LABEL: uaddo.selectboth.i64:
1549; FAST:       // %bb.0: // %entry
1550; FAST-NEXT:    mov x8, #10 // =0xa
1551; FAST-NEXT:    adds x9, x0, x1
1552; FAST-NEXT:    csel x0, x9, x8, hs
1553; FAST-NEXT:    ret
1554;
1555; GISEL-LABEL: uaddo.selectboth.i64:
1556; GISEL:       // %bb.0: // %entry
1557; GISEL-NEXT:    adds x9, x0, x1
1558; GISEL-NEXT:    mov w8, #10 // =0xa
1559; GISEL-NEXT:    cset w10, hs
1560; GISEL-NEXT:    tst w10, #0x1
1561; GISEL-NEXT:    csel x0, x9, x8, ne
1562; GISEL-NEXT:    ret
1563entry:
1564  %m = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %a, i64 %b)
1565  %m1 = extractvalue { i64, i1 } %m, 0
1566  %m2 = extractvalue { i64, i1 } %m, 1
1567  %r = select i1 %m2, i64 %m1, i64 10
1568  ret i64 %r
1569}
1570
1571define i64 @saddo.selectboth.i64(i64 %a, i64 %b) {
1572; SDAG-LABEL: saddo.selectboth.i64:
1573; SDAG:       // %bb.0: // %entry
1574; SDAG-NEXT:    mov w8, #10 // =0xa
1575; SDAG-NEXT:    adds x9, x0, x1
1576; SDAG-NEXT:    csel x0, x9, x8, vs
1577; SDAG-NEXT:    ret
1578;
1579; FAST-LABEL: saddo.selectboth.i64:
1580; FAST:       // %bb.0: // %entry
1581; FAST-NEXT:    mov x8, #10 // =0xa
1582; FAST-NEXT:    adds x9, x0, x1
1583; FAST-NEXT:    csel x0, x9, x8, vs
1584; FAST-NEXT:    ret
1585;
1586; GISEL-LABEL: saddo.selectboth.i64:
1587; GISEL:       // %bb.0: // %entry
1588; GISEL-NEXT:    adds x9, x0, x1
1589; GISEL-NEXT:    mov w8, #10 // =0xa
1590; GISEL-NEXT:    cset w10, vs
1591; GISEL-NEXT:    tst w10, #0x1
1592; GISEL-NEXT:    csel x0, x9, x8, ne
1593; GISEL-NEXT:    ret
1594entry:
1595  %m = call { i64, i1 } @llvm.sadd.with.overflow.i64(i64 %a, i64 %b)
1596  %m1 = extractvalue { i64, i1 } %m, 0
1597  %m2 = extractvalue { i64, i1 } %m, 1
1598  %r = select i1 %m2, i64 %m1, i64 10
1599  ret i64 %r
1600}
1601
1602define i8 @usubo.selectboth.i8(i8 %a, i8 %b) {
1603; SDAG-LABEL: usubo.selectboth.i8:
1604; SDAG:       // %bb.0: // %entry
1605; SDAG-NEXT:    and w9, w0, #0xff
1606; SDAG-NEXT:    mov w8, #10 // =0xa
1607; SDAG-NEXT:    sub w9, w9, w1, uxtb
1608; SDAG-NEXT:    tst w9, #0xffffff00
1609; SDAG-NEXT:    csel w0, w9, w8, ne
1610; SDAG-NEXT:    ret
1611;
1612; FAST-LABEL: usubo.selectboth.i8:
1613; FAST:       // %bb.0: // %entry
1614; FAST-NEXT:    and w9, w0, #0xff
1615; FAST-NEXT:    mov w8, #10 // =0xa
1616; FAST-NEXT:    sub w9, w9, w1, uxtb
1617; FAST-NEXT:    tst w9, #0xffffff00
1618; FAST-NEXT:    csel w0, w9, w8, ne
1619; FAST-NEXT:    ret
1620;
1621; GISEL-LABEL: usubo.selectboth.i8:
1622; GISEL:       // %bb.0: // %entry
1623; GISEL-NEXT:    and w9, w0, #0xff
1624; GISEL-NEXT:    mov w8, #10 // =0xa
1625; GISEL-NEXT:    sub w9, w9, w1, uxtb
1626; GISEL-NEXT:    cmp w9, w9, uxtb
1627; GISEL-NEXT:    csel w0, w9, w8, ne
1628; GISEL-NEXT:    ret
1629entry:
1630  %m = call { i8, i1 } @llvm.usub.with.overflow.i8(i8 %a, i8 %b)
1631  %m1 = extractvalue { i8, i1 } %m, 0
1632  %m2 = extractvalue { i8, i1 } %m, 1
1633  %r = select i1 %m2, i8 %m1, i8 10
1634  ret i8 %r
1635}
1636
1637define i8 @ssubo.selectboth.i8(i8 %a, i8 %b) {
1638; CHECK-LABEL: ssubo.selectboth.i8:
1639; CHECK:       // %bb.0: // %entry
1640; CHECK-NEXT:    sxtb w9, w0
1641; CHECK-NEXT:    mov w8, #10 // =0xa
1642; CHECK-NEXT:    sub w9, w9, w1, sxtb
1643; CHECK-NEXT:    cmp w9, w9, sxtb
1644; CHECK-NEXT:    csel w0, w9, w8, ne
1645; CHECK-NEXT:    ret
1646entry:
1647  %m = call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 %a, i8 %b)
1648  %m1 = extractvalue { i8, i1 } %m, 0
1649  %m2 = extractvalue { i8, i1 } %m, 1
1650  %r = select i1 %m2, i8 %m1, i8 10
1651  ret i8 %r
1652}
1653
1654define i16 @usubo.selectboth.i16(i16 %a, i16 %b) {
1655; SDAG-LABEL: usubo.selectboth.i16:
1656; SDAG:       // %bb.0: // %entry
1657; SDAG-NEXT:    and w9, w0, #0xffff
1658; SDAG-NEXT:    mov w8, #10 // =0xa
1659; SDAG-NEXT:    sub w9, w9, w1, uxth
1660; SDAG-NEXT:    tst w9, #0xffff0000
1661; SDAG-NEXT:    csel w0, w9, w8, ne
1662; SDAG-NEXT:    ret
1663;
1664; FAST-LABEL: usubo.selectboth.i16:
1665; FAST:       // %bb.0: // %entry
1666; FAST-NEXT:    and w9, w0, #0xffff
1667; FAST-NEXT:    mov w8, #10 // =0xa
1668; FAST-NEXT:    sub w9, w9, w1, uxth
1669; FAST-NEXT:    tst w9, #0xffff0000
1670; FAST-NEXT:    csel w0, w9, w8, ne
1671; FAST-NEXT:    ret
1672;
1673; GISEL-LABEL: usubo.selectboth.i16:
1674; GISEL:       // %bb.0: // %entry
1675; GISEL-NEXT:    and w9, w0, #0xffff
1676; GISEL-NEXT:    mov w8, #10 // =0xa
1677; GISEL-NEXT:    sub w9, w9, w1, uxth
1678; GISEL-NEXT:    cmp w9, w9, uxth
1679; GISEL-NEXT:    csel w0, w9, w8, ne
1680; GISEL-NEXT:    ret
1681entry:
1682  %m = call { i16, i1 } @llvm.usub.with.overflow.i16(i16 %a, i16 %b)
1683  %m1 = extractvalue { i16, i1 } %m, 0
1684  %m2 = extractvalue { i16, i1 } %m, 1
1685  %r = select i1 %m2, i16 %m1, i16 10
1686  ret i16 %r
1687}
1688
1689define i16 @ssubo.selectboth.i16(i16 %a, i16 %b) {
1690; CHECK-LABEL: ssubo.selectboth.i16:
1691; CHECK:       // %bb.0: // %entry
1692; CHECK-NEXT:    sxth w9, w0
1693; CHECK-NEXT:    mov w8, #10 // =0xa
1694; CHECK-NEXT:    sub w9, w9, w1, sxth
1695; CHECK-NEXT:    cmp w9, w9, sxth
1696; CHECK-NEXT:    csel w0, w9, w8, ne
1697; CHECK-NEXT:    ret
1698entry:
1699  %m = call { i16, i1 } @llvm.ssub.with.overflow.i16(i16 %a, i16 %b)
1700  %m1 = extractvalue { i16, i1 } %m, 0
1701  %m2 = extractvalue { i16, i1 } %m, 1
1702  %r = select i1 %m2, i16 %m1, i16 10
1703  ret i16 %r
1704}
1705
1706define i32 @usubo.selectboth.i32(i32 %a, i32 %b) {
1707; SDAG-LABEL: usubo.selectboth.i32:
1708; SDAG:       // %bb.0: // %entry
1709; SDAG-NEXT:    mov w8, #10 // =0xa
1710; SDAG-NEXT:    subs w9, w0, w1
1711; SDAG-NEXT:    csel w0, w9, w8, lo
1712; SDAG-NEXT:    ret
1713;
1714; FAST-LABEL: usubo.selectboth.i32:
1715; FAST:       // %bb.0: // %entry
1716; FAST-NEXT:    mov w8, #10 // =0xa
1717; FAST-NEXT:    subs w9, w0, w1
1718; FAST-NEXT:    csel w0, w9, w8, lo
1719; FAST-NEXT:    ret
1720;
1721; GISEL-LABEL: usubo.selectboth.i32:
1722; GISEL:       // %bb.0: // %entry
1723; GISEL-NEXT:    subs w9, w0, w1
1724; GISEL-NEXT:    mov w8, #10 // =0xa
1725; GISEL-NEXT:    cset w10, lo
1726; GISEL-NEXT:    tst w10, #0x1
1727; GISEL-NEXT:    csel w0, w9, w8, ne
1728; GISEL-NEXT:    ret
1729entry:
1730  %m = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %a, i32 %b)
1731  %m1 = extractvalue { i32, i1 } %m, 0
1732  %m2 = extractvalue { i32, i1 } %m, 1
1733  %r = select i1 %m2, i32 %m1, i32 10
1734  ret i32 %r
1735}
1736
1737define i32 @ssubo.selectboth.i32(i32 %a, i32 %b) {
1738; SDAG-LABEL: ssubo.selectboth.i32:
1739; SDAG:       // %bb.0: // %entry
1740; SDAG-NEXT:    mov w8, #10 // =0xa
1741; SDAG-NEXT:    subs w9, w0, w1
1742; SDAG-NEXT:    csel w0, w9, w8, vs
1743; SDAG-NEXT:    ret
1744;
1745; FAST-LABEL: ssubo.selectboth.i32:
1746; FAST:       // %bb.0: // %entry
1747; FAST-NEXT:    mov w8, #10 // =0xa
1748; FAST-NEXT:    subs w9, w0, w1
1749; FAST-NEXT:    csel w0, w9, w8, vs
1750; FAST-NEXT:    ret
1751;
1752; GISEL-LABEL: ssubo.selectboth.i32:
1753; GISEL:       // %bb.0: // %entry
1754; GISEL-NEXT:    subs w9, w0, w1
1755; GISEL-NEXT:    mov w8, #10 // =0xa
1756; GISEL-NEXT:    cset w10, vs
1757; GISEL-NEXT:    tst w10, #0x1
1758; GISEL-NEXT:    csel w0, w9, w8, ne
1759; GISEL-NEXT:    ret
1760entry:
1761  %m = call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %a, i32 %b)
1762  %m1 = extractvalue { i32, i1 } %m, 0
1763  %m2 = extractvalue { i32, i1 } %m, 1
1764  %r = select i1 %m2, i32 %m1, i32 10
1765  ret i32 %r
1766}
1767
1768define i64 @usubo.selectboth.i64(i64 %a, i64 %b) {
1769; SDAG-LABEL: usubo.selectboth.i64:
1770; SDAG:       // %bb.0: // %entry
1771; SDAG-NEXT:    mov w8, #10 // =0xa
1772; SDAG-NEXT:    subs x9, x0, x1
1773; SDAG-NEXT:    csel x0, x9, x8, lo
1774; SDAG-NEXT:    ret
1775;
1776; FAST-LABEL: usubo.selectboth.i64:
1777; FAST:       // %bb.0: // %entry
1778; FAST-NEXT:    mov x8, #10 // =0xa
1779; FAST-NEXT:    subs x9, x0, x1
1780; FAST-NEXT:    csel x0, x9, x8, lo
1781; FAST-NEXT:    ret
1782;
1783; GISEL-LABEL: usubo.selectboth.i64:
1784; GISEL:       // %bb.0: // %entry
1785; GISEL-NEXT:    subs x9, x0, x1
1786; GISEL-NEXT:    mov w8, #10 // =0xa
1787; GISEL-NEXT:    cset w10, lo
1788; GISEL-NEXT:    tst w10, #0x1
1789; GISEL-NEXT:    csel x0, x9, x8, ne
1790; GISEL-NEXT:    ret
1791entry:
1792  %m = call { i64, i1 } @llvm.usub.with.overflow.i64(i64 %a, i64 %b)
1793  %m1 = extractvalue { i64, i1 } %m, 0
1794  %m2 = extractvalue { i64, i1 } %m, 1
1795  %r = select i1 %m2, i64 %m1, i64 10
1796  ret i64 %r
1797}
1798
1799define i64 @ssubo.selectboth.i64(i64 %a, i64 %b) {
1800; SDAG-LABEL: ssubo.selectboth.i64:
1801; SDAG:       // %bb.0: // %entry
1802; SDAG-NEXT:    mov w8, #10 // =0xa
1803; SDAG-NEXT:    subs x9, x0, x1
1804; SDAG-NEXT:    csel x0, x9, x8, vs
1805; SDAG-NEXT:    ret
1806;
1807; FAST-LABEL: ssubo.selectboth.i64:
1808; FAST:       // %bb.0: // %entry
1809; FAST-NEXT:    mov x8, #10 // =0xa
1810; FAST-NEXT:    subs x9, x0, x1
1811; FAST-NEXT:    csel x0, x9, x8, vs
1812; FAST-NEXT:    ret
1813;
1814; GISEL-LABEL: ssubo.selectboth.i64:
1815; GISEL:       // %bb.0: // %entry
1816; GISEL-NEXT:    subs x9, x0, x1
1817; GISEL-NEXT:    mov w8, #10 // =0xa
1818; GISEL-NEXT:    cset w10, vs
1819; GISEL-NEXT:    tst w10, #0x1
1820; GISEL-NEXT:    csel x0, x9, x8, ne
1821; GISEL-NEXT:    ret
1822entry:
1823  %m = call { i64, i1 } @llvm.ssub.with.overflow.i64(i64 %a, i64 %b)
1824  %m1 = extractvalue { i64, i1 } %m, 0
1825  %m2 = extractvalue { i64, i1 } %m, 1
1826  %r = select i1 %m2, i64 %m1, i64 10
1827  ret i64 %r
1828}
1829
1830
1831define i8 @umulo.selectboth.i8(i8 %a, i8 %b) {
1832; SDAG-LABEL: umulo.selectboth.i8:
1833; SDAG:       // %bb.0: // %entry
1834; SDAG-NEXT:    and w9, w1, #0xff
1835; SDAG-NEXT:    and w10, w0, #0xff
1836; SDAG-NEXT:    mov w8, #10 // =0xa
1837; SDAG-NEXT:    mul w9, w10, w9
1838; SDAG-NEXT:    tst w9, #0xff00
1839; SDAG-NEXT:    csel w0, w9, w8, ne
1840; SDAG-NEXT:    ret
1841;
1842; FAST-LABEL: umulo.selectboth.i8:
1843; FAST:       // %bb.0: // %entry
1844; FAST-NEXT:    and w9, w1, #0xff
1845; FAST-NEXT:    and w10, w0, #0xff
1846; FAST-NEXT:    mov w8, #10 // =0xa
1847; FAST-NEXT:    mul w9, w10, w9
1848; FAST-NEXT:    tst w9, #0xff00
1849; FAST-NEXT:    csel w0, w9, w8, ne
1850; FAST-NEXT:    ret
1851;
1852; GISEL-LABEL: umulo.selectboth.i8:
1853; GISEL:       // %bb.0: // %entry
1854; GISEL-NEXT:    and w9, w0, #0xff
1855; GISEL-NEXT:    and w10, w1, #0xff
1856; GISEL-NEXT:    mov w8, #10 // =0xa
1857; GISEL-NEXT:    mul w9, w9, w10
1858; GISEL-NEXT:    cmp w9, w9, uxtb
1859; GISEL-NEXT:    csel w0, w9, w8, ne
1860; GISEL-NEXT:    ret
1861entry:
1862  %m = call { i8, i1 } @llvm.umul.with.overflow.i8(i8 %a, i8 %b)
1863  %m1 = extractvalue { i8, i1 } %m, 0
1864  %m2 = extractvalue { i8, i1 } %m, 1
1865  %r = select i1 %m2, i8 %m1, i8 10
1866  ret i8 %r
1867}
1868
1869define i8 @smulo.selectboth.i8(i8 %a, i8 %b) {
1870; SDAG-LABEL: smulo.selectboth.i8:
1871; SDAG:       // %bb.0: // %entry
1872; SDAG-NEXT:    sxtb w9, w1
1873; SDAG-NEXT:    sxtb w10, w0
1874; SDAG-NEXT:    mov w8, #10 // =0xa
1875; SDAG-NEXT:    mul w9, w10, w9
1876; SDAG-NEXT:    cmp w9, w9, sxtb
1877; SDAG-NEXT:    csel w0, w9, w8, ne
1878; SDAG-NEXT:    ret
1879;
1880; FAST-LABEL: smulo.selectboth.i8:
1881; FAST:       // %bb.0: // %entry
1882; FAST-NEXT:    sxtb w9, w1
1883; FAST-NEXT:    sxtb w10, w0
1884; FAST-NEXT:    mov w8, #10 // =0xa
1885; FAST-NEXT:    mul w9, w10, w9
1886; FAST-NEXT:    cmp w9, w9, sxtb
1887; FAST-NEXT:    csel w0, w9, w8, ne
1888; FAST-NEXT:    ret
1889;
1890; GISEL-LABEL: smulo.selectboth.i8:
1891; GISEL:       // %bb.0: // %entry
1892; GISEL-NEXT:    sxtb w9, w0
1893; GISEL-NEXT:    sxtb w10, w1
1894; GISEL-NEXT:    mov w8, #10 // =0xa
1895; GISEL-NEXT:    mul w9, w9, w10
1896; GISEL-NEXT:    cmp w9, w9, sxtb
1897; GISEL-NEXT:    csel w0, w9, w8, ne
1898; GISEL-NEXT:    ret
1899entry:
1900  %m = call { i8, i1 } @llvm.smul.with.overflow.i8(i8 %a, i8 %b)
1901  %m1 = extractvalue { i8, i1 } %m, 0
1902  %m2 = extractvalue { i8, i1 } %m, 1
1903  %r = select i1 %m2, i8 %m1, i8 10
1904  ret i8 %r
1905}
1906
1907define i16 @umulo.selectboth.i16(i16 %a, i16 %b) {
1908; SDAG-LABEL: umulo.selectboth.i16:
1909; SDAG:       // %bb.0: // %entry
1910; SDAG-NEXT:    and w9, w1, #0xffff
1911; SDAG-NEXT:    and w10, w0, #0xffff
1912; SDAG-NEXT:    mov w8, #10 // =0xa
1913; SDAG-NEXT:    mul w9, w10, w9
1914; SDAG-NEXT:    tst w9, #0xffff0000
1915; SDAG-NEXT:    csel w0, w9, w8, ne
1916; SDAG-NEXT:    ret
1917;
1918; FAST-LABEL: umulo.selectboth.i16:
1919; FAST:       // %bb.0: // %entry
1920; FAST-NEXT:    and w9, w1, #0xffff
1921; FAST-NEXT:    and w10, w0, #0xffff
1922; FAST-NEXT:    mov w8, #10 // =0xa
1923; FAST-NEXT:    mul w9, w10, w9
1924; FAST-NEXT:    tst w9, #0xffff0000
1925; FAST-NEXT:    csel w0, w9, w8, ne
1926; FAST-NEXT:    ret
1927;
1928; GISEL-LABEL: umulo.selectboth.i16:
1929; GISEL:       // %bb.0: // %entry
1930; GISEL-NEXT:    and w9, w0, #0xffff
1931; GISEL-NEXT:    and w10, w1, #0xffff
1932; GISEL-NEXT:    mov w8, #10 // =0xa
1933; GISEL-NEXT:    mul w9, w9, w10
1934; GISEL-NEXT:    cmp w9, w9, uxth
1935; GISEL-NEXT:    csel w0, w9, w8, ne
1936; GISEL-NEXT:    ret
1937entry:
1938  %m = call { i16, i1 } @llvm.umul.with.overflow.i16(i16 %a, i16 %b)
1939  %m1 = extractvalue { i16, i1 } %m, 0
1940  %m2 = extractvalue { i16, i1 } %m, 1
1941  %r = select i1 %m2, i16 %m1, i16 10
1942  ret i16 %r
1943}
1944
1945define i16 @smulo.selectboth.i16(i16 %a, i16 %b) {
1946; SDAG-LABEL: smulo.selectboth.i16:
1947; SDAG:       // %bb.0: // %entry
1948; SDAG-NEXT:    sxth w9, w1
1949; SDAG-NEXT:    sxth w10, w0
1950; SDAG-NEXT:    mov w8, #10 // =0xa
1951; SDAG-NEXT:    mul w9, w10, w9
1952; SDAG-NEXT:    cmp w9, w9, sxth
1953; SDAG-NEXT:    csel w0, w9, w8, ne
1954; SDAG-NEXT:    ret
1955;
1956; FAST-LABEL: smulo.selectboth.i16:
1957; FAST:       // %bb.0: // %entry
1958; FAST-NEXT:    sxth w9, w1
1959; FAST-NEXT:    sxth w10, w0
1960; FAST-NEXT:    mov w8, #10 // =0xa
1961; FAST-NEXT:    mul w9, w10, w9
1962; FAST-NEXT:    cmp w9, w9, sxth
1963; FAST-NEXT:    csel w0, w9, w8, ne
1964; FAST-NEXT:    ret
1965;
1966; GISEL-LABEL: smulo.selectboth.i16:
1967; GISEL:       // %bb.0: // %entry
1968; GISEL-NEXT:    sxth w9, w0
1969; GISEL-NEXT:    sxth w10, w1
1970; GISEL-NEXT:    mov w8, #10 // =0xa
1971; GISEL-NEXT:    mul w9, w9, w10
1972; GISEL-NEXT:    cmp w9, w9, sxth
1973; GISEL-NEXT:    csel w0, w9, w8, ne
1974; GISEL-NEXT:    ret
1975entry:
1976  %m = call { i16, i1 } @llvm.smul.with.overflow.i16(i16 %a, i16 %b)
1977  %m1 = extractvalue { i16, i1 } %m, 0
1978  %m2 = extractvalue { i16, i1 } %m, 1
1979  %r = select i1 %m2, i16 %m1, i16 10
1980  ret i16 %r
1981}
1982
1983define i32 @umulo.selectboth.i32(i32 %a, i32 %b) {
1984; SDAG-LABEL: umulo.selectboth.i32:
1985; SDAG:       // %bb.0: // %entry
1986; SDAG-NEXT:    umull x9, w0, w1
1987; SDAG-NEXT:    mov w8, #10 // =0xa
1988; SDAG-NEXT:    tst x9, #0xffffffff00000000
1989; SDAG-NEXT:    csel w0, w9, w8, ne
1990; SDAG-NEXT:    ret
1991;
1992; FAST-LABEL: umulo.selectboth.i32:
1993; FAST:       // %bb.0: // %entry
1994; FAST-NEXT:    umull x9, w0, w1
1995; FAST-NEXT:    mov w8, #10 // =0xa
1996; FAST-NEXT:    tst x9, #0xffffffff00000000
1997; FAST-NEXT:    csel w0, w9, w8, ne
1998; FAST-NEXT:    ret
1999;
2000; GISEL-LABEL: umulo.selectboth.i32:
2001; GISEL:       // %bb.0: // %entry
2002; GISEL-NEXT:    umull x9, w0, w1
2003; GISEL-NEXT:    mov w8, #10 // =0xa
2004; GISEL-NEXT:    mul w10, w0, w1
2005; GISEL-NEXT:    lsr x9, x9, #32
2006; GISEL-NEXT:    cmp w9, #0
2007; GISEL-NEXT:    csel w0, w10, w8, ne
2008; GISEL-NEXT:    ret
2009entry:
2010  %m = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %a, i32 %b)
2011  %m1 = extractvalue { i32, i1 } %m, 0
2012  %m2 = extractvalue { i32, i1 } %m, 1
2013  %r = select i1 %m2, i32 %m1, i32 10
2014  ret i32 %r
2015}
2016
2017define i32 @smulo.selectboth.i32(i32 %a, i32 %b) {
2018; SDAG-LABEL: smulo.selectboth.i32:
2019; SDAG:       // %bb.0: // %entry
2020; SDAG-NEXT:    smull x9, w0, w1
2021; SDAG-NEXT:    mov w8, #10 // =0xa
2022; SDAG-NEXT:    cmp x9, w9, sxtw
2023; SDAG-NEXT:    csel w0, w9, w8, ne
2024; SDAG-NEXT:    ret
2025;
2026; FAST-LABEL: smulo.selectboth.i32:
2027; FAST:       // %bb.0: // %entry
2028; FAST-NEXT:    smull x9, w0, w1
2029; FAST-NEXT:    mov w8, #10 // =0xa
2030; FAST-NEXT:    cmp x9, w9, sxtw
2031; FAST-NEXT:    csel w0, w9, w8, ne
2032; FAST-NEXT:    ret
2033;
2034; GISEL-LABEL: smulo.selectboth.i32:
2035; GISEL:       // %bb.0: // %entry
2036; GISEL-NEXT:    smull x9, w0, w1
2037; GISEL-NEXT:    mov w8, #10 // =0xa
2038; GISEL-NEXT:    mul w10, w0, w1
2039; GISEL-NEXT:    asr x9, x9, #32
2040; GISEL-NEXT:    cmp w9, w10, asr #31
2041; GISEL-NEXT:    csel w0, w10, w8, ne
2042; GISEL-NEXT:    ret
2043entry:
2044  %m = call { i32, i1 } @llvm.smul.with.overflow.i32(i32 %a, i32 %b)
2045  %m1 = extractvalue { i32, i1 } %m, 0
2046  %m2 = extractvalue { i32, i1 } %m, 1
2047  %r = select i1 %m2, i32 %m1, i32 10
2048  ret i32 %r
2049}
2050
2051define i64 @umulo.selectboth.i64(i64 %a, i64 %b) {
2052; SDAG-LABEL: umulo.selectboth.i64:
2053; SDAG:       // %bb.0: // %entry
2054; SDAG-NEXT:    umulh x9, x0, x1
2055; SDAG-NEXT:    mov w8, #10 // =0xa
2056; SDAG-NEXT:    mul x10, x0, x1
2057; SDAG-NEXT:    cmp xzr, x9
2058; SDAG-NEXT:    csel x0, x10, x8, ne
2059; SDAG-NEXT:    ret
2060;
2061; FAST-LABEL: umulo.selectboth.i64:
2062; FAST:       // %bb.0: // %entry
2063; FAST-NEXT:    umulh x9, x0, x1
2064; FAST-NEXT:    mov x8, #10 // =0xa
2065; FAST-NEXT:    mul x10, x0, x1
2066; FAST-NEXT:    cmp xzr, x9
2067; FAST-NEXT:    csel x0, x10, x8, ne
2068; FAST-NEXT:    ret
2069;
2070; GISEL-LABEL: umulo.selectboth.i64:
2071; GISEL:       // %bb.0: // %entry
2072; GISEL-NEXT:    umulh x9, x0, x1
2073; GISEL-NEXT:    mov w8, #10 // =0xa
2074; GISEL-NEXT:    mul x10, x0, x1
2075; GISEL-NEXT:    cmp x9, #0
2076; GISEL-NEXT:    csel x0, x10, x8, ne
2077; GISEL-NEXT:    ret
2078entry:
2079  %m = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 %a, i64 %b)
2080  %m1 = extractvalue { i64, i1 } %m, 0
2081  %m2 = extractvalue { i64, i1 } %m, 1
2082  %r = select i1 %m2, i64 %m1, i64 10
2083  ret i64 %r
2084}
2085
2086define i64 @smulo.selectboth.i64(i64 %a, i64 %b) {
2087; SDAG-LABEL: smulo.selectboth.i64:
2088; SDAG:       // %bb.0: // %entry
2089; SDAG-NEXT:    mul x9, x0, x1
2090; SDAG-NEXT:    mov w8, #10 // =0xa
2091; SDAG-NEXT:    smulh x10, x0, x1
2092; SDAG-NEXT:    cmp x10, x9, asr #63
2093; SDAG-NEXT:    csel x0, x9, x8, ne
2094; SDAG-NEXT:    ret
2095;
2096; FAST-LABEL: smulo.selectboth.i64:
2097; FAST:       // %bb.0: // %entry
2098; FAST-NEXT:    mul x9, x0, x1
2099; FAST-NEXT:    mov x8, #10 // =0xa
2100; FAST-NEXT:    smulh x10, x0, x1
2101; FAST-NEXT:    cmp x10, x9, asr #63
2102; FAST-NEXT:    csel x0, x9, x8, ne
2103; FAST-NEXT:    ret
2104;
2105; GISEL-LABEL: smulo.selectboth.i64:
2106; GISEL:       // %bb.0: // %entry
2107; GISEL-NEXT:    smulh x9, x0, x1
2108; GISEL-NEXT:    mov w8, #10 // =0xa
2109; GISEL-NEXT:    mul x10, x0, x1
2110; GISEL-NEXT:    cmp x9, x10, asr #63
2111; GISEL-NEXT:    csel x0, x10, x8, ne
2112; GISEL-NEXT:    ret
2113entry:
2114  %m = call { i64, i1 } @llvm.smul.with.overflow.i64(i64 %a, i64 %b)
2115  %m1 = extractvalue { i64, i1 } %m, 0
2116  %m2 = extractvalue { i64, i1 } %m, 1
2117  %r = select i1 %m2, i64 %m1, i64 10
2118  ret i64 %r
2119}
2120
2121
2122;
2123; Check the use of the overflow bit in combination with a branch instruction.
2124;
2125define zeroext i1 @saddo.br.i32(i32 %v1, i32 %v2) {
2126; SDAG-LABEL: saddo.br.i32:
2127; SDAG:       // %bb.0: // %entry
2128; SDAG-NEXT:    cmn w0, w1
2129; SDAG-NEXT:    cset w0, vc
2130; SDAG-NEXT:    ret
2131;
2132; FAST-LABEL: saddo.br.i32:
2133; FAST:       // %bb.0: // %entry
2134; FAST-NEXT:    cmn w0, w1
2135; FAST-NEXT:    mov w8, #1 // =0x1
2136; FAST-NEXT:    cset w9, vs
2137; FAST-NEXT:    bic w8, w8, w9
2138; FAST-NEXT:    and w0, w8, #0x1
2139; FAST-NEXT:    ret
2140;
2141; GISEL-LABEL: saddo.br.i32:
2142; GISEL:       // %bb.0: // %entry
2143; GISEL-NEXT:    cmn w0, w1
2144; GISEL-NEXT:    cset w8, vs
2145; GISEL-NEXT:    eor w0, w8, #0x1
2146; GISEL-NEXT:    ret
2147entry:
2148  %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2)
2149  %val = extractvalue {i32, i1} %t, 0
2150  %obit = extractvalue {i32, i1} %t, 1
2151  br i1 %obit, label %overflow, label %continue
2152
2153overflow:
2154  ret i1 false
2155
2156continue:
2157  ret i1 true
2158}
2159
2160define zeroext i1 @saddo.br.i64(i64 %v1, i64 %v2) {
2161; SDAG-LABEL: saddo.br.i64:
2162; SDAG:       // %bb.0: // %entry
2163; SDAG-NEXT:    cmn x0, x1
2164; SDAG-NEXT:    cset w0, vc
2165; SDAG-NEXT:    ret
2166;
2167; FAST-LABEL: saddo.br.i64:
2168; FAST:       // %bb.0: // %entry
2169; FAST-NEXT:    cmn x0, x1
2170; FAST-NEXT:    mov w8, #1 // =0x1
2171; FAST-NEXT:    cset w9, vs
2172; FAST-NEXT:    bic w8, w8, w9
2173; FAST-NEXT:    and w0, w8, #0x1
2174; FAST-NEXT:    ret
2175;
2176; GISEL-LABEL: saddo.br.i64:
2177; GISEL:       // %bb.0: // %entry
2178; GISEL-NEXT:    cmn x0, x1
2179; GISEL-NEXT:    cset w8, vs
2180; GISEL-NEXT:    eor w0, w8, #0x1
2181; GISEL-NEXT:    ret
2182entry:
2183  %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2)
2184  %val = extractvalue {i64, i1} %t, 0
2185  %obit = extractvalue {i64, i1} %t, 1
2186  br i1 %obit, label %overflow, label %continue
2187
2188overflow:
2189  ret i1 false
2190
2191continue:
2192  ret i1 true
2193}
2194
2195define zeroext i1 @uaddo.br.i32(i32 %v1, i32 %v2) {
2196; SDAG-LABEL: uaddo.br.i32:
2197; SDAG:       // %bb.0: // %entry
2198; SDAG-NEXT:    cmn w0, w1
2199; SDAG-NEXT:    cset w0, lo
2200; SDAG-NEXT:    ret
2201;
2202; FAST-LABEL: uaddo.br.i32:
2203; FAST:       // %bb.0: // %entry
2204; FAST-NEXT:    cmn w0, w1
2205; FAST-NEXT:    mov w8, #1 // =0x1
2206; FAST-NEXT:    cset w9, hs
2207; FAST-NEXT:    bic w8, w8, w9
2208; FAST-NEXT:    and w0, w8, #0x1
2209; FAST-NEXT:    ret
2210;
2211; GISEL-LABEL: uaddo.br.i32:
2212; GISEL:       // %bb.0: // %entry
2213; GISEL-NEXT:    cmn w0, w1
2214; GISEL-NEXT:    cset w8, hs
2215; GISEL-NEXT:    eor w0, w8, #0x1
2216; GISEL-NEXT:    ret
2217entry:
2218  %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)
2219  %val = extractvalue {i32, i1} %t, 0
2220  %obit = extractvalue {i32, i1} %t, 1
2221  br i1 %obit, label %overflow, label %continue
2222
2223overflow:
2224  ret i1 false
2225
2226continue:
2227  ret i1 true
2228}
2229
2230define zeroext i1 @uaddo.br.i64(i64 %v1, i64 %v2) {
2231; SDAG-LABEL: uaddo.br.i64:
2232; SDAG:       // %bb.0: // %entry
2233; SDAG-NEXT:    cmn x0, x1
2234; SDAG-NEXT:    cset w0, lo
2235; SDAG-NEXT:    ret
2236;
2237; FAST-LABEL: uaddo.br.i64:
2238; FAST:       // %bb.0: // %entry
2239; FAST-NEXT:    cmn x0, x1
2240; FAST-NEXT:    mov w8, #1 // =0x1
2241; FAST-NEXT:    cset w9, hs
2242; FAST-NEXT:    bic w8, w8, w9
2243; FAST-NEXT:    and w0, w8, #0x1
2244; FAST-NEXT:    ret
2245;
2246; GISEL-LABEL: uaddo.br.i64:
2247; GISEL:       // %bb.0: // %entry
2248; GISEL-NEXT:    cmn x0, x1
2249; GISEL-NEXT:    cset w8, hs
2250; GISEL-NEXT:    eor w0, w8, #0x1
2251; GISEL-NEXT:    ret
2252entry:
2253  %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2)
2254  %val = extractvalue {i64, i1} %t, 0
2255  %obit = extractvalue {i64, i1} %t, 1
2256  br i1 %obit, label %overflow, label %continue
2257
2258overflow:
2259  ret i1 false
2260
2261continue:
2262  ret i1 true
2263}
2264
2265define zeroext i1 @ssubo.br.i32(i32 %v1, i32 %v2) {
2266; SDAG-LABEL: ssubo.br.i32:
2267; SDAG:       // %bb.0: // %entry
2268; SDAG-NEXT:    cmp w0, w1
2269; SDAG-NEXT:    cset w0, vc
2270; SDAG-NEXT:    ret
2271;
2272; FAST-LABEL: ssubo.br.i32:
2273; FAST:       // %bb.0: // %entry
2274; FAST-NEXT:    cmp w0, w1
2275; FAST-NEXT:    mov w8, #1 // =0x1
2276; FAST-NEXT:    cset w9, vs
2277; FAST-NEXT:    bic w8, w8, w9
2278; FAST-NEXT:    and w0, w8, #0x1
2279; FAST-NEXT:    ret
2280;
2281; GISEL-LABEL: ssubo.br.i32:
2282; GISEL:       // %bb.0: // %entry
2283; GISEL-NEXT:    cmp w0, w1
2284; GISEL-NEXT:    cset w8, vs
2285; GISEL-NEXT:    eor w0, w8, #0x1
2286; GISEL-NEXT:    ret
2287entry:
2288  %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2)
2289  %val = extractvalue {i32, i1} %t, 0
2290  %obit = extractvalue {i32, i1} %t, 1
2291  br i1 %obit, label %overflow, label %continue
2292
2293overflow:
2294  ret i1 false
2295
2296continue:
2297  ret i1 true
2298}
2299
2300define zeroext i1 @ssubo.br.i64(i64 %v1, i64 %v2) {
2301; SDAG-LABEL: ssubo.br.i64:
2302; SDAG:       // %bb.0: // %entry
2303; SDAG-NEXT:    cmp x0, x1
2304; SDAG-NEXT:    cset w0, vc
2305; SDAG-NEXT:    ret
2306;
2307; FAST-LABEL: ssubo.br.i64:
2308; FAST:       // %bb.0: // %entry
2309; FAST-NEXT:    cmp x0, x1
2310; FAST-NEXT:    mov w8, #1 // =0x1
2311; FAST-NEXT:    cset w9, vs
2312; FAST-NEXT:    bic w8, w8, w9
2313; FAST-NEXT:    and w0, w8, #0x1
2314; FAST-NEXT:    ret
2315;
2316; GISEL-LABEL: ssubo.br.i64:
2317; GISEL:       // %bb.0: // %entry
2318; GISEL-NEXT:    cmp x0, x1
2319; GISEL-NEXT:    cset w8, vs
2320; GISEL-NEXT:    eor w0, w8, #0x1
2321; GISEL-NEXT:    ret
2322entry:
2323  %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2)
2324  %val = extractvalue {i64, i1} %t, 0
2325  %obit = extractvalue {i64, i1} %t, 1
2326  br i1 %obit, label %overflow, label %continue
2327
2328overflow:
2329  ret i1 false
2330
2331continue:
2332  ret i1 true
2333}
2334
2335define zeroext i1 @usubo.br.i32(i32 %v1, i32 %v2) {
2336; SDAG-LABEL: usubo.br.i32:
2337; SDAG:       // %bb.0: // %entry
2338; SDAG-NEXT:    cmp w0, w1
2339; SDAG-NEXT:    cset w0, hs
2340; SDAG-NEXT:    ret
2341;
2342; FAST-LABEL: usubo.br.i32:
2343; FAST:       // %bb.0: // %entry
2344; FAST-NEXT:    cmp w0, w1
2345; FAST-NEXT:    mov w8, #1 // =0x1
2346; FAST-NEXT:    cset w9, lo
2347; FAST-NEXT:    bic w8, w8, w9
2348; FAST-NEXT:    and w0, w8, #0x1
2349; FAST-NEXT:    ret
2350;
2351; GISEL-LABEL: usubo.br.i32:
2352; GISEL:       // %bb.0: // %entry
2353; GISEL-NEXT:    cmp w0, w1
2354; GISEL-NEXT:    cset w8, lo
2355; GISEL-NEXT:    eor w0, w8, #0x1
2356; GISEL-NEXT:    ret
2357entry:
2358  %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2)
2359  %val = extractvalue {i32, i1} %t, 0
2360  %obit = extractvalue {i32, i1} %t, 1
2361  br i1 %obit, label %overflow, label %continue
2362
2363overflow:
2364  ret i1 false
2365
2366continue:
2367  ret i1 true
2368}
2369
2370define zeroext i1 @usubo.br.i64(i64 %v1, i64 %v2) {
2371; SDAG-LABEL: usubo.br.i64:
2372; SDAG:       // %bb.0: // %entry
2373; SDAG-NEXT:    cmp x0, x1
2374; SDAG-NEXT:    cset w0, hs
2375; SDAG-NEXT:    ret
2376;
2377; FAST-LABEL: usubo.br.i64:
2378; FAST:       // %bb.0: // %entry
2379; FAST-NEXT:    cmp x0, x1
2380; FAST-NEXT:    mov w8, #1 // =0x1
2381; FAST-NEXT:    cset w9, lo
2382; FAST-NEXT:    bic w8, w8, w9
2383; FAST-NEXT:    and w0, w8, #0x1
2384; FAST-NEXT:    ret
2385;
2386; GISEL-LABEL: usubo.br.i64:
2387; GISEL:       // %bb.0: // %entry
2388; GISEL-NEXT:    cmp x0, x1
2389; GISEL-NEXT:    cset w8, lo
2390; GISEL-NEXT:    eor w0, w8, #0x1
2391; GISEL-NEXT:    ret
2392entry:
2393  %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2)
2394  %val = extractvalue {i64, i1} %t, 0
2395  %obit = extractvalue {i64, i1} %t, 1
2396  br i1 %obit, label %overflow, label %continue
2397
2398overflow:
2399  ret i1 false
2400
2401continue:
2402  ret i1 true
2403}
2404
2405define zeroext i1 @smulo.br.i32(i32 %v1, i32 %v2) {
2406; SDAG-LABEL: smulo.br.i32:
2407; SDAG:       // %bb.0: // %entry
2408; SDAG-NEXT:    smull x8, w0, w1
2409; SDAG-NEXT:    cmp x8, w8, sxtw
2410; SDAG-NEXT:    cset w0, eq
2411; SDAG-NEXT:    ret
2412;
2413; FAST-LABEL: smulo.br.i32:
2414; FAST:       // %bb.0: // %entry
2415; FAST-NEXT:    smull x9, w0, w1
2416; FAST-NEXT:    mov w8, #1 // =0x1
2417; FAST-NEXT:    cmp x9, w9, sxtw
2418; FAST-NEXT:    cset w9, ne
2419; FAST-NEXT:    bic w8, w8, w9
2420; FAST-NEXT:    and w0, w8, #0x1
2421; FAST-NEXT:    ret
2422;
2423; GISEL-LABEL: smulo.br.i32:
2424; GISEL:       // %bb.0: // %entry
2425; GISEL-NEXT:    smull x8, w0, w1
2426; GISEL-NEXT:    mul w9, w0, w1
2427; GISEL-NEXT:    asr x8, x8, #32
2428; GISEL-NEXT:    cmp w8, w9, asr #31
2429; GISEL-NEXT:    cset w8, ne
2430; GISEL-NEXT:    eor w0, w8, #0x1
2431; GISEL-NEXT:    ret
2432entry:
2433  %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
2434  %val = extractvalue {i32, i1} %t, 0
2435  %obit = extractvalue {i32, i1} %t, 1
2436  br i1 %obit, label %overflow, label %continue
2437
2438overflow:
2439  ret i1 false
2440
2441continue:
2442  ret i1 true
2443}
2444
2445define zeroext i1 @smulo.br.i64(i64 %v1, i64 %v2) {
2446; SDAG-LABEL: smulo.br.i64:
2447; SDAG:       // %bb.0: // %entry
2448; SDAG-NEXT:    mul x8, x0, x1
2449; SDAG-NEXT:    smulh x9, x0, x1
2450; SDAG-NEXT:    cmp x9, x8, asr #63
2451; SDAG-NEXT:    cset w0, eq
2452; SDAG-NEXT:    ret
2453;
2454; FAST-LABEL: smulo.br.i64:
2455; FAST:       // %bb.0: // %entry
2456; FAST-NEXT:    mul x9, x0, x1
2457; FAST-NEXT:    mov w8, #1 // =0x1
2458; FAST-NEXT:    smulh x10, x0, x1
2459; FAST-NEXT:    cmp x10, x9, asr #63
2460; FAST-NEXT:    cset w9, ne
2461; FAST-NEXT:    bic w8, w8, w9
2462; FAST-NEXT:    and w0, w8, #0x1
2463; FAST-NEXT:    ret
2464;
2465; GISEL-LABEL: smulo.br.i64:
2466; GISEL:       // %bb.0: // %entry
2467; GISEL-NEXT:    smulh x8, x0, x1
2468; GISEL-NEXT:    mul x9, x0, x1
2469; GISEL-NEXT:    cmp x8, x9, asr #63
2470; GISEL-NEXT:    cset w8, ne
2471; GISEL-NEXT:    eor w0, w8, #0x1
2472; GISEL-NEXT:    ret
2473entry:
2474  %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
2475  %val = extractvalue {i64, i1} %t, 0
2476  %obit = extractvalue {i64, i1} %t, 1
2477  br i1 %obit, label %overflow, label %continue
2478
2479overflow:
2480  ret i1 false
2481
2482continue:
2483  ret i1 true
2484}
2485
2486define zeroext i1 @smulo2.br.i64(i64 %v1) {
2487; SDAG-LABEL: smulo2.br.i64:
2488; SDAG:       // %bb.0: // %entry
2489; SDAG-NEXT:    cmn x0, x0
2490; SDAG-NEXT:    cset w0, vc
2491; SDAG-NEXT:    ret
2492;
2493; FAST-LABEL: smulo2.br.i64:
2494; FAST:       // %bb.0: // %entry
2495; FAST-NEXT:    cmn x0, x0
2496; FAST-NEXT:    mov w8, #1 // =0x1
2497; FAST-NEXT:    cset w9, vs
2498; FAST-NEXT:    bic w8, w8, w9
2499; FAST-NEXT:    and w0, w8, #0x1
2500; FAST-NEXT:    ret
2501;
2502; GISEL-LABEL: smulo2.br.i64:
2503; GISEL:       // %bb.0: // %entry
2504; GISEL-NEXT:    cmn x0, x0
2505; GISEL-NEXT:    cset w8, vs
2506; GISEL-NEXT:    eor w0, w8, #0x1
2507; GISEL-NEXT:    ret
2508entry:
2509  %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 2)
2510  %val = extractvalue {i64, i1} %t, 0
2511  %obit = extractvalue {i64, i1} %t, 1
2512  br i1 %obit, label %overflow, label %continue
2513
2514overflow:
2515  ret i1 false
2516
2517continue:
2518  ret i1 true
2519}
2520
2521define zeroext i1 @umulo.br.i32(i32 %v1, i32 %v2) {
2522; SDAG-LABEL: umulo.br.i32:
2523; SDAG:       // %bb.0: // %entry
2524; SDAG-NEXT:    umull x8, w0, w1
2525; SDAG-NEXT:    tst x8, #0xffffffff00000000
2526; SDAG-NEXT:    cset w0, eq
2527; SDAG-NEXT:    ret
2528;
2529; FAST-LABEL: umulo.br.i32:
2530; FAST:       // %bb.0: // %entry
2531; FAST-NEXT:    umull x9, w0, w1
2532; FAST-NEXT:    mov w8, #1 // =0x1
2533; FAST-NEXT:    tst x9, #0xffffffff00000000
2534; FAST-NEXT:    cset w9, ne
2535; FAST-NEXT:    bic w8, w8, w9
2536; FAST-NEXT:    and w0, w8, #0x1
2537; FAST-NEXT:    ret
2538;
2539; GISEL-LABEL: umulo.br.i32:
2540; GISEL:       // %bb.0: // %entry
2541; GISEL-NEXT:    umull x8, w0, w1
2542; GISEL-NEXT:    lsr x8, x8, #32
2543; GISEL-NEXT:    cmp w8, #0
2544; GISEL-NEXT:    cset w8, ne
2545; GISEL-NEXT:    eor w0, w8, #0x1
2546; GISEL-NEXT:    ret
2547entry:
2548  %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
2549  %val = extractvalue {i32, i1} %t, 0
2550  %obit = extractvalue {i32, i1} %t, 1
2551  br i1 %obit, label %overflow, label %continue
2552
2553overflow:
2554  ret i1 false
2555
2556continue:
2557  ret i1 true
2558}
2559
2560define zeroext i1 @umulo.br.i64(i64 %v1, i64 %v2) {
2561; SDAG-LABEL: umulo.br.i64:
2562; SDAG:       // %bb.0: // %entry
2563; SDAG-NEXT:    umulh x8, x0, x1
2564; SDAG-NEXT:    cmp xzr, x8
2565; SDAG-NEXT:    cset w0, eq
2566; SDAG-NEXT:    ret
2567;
2568; FAST-LABEL: umulo.br.i64:
2569; FAST:       // %bb.0: // %entry
2570; FAST-NEXT:    umulh x9, x0, x1
2571; FAST-NEXT:    mov w8, #1 // =0x1
2572; FAST-NEXT:    cmp xzr, x9
2573; FAST-NEXT:    cset w9, ne
2574; FAST-NEXT:    bic w8, w8, w9
2575; FAST-NEXT:    and w0, w8, #0x1
2576; FAST-NEXT:    ret
2577;
2578; GISEL-LABEL: umulo.br.i64:
2579; GISEL:       // %bb.0: // %entry
2580; GISEL-NEXT:    umulh x8, x0, x1
2581; GISEL-NEXT:    cmp x8, #0
2582; GISEL-NEXT:    cset w8, ne
2583; GISEL-NEXT:    eor w0, w8, #0x1
2584; GISEL-NEXT:    ret
2585entry:
2586  %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
2587  %val = extractvalue {i64, i1} %t, 0
2588  %obit = extractvalue {i64, i1} %t, 1
2589  br i1 %obit, label %overflow, label %continue
2590
2591overflow:
2592  ret i1 false
2593
2594continue:
2595  ret i1 true
2596}
2597
2598define zeroext i1 @umulo2.br.i64(i64 %v1) {
2599; SDAG-LABEL: umulo2.br.i64:
2600; SDAG:       // %bb.0: // %entry
2601; SDAG-NEXT:    cmn x0, x0
2602; SDAG-NEXT:    cset w0, lo
2603; SDAG-NEXT:    ret
2604;
2605; FAST-LABEL: umulo2.br.i64:
2606; FAST:       // %bb.0: // %entry
2607; FAST-NEXT:    cmn x0, x0
2608; FAST-NEXT:    mov w8, #1 // =0x1
2609; FAST-NEXT:    cset w9, hs
2610; FAST-NEXT:    bic w8, w8, w9
2611; FAST-NEXT:    and w0, w8, #0x1
2612; FAST-NEXT:    ret
2613;
2614; GISEL-LABEL: umulo2.br.i64:
2615; GISEL:       // %bb.0: // %entry
2616; GISEL-NEXT:    cmn x0, x0
2617; GISEL-NEXT:    cset w8, hs
2618; GISEL-NEXT:    eor w0, w8, #0x1
2619; GISEL-NEXT:    ret
2620entry:
2621  %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 2)
2622  %val = extractvalue {i64, i1} %t, 0
2623  %obit = extractvalue {i64, i1} %t, 1
2624  br i1 %obit, label %overflow, label %continue
2625
2626overflow:
2627  ret i1 false
2628
2629continue:
2630  ret i1 true
2631}
2632
2633define i8 @pr60530() {
2634; SDAG-LABEL: pr60530:
2635; SDAG:       // %bb.0:
2636; SDAG-NEXT:    mov w0, #-1 // =0xffffffff
2637; SDAG-NEXT:    ret
2638;
2639; FAST-LABEL: pr60530:
2640; FAST:       // %bb.0:
2641; FAST-NEXT:    mov w0, #-1 // =0xffffffff
2642; FAST-NEXT:    ret
2643;
2644; GISEL-LABEL: pr60530:
2645; GISEL:       // %bb.0:
2646; GISEL-NEXT:    mov w0, #255 // =0xff
2647; GISEL-NEXT:    ret
2648  %1 = call { i8, i1 } @llvm.uadd.with.overflow.i8(i8 0, i8 1)
2649  %2 = extractvalue { i8, i1 } %1, 1
2650  %3 = zext i1 %2 to i8
2651  %4 = shl i8 -1, %3
2652  %5 = lshr i8 1, %4
2653  %6 = icmp uge i8 %5, 1
2654  %7 = sext i1 %6 to i8
2655  %8 = zext i1 %2 to i8
2656  %9 = icmp uge i8 %7, %8
2657  %10 = sext i1 %9 to i8
2658  ret i8 %10
2659}
2660
2661declare {i8, i1} @llvm.sadd.with.overflow.i8(i8, i8) nounwind readnone
2662declare {i16, i1} @llvm.sadd.with.overflow.i16(i16, i16) nounwind readnone
2663declare {i32, i1} @llvm.sadd.with.overflow.i32(i32, i32) nounwind readnone
2664declare {i64, i1} @llvm.sadd.with.overflow.i64(i64, i64) nounwind readnone
2665declare {i8, i1} @llvm.uadd.with.overflow.i8(i8, i8) nounwind readnone
2666declare {i16, i1} @llvm.uadd.with.overflow.i16(i16, i16) nounwind readnone
2667declare {i32, i1} @llvm.uadd.with.overflow.i32(i32, i32) nounwind readnone
2668declare {i64, i1} @llvm.uadd.with.overflow.i64(i64, i64) nounwind readnone
2669declare {i8, i1} @llvm.ssub.with.overflow.i8(i8, i8) nounwind readnone
2670declare {i16, i1} @llvm.ssub.with.overflow.i16(i16, i16) nounwind readnone
2671declare {i32, i1} @llvm.ssub.with.overflow.i32(i32, i32) nounwind readnone
2672declare {i64, i1} @llvm.ssub.with.overflow.i64(i64, i64) nounwind readnone
2673declare {i8, i1} @llvm.usub.with.overflow.i8(i8, i8) nounwind readnone
2674declare {i16, i1} @llvm.usub.with.overflow.i16(i16, i16) nounwind readnone
2675declare {i32, i1} @llvm.usub.with.overflow.i32(i32, i32) nounwind readnone
2676declare {i64, i1} @llvm.usub.with.overflow.i64(i64, i64) nounwind readnone
2677declare {i8, i1} @llvm.smul.with.overflow.i8(i8, i8) nounwind readnone
2678declare {i16, i1} @llvm.smul.with.overflow.i16(i16, i16) nounwind readnone
2679declare {i32, i1} @llvm.smul.with.overflow.i32(i32, i32) nounwind readnone
2680declare {i64, i1} @llvm.smul.with.overflow.i64(i64, i64) nounwind readnone
2681declare {i8, i1} @llvm.umul.with.overflow.i8(i8, i8) nounwind readnone
2682declare {i16, i1} @llvm.umul.with.overflow.i16(i16, i16) nounwind readnone
2683declare {i32, i1} @llvm.umul.with.overflow.i32(i32, i32) nounwind readnone
2684declare {i64, i1} @llvm.umul.with.overflow.i64(i64, i64) nounwind readnone
2685
2686