• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; RUN: llc < %s -mtriple=arm64-eabi -aarch64-enable-atomic-cfg-tidy=0 -disable-post-ra -verify-machineinstrs | FileCheck %s
2; RUN: llc < %s -mtriple=arm64-eabi -aarch64-enable-atomic-cfg-tidy=0 -fast-isel -fast-isel-abort=1 -disable-post-ra -verify-machineinstrs | FileCheck %s
3
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 i1 @saddo.not.i32(i32 %v1, i32 %v2) {
286entry:
287; CHECK-LABEL:  saddo.not.i32
288; CHECK:        cmn w0, w1
289; CHECK-NEXT:   cset w0, vc
290  %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2)
291  %obit = extractvalue {i32, i1} %t, 1
292  %ret = xor i1 %obit, true
293  ret i1 %ret
294}
295
296define i64 @saddo.select.i64(i64 %v1, i64 %v2) {
297entry:
298; CHECK-LABEL:  saddo.select.i64
299; CHECK:        cmn x0, x1
300; CHECK-NEXT:   csel x0, x0, x1, vs
301  %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2)
302  %obit = extractvalue {i64, i1} %t, 1
303  %ret = select i1 %obit, i64 %v1, i64 %v2
304  ret i64 %ret
305}
306
307define i1 @saddo.not.i64(i64 %v1, i64 %v2) {
308entry:
309; CHECK-LABEL:  saddo.not.i64
310; CHECK:        cmn x0, x1
311; CHECK-NEXT:   cset w0, vc
312  %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2)
313  %obit = extractvalue {i64, i1} %t, 1
314  %ret = xor i1 %obit, true
315  ret i1 %ret
316}
317
318define i32 @uaddo.select.i32(i32 %v1, i32 %v2) {
319entry:
320; CHECK-LABEL:  uaddo.select.i32
321; CHECK:        cmn w0, w1
322; CHECK-NEXT:   csel w0, w0, w1, hs
323  %t = call {i32, i1} @llvm.uadd.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 i1 @uaddo.not.i32(i32 %v1, i32 %v2) {
330entry:
331; CHECK-LABEL:  uaddo.not.i32
332; CHECK:        cmn w0, w1
333; CHECK-NEXT:   cset w0, lo
334  %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)
335  %obit = extractvalue {i32, i1} %t, 1
336  %ret = xor i1 %obit, true
337  ret i1 %ret
338}
339
340define i64 @uaddo.select.i64(i64 %v1, i64 %v2) {
341entry:
342; CHECK-LABEL:  uaddo.select.i64
343; CHECK:        cmn x0, x1
344; CHECK-NEXT:   csel x0, x0, x1, hs
345  %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2)
346  %obit = extractvalue {i64, i1} %t, 1
347  %ret = select i1 %obit, i64 %v1, i64 %v2
348  ret i64 %ret
349}
350
351define i1 @uaddo.not.i64(i64 %v1, i64 %v2) {
352entry:
353; CHECK-LABEL:  uaddo.not.i64
354; CHECK:        cmn x0, x1
355; CHECK-NEXT:   cset w0, lo
356  %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2)
357  %obit = extractvalue {i64, i1} %t, 1
358  %ret = xor i1 %obit, true
359  ret i1 %ret
360}
361
362define i32 @ssubo.select.i32(i32 %v1, i32 %v2) {
363entry:
364; CHECK-LABEL:  ssubo.select.i32
365; CHECK:        cmp w0, w1
366; CHECK-NEXT:   csel w0, w0, w1, vs
367  %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2)
368  %obit = extractvalue {i32, i1} %t, 1
369  %ret = select i1 %obit, i32 %v1, i32 %v2
370  ret i32 %ret
371}
372
373define i1 @ssubo.not.i32(i32 %v1, i32 %v2) {
374entry:
375; CHECK-LABEL:  ssubo.not.i32
376; CHECK:        cmp w0, w1
377; CHECK-NEXT:   cset w0, vc
378  %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2)
379  %obit = extractvalue {i32, i1} %t, 1
380  %ret = xor i1 %obit, true
381  ret i1 %ret
382}
383
384define i64 @ssubo.select.i64(i64 %v1, i64 %v2) {
385entry:
386; CHECK-LABEL:  ssubo.select.i64
387; CHECK:        cmp x0, x1
388; CHECK-NEXT:   csel x0, x0, x1, vs
389  %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2)
390  %obit = extractvalue {i64, i1} %t, 1
391  %ret = select i1 %obit, i64 %v1, i64 %v2
392  ret i64 %ret
393}
394
395define i1 @ssub.not.i64(i64 %v1, i64 %v2) {
396entry:
397; CHECK-LABEL:  ssub.not.i64
398; CHECK:        cmp x0, x1
399; CHECK-NEXT:   cset w0, vc
400  %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2)
401  %obit = extractvalue {i64, i1} %t, 1
402  %ret = xor i1 %obit, true
403  ret i1 %ret
404}
405
406define i32 @usubo.select.i32(i32 %v1, i32 %v2) {
407entry:
408; CHECK-LABEL:  usubo.select.i32
409; CHECK:        cmp w0, w1
410; CHECK-NEXT:   csel w0, w0, w1, lo
411  %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2)
412  %obit = extractvalue {i32, i1} %t, 1
413  %ret = select i1 %obit, i32 %v1, i32 %v2
414  ret i32 %ret
415}
416
417define i1 @usubo.not.i32(i32 %v1, i32 %v2) {
418entry:
419; CHECK-LABEL:  usubo.not.i32
420; CHECK:        cmp w0, w1
421; CHECK-NEXT:   cset w0, hs
422  %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2)
423  %obit = extractvalue {i32, i1} %t, 1
424  %ret = xor i1 %obit, true
425  ret i1 %ret
426}
427
428define i64 @usubo.select.i64(i64 %v1, i64 %v2) {
429entry:
430; CHECK-LABEL:  usubo.select.i64
431; CHECK:        cmp x0, x1
432; CHECK-NEXT:   csel x0, x0, x1, lo
433  %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2)
434  %obit = extractvalue {i64, i1} %t, 1
435  %ret = select i1 %obit, i64 %v1, i64 %v2
436  ret i64 %ret
437}
438
439define i1 @usubo.not.i64(i64 %v1, i64 %v2) {
440entry:
441; CHECK-LABEL:  usubo.not.i64
442; CHECK:        cmp x0, x1
443; CHECK-NEXT:   cset w0, hs
444  %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2)
445  %obit = extractvalue {i64, i1} %t, 1
446  %ret = xor i1 %obit, true
447  ret i1 %ret
448}
449
450define i32 @smulo.select.i32(i32 %v1, i32 %v2) {
451entry:
452; CHECK-LABEL:  smulo.select.i32
453; CHECK:        smull   x[[MREG:[0-9]+]], w0, w1
454; CHECK-NEXT:   lsr     x[[SREG:[0-9]+]], x[[MREG]], #32
455; CHECK-NEXT:   cmp     w[[SREG]], w[[MREG]], asr #31
456; CHECK-NEXT:   csel    w0, w0, w1, ne
457  %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
458  %obit = extractvalue {i32, i1} %t, 1
459  %ret = select i1 %obit, i32 %v1, i32 %v2
460  ret i32 %ret
461}
462
463define i1 @smulo.not.i32(i32 %v1, i32 %v2) {
464entry:
465; CHECK-LABEL:  smulo.not.i32
466; CHECK:        smull   x[[MREG:[0-9]+]], w0, w1
467; CHECK-NEXT:   lsr     x[[SREG:[0-9]+]], x[[MREG]], #32
468; CHECK-NEXT:   cmp     w[[SREG]], w[[MREG]], asr #31
469; CHECK-NEXT:   cset    w0, eq
470  %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
471  %obit = extractvalue {i32, i1} %t, 1
472  %ret = xor i1 %obit, true
473  ret i1 %ret
474}
475
476define i64 @smulo.select.i64(i64 %v1, i64 %v2) {
477entry:
478; CHECK-LABEL:  smulo.select.i64
479; CHECK:        mul     [[MREG:x[0-9]+]], x0, x1
480; CHECK-NEXT:   smulh   [[HREG:x[0-9]+]], x0, x1
481; CHECK-NEXT:   cmp     [[HREG]], [[MREG]], asr #63
482; CHECK-NEXT:   csel    x0, x0, x1, ne
483  %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
484  %obit = extractvalue {i64, i1} %t, 1
485  %ret = select i1 %obit, i64 %v1, i64 %v2
486  ret i64 %ret
487}
488
489define i1 @smulo.not.i64(i64 %v1, i64 %v2) {
490entry:
491; CHECK-LABEL:  smulo.not.i64
492; CHECK:        mul     [[MREG:x[0-9]+]], x0, x1
493; CHECK-NEXT:   smulh   [[HREG:x[0-9]+]], x0, x1
494; CHECK-NEXT:   cmp     [[HREG]], [[MREG]], asr #63
495; CHECK-NEXT:   cset    w0, eq
496  %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
497  %obit = extractvalue {i64, i1} %t, 1
498  %ret = xor i1 %obit, true
499  ret i1 %ret
500}
501
502define i32 @umulo.select.i32(i32 %v1, i32 %v2) {
503entry:
504; CHECK-LABEL:  umulo.select.i32
505; CHECK:        umull   [[MREG:x[0-9]+]], w0, w1
506; CHECK-NEXT:   cmp     xzr, [[MREG]], lsr #32
507; CHECK-NEXT:   csel    w0, w0, w1, ne
508  %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
509  %obit = extractvalue {i32, i1} %t, 1
510  %ret = select i1 %obit, i32 %v1, i32 %v2
511  ret i32 %ret
512}
513
514define i1 @umulo.not.i32(i32 %v1, i32 %v2) {
515entry:
516; CHECK-LABEL:  umulo.not.i32
517; CHECK:        umull   [[MREG:x[0-9]+]], w0, w1
518; CHECK-NEXT:   cmp     xzr, [[MREG]], lsr #32
519; CHECK-NEXT:   cset    w0, eq
520  %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
521  %obit = extractvalue {i32, i1} %t, 1
522  %ret = xor i1 %obit, true
523  ret i1 %ret
524}
525
526define i64 @umulo.select.i64(i64 %v1, i64 %v2) {
527entry:
528; CHECK-LABEL:  umulo.select.i64
529; CHECK:        umulh   [[MREG:x[0-9]+]], x0, x1
530; CHECK-NEXT:   cmp     xzr, [[MREG]]
531; CHECK-NEXT:   csel    x0, x0, x1, ne
532  %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
533  %obit = extractvalue {i64, i1} %t, 1
534  %ret = select i1 %obit, i64 %v1, i64 %v2
535  ret i64 %ret
536}
537
538define i1 @umulo.not.i64(i64 %v1, i64 %v2) {
539entry:
540; CHECK-LABEL:  umulo.not.i64
541; CHECK:        umulh   [[MREG:x[0-9]+]], x0, x1
542; CHECK-NEXT:   cmp     xzr, [[MREG]]
543; CHECK-NEXT:   cset    w0, eq
544  %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
545  %obit = extractvalue {i64, i1} %t, 1
546  %ret = xor i1 %obit, true
547  ret i1 %ret
548}
549
550
551;
552; Check the use of the overflow bit in combination with a branch instruction.
553;
554define zeroext i1 @saddo.br.i32(i32 %v1, i32 %v2) {
555entry:
556; CHECK-LABEL:  saddo.br.i32
557; CHECK:        cmn w0, w1
558; CHECK-NEXT:   b.vc
559  %t = call {i32, i1} @llvm.sadd.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 @saddo.br.i64(i64 %v1, i64 %v2) {
572entry:
573; CHECK-LABEL:  saddo.br.i64
574; CHECK:        cmn x0, x1
575; CHECK-NEXT:   b.vc
576  %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2)
577  %val = extractvalue {i64, i1} %t, 0
578  %obit = extractvalue {i64, i1} %t, 1
579  br i1 %obit, label %overflow, label %continue
580
581overflow:
582  ret i1 false
583
584continue:
585  ret i1 true
586}
587
588define zeroext i1 @uaddo.br.i32(i32 %v1, i32 %v2) {
589entry:
590; CHECK-LABEL:  uaddo.br.i32
591; CHECK:        cmn w0, w1
592; CHECK-NEXT:   b.lo
593  %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)
594  %val = extractvalue {i32, i1} %t, 0
595  %obit = extractvalue {i32, i1} %t, 1
596  br i1 %obit, label %overflow, label %continue
597
598overflow:
599  ret i1 false
600
601continue:
602  ret i1 true
603}
604
605define zeroext i1 @uaddo.br.i64(i64 %v1, i64 %v2) {
606entry:
607; CHECK-LABEL:  uaddo.br.i64
608; CHECK:        cmn x0, x1
609; CHECK-NEXT:   b.lo
610  %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2)
611  %val = extractvalue {i64, i1} %t, 0
612  %obit = extractvalue {i64, i1} %t, 1
613  br i1 %obit, label %overflow, label %continue
614
615overflow:
616  ret i1 false
617
618continue:
619  ret i1 true
620}
621
622define zeroext i1 @ssubo.br.i32(i32 %v1, i32 %v2) {
623entry:
624; CHECK-LABEL:  ssubo.br.i32
625; CHECK:        cmp w0, w1
626; CHECK-NEXT:   b.vc
627  %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2)
628  %val = extractvalue {i32, i1} %t, 0
629  %obit = extractvalue {i32, i1} %t, 1
630  br i1 %obit, label %overflow, label %continue
631
632overflow:
633  ret i1 false
634
635continue:
636  ret i1 true
637}
638
639define zeroext i1 @ssubo.br.i64(i64 %v1, i64 %v2) {
640entry:
641; CHECK-LABEL:  ssubo.br.i64
642; CHECK:        cmp x0, x1
643; CHECK-NEXT:   b.vc
644  %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2)
645  %val = extractvalue {i64, i1} %t, 0
646  %obit = extractvalue {i64, i1} %t, 1
647  br i1 %obit, label %overflow, label %continue
648
649overflow:
650  ret i1 false
651
652continue:
653  ret i1 true
654}
655
656define zeroext i1 @usubo.br.i32(i32 %v1, i32 %v2) {
657entry:
658; CHECK-LABEL:  usubo.br.i32
659; CHECK:        cmp w0, w1
660; CHECK-NEXT:   b.hs
661  %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2)
662  %val = extractvalue {i32, i1} %t, 0
663  %obit = extractvalue {i32, i1} %t, 1
664  br i1 %obit, label %overflow, label %continue
665
666overflow:
667  ret i1 false
668
669continue:
670  ret i1 true
671}
672
673define zeroext i1 @usubo.br.i64(i64 %v1, i64 %v2) {
674entry:
675; CHECK-LABEL:  usubo.br.i64
676; CHECK:        cmp x0, x1
677; CHECK-NEXT:   b.hs
678  %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2)
679  %val = extractvalue {i64, i1} %t, 0
680  %obit = extractvalue {i64, i1} %t, 1
681  br i1 %obit, label %overflow, label %continue
682
683overflow:
684  ret i1 false
685
686continue:
687  ret i1 true
688}
689
690define zeroext i1 @smulo.br.i32(i32 %v1, i32 %v2) {
691entry:
692; CHECK-LABEL:  smulo.br.i32
693; CHECK:        smull   x[[MREG:[0-9]+]], w0, w1
694; CHECK-NEXT:   lsr     x[[SREG:[0-9]+]], x8, #32
695; CHECK-NEXT:   cmp     w[[SREG]], w[[MREG]], asr #31
696; CHECK-NEXT:   b.eq
697  %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
698  %val = extractvalue {i32, i1} %t, 0
699  %obit = extractvalue {i32, i1} %t, 1
700  br i1 %obit, label %overflow, label %continue
701
702overflow:
703  ret i1 false
704
705continue:
706  ret i1 true
707}
708
709define zeroext i1 @smulo.br.i64(i64 %v1, i64 %v2) {
710entry:
711; CHECK-LABEL:  smulo.br.i64
712; CHECK:        mul     [[MREG:x[0-9]+]], x0, x1
713; CHECK-NEXT:   smulh   [[HREG:x[0-9]+]], x0, x1
714; CHECK-NEXT:   cmp     [[HREG]], [[MREG]], asr #63
715; CHECK-NEXT:   b.eq
716  %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
717  %val = extractvalue {i64, i1} %t, 0
718  %obit = extractvalue {i64, i1} %t, 1
719  br i1 %obit, label %overflow, label %continue
720
721overflow:
722  ret i1 false
723
724continue:
725  ret i1 true
726}
727
728define zeroext i1 @smulo2.br.i64(i64 %v1) {
729entry:
730; CHECK-LABEL:  smulo2.br.i64
731; CHECK:        cmn  x0, x0
732; CHECK-NEXT:   b.vc
733  %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 2)
734  %val = extractvalue {i64, i1} %t, 0
735  %obit = extractvalue {i64, i1} %t, 1
736  br i1 %obit, label %overflow, label %continue
737
738overflow:
739  ret i1 false
740
741continue:
742  ret i1 true
743}
744
745define zeroext i1 @umulo.br.i32(i32 %v1, i32 %v2) {
746entry:
747; CHECK-LABEL:  umulo.br.i32
748; CHECK:        umull   [[MREG:x[0-9]+]], w0, w1
749; CHECK-NEXT:   cmp     xzr, [[MREG]], lsr #32
750; CHECK-NEXT:   b.eq
751  %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
752  %val = extractvalue {i32, i1} %t, 0
753  %obit = extractvalue {i32, i1} %t, 1
754  br i1 %obit, label %overflow, label %continue
755
756overflow:
757  ret i1 false
758
759continue:
760  ret i1 true
761}
762
763define zeroext i1 @umulo.br.i64(i64 %v1, i64 %v2) {
764entry:
765; CHECK-LABEL:  umulo.br.i64
766; CHECK:        umulh   [[REG:x[0-9]+]], x0, x1
767; CHECK-NEXT:   {{cbz|cmp}}
768  %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
769  %val = extractvalue {i64, i1} %t, 0
770  %obit = extractvalue {i64, i1} %t, 1
771  br i1 %obit, label %overflow, label %continue
772
773overflow:
774  ret i1 false
775
776continue:
777  ret i1 true
778}
779
780define zeroext i1 @umulo2.br.i64(i64 %v1) {
781entry:
782; CHECK-LABEL:  umulo2.br.i64
783; CHECK:        cmn  x0, x0
784; CHECK-NEXT:   b.lo
785  %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 2)
786  %val = extractvalue {i64, i1} %t, 0
787  %obit = extractvalue {i64, i1} %t, 1
788  br i1 %obit, label %overflow, label %continue
789
790overflow:
791  ret i1 false
792
793continue:
794  ret i1 true
795}
796
797declare {i32, i1} @llvm.sadd.with.overflow.i32(i32, i32) nounwind readnone
798declare {i64, i1} @llvm.sadd.with.overflow.i64(i64, i64) nounwind readnone
799declare {i32, i1} @llvm.uadd.with.overflow.i32(i32, i32) nounwind readnone
800declare {i64, i1} @llvm.uadd.with.overflow.i64(i64, i64) nounwind readnone
801declare {i32, i1} @llvm.ssub.with.overflow.i32(i32, i32) nounwind readnone
802declare {i64, i1} @llvm.ssub.with.overflow.i64(i64, i64) nounwind readnone
803declare {i32, i1} @llvm.usub.with.overflow.i32(i32, i32) nounwind readnone
804declare {i64, i1} @llvm.usub.with.overflow.i64(i64, i64) nounwind readnone
805declare {i32, i1} @llvm.smul.with.overflow.i32(i32, i32) nounwind readnone
806declare {i64, i1} @llvm.smul.with.overflow.i64(i64, i64) nounwind readnone
807declare {i32, i1} @llvm.umul.with.overflow.i32(i32, i32) nounwind readnone
808declare {i64, i1} @llvm.umul.with.overflow.i64(i64, i64) nounwind readnone
809
810