Revert "[AArch64] Add DAG combine for extract extend pattern"
[oota-llvm.git] / test / CodeGen / AArch64 / arm64-xaluo.ll
1 ; RUN: llc -march=arm64 -aarch64-atomic-cfg-tidy=0                             -verify-machineinstrs < %s | FileCheck %s
2 ; RUN: llc -march=arm64 -aarch64-atomic-cfg-tidy=0 -fast-isel -fast-isel-abort=1 -verify-machineinstrs < %s | FileCheck %s
3
4 ;
5 ; Get the actual value of the overflow bit.
6 ;
7 define zeroext i1 @saddo1.i32(i32 %v1, i32 %v2, i32* %res) {
8 entry:
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.
20 define zeroext i1 @saddo2.i32(i32 %v1, i32* %res) {
21 entry:
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.
33 define zeroext i1 @saddo3.i32(i32 %v1, i32* %res) {
34 entry:
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.
46 define zeroext i1 @saddo4.i32(i32 %v1, i32* %res) {
47 entry:
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.
59 define zeroext i1 @saddo5.i32(i32 %v1, i32 %v2, i32* %res) {
60 entry:
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
72 define zeroext i1 @saddo1.i64(i64 %v1, i64 %v2, i64* %res) {
73 entry:
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
84 define zeroext i1 @saddo2.i64(i64 %v1, i64* %res) {
85 entry:
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
96 define zeroext i1 @saddo3.i64(i64 %v1, i64* %res) {
97 entry:
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
108 define zeroext i1 @uaddo.i32(i32 %v1, i32 %v2, i32* %res) {
109 entry:
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
120 define zeroext i1 @uaddo.i64(i64 %v1, i64 %v2, i64* %res) {
121 entry:
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
132 define zeroext i1 @ssubo1.i32(i32 %v1, i32 %v2, i32* %res) {
133 entry:
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
144 define zeroext i1 @ssubo2.i32(i32 %v1, i32* %res) {
145 entry:
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
156 define zeroext i1 @ssubo.i64(i64 %v1, i64 %v2, i64* %res) {
157 entry:
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
168 define zeroext i1 @usubo.i32(i32 %v1, i32 %v2, i32* %res) {
169 entry:
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
180 define zeroext i1 @usubo.i64(i64 %v1, i64 %v2, i64* %res) {
181 entry:
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
192 define zeroext i1 @smulo.i32(i32 %v1, i32 %v2, i32* %res) {
193 entry:
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
206 define zeroext i1 @smulo.i64(i64 %v1, i64 %v2, i64* %res) {
207 entry:
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
220 define zeroext i1 @smulo2.i64(i64 %v1, i64* %res) {
221 entry:
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
232 define zeroext i1 @umulo.i32(i32 %v1, i32 %v2, i32* %res) {
233 entry:
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
245 define zeroext i1 @umulo.i64(i64 %v1, i64 %v2, i64* %res) {
246 entry:
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
258 define zeroext i1 @umulo2.i64(i64 %v1, i64* %res) {
259 entry:
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 ;
274 define i32 @saddo.select.i32(i32 %v1, i32 %v2) {
275 entry:
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
285 define i64 @saddo.select.i64(i64 %v1, i64 %v2) {
286 entry:
287 ; CHECK-LABEL:  saddo.select.i64
288 ; CHECK:        cmn x0, x1
289 ; CHECK-NEXT:   csel x0, x0, x1, vs
290   %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2)
291   %obit = extractvalue {i64, i1} %t, 1
292   %ret = select i1 %obit, i64 %v1, i64 %v2
293   ret i64 %ret
294 }
295
296 define i32 @uaddo.select.i32(i32 %v1, i32 %v2) {
297 entry:
298 ; CHECK-LABEL:  uaddo.select.i32
299 ; CHECK:        cmn w0, w1
300 ; CHECK-NEXT:   csel w0, w0, w1, hs
301   %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)
302   %obit = extractvalue {i32, i1} %t, 1
303   %ret = select i1 %obit, i32 %v1, i32 %v2
304   ret i32 %ret
305 }
306
307 define i64 @uaddo.select.i64(i64 %v1, i64 %v2) {
308 entry:
309 ; CHECK-LABEL:  uaddo.select.i64
310 ; CHECK:        cmn x0, x1
311 ; CHECK-NEXT:   csel x0, x0, x1, hs
312   %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2)
313   %obit = extractvalue {i64, i1} %t, 1
314   %ret = select i1 %obit, i64 %v1, i64 %v2
315   ret i64 %ret
316 }
317
318 define i32 @ssubo.select.i32(i32 %v1, i32 %v2) {
319 entry:
320 ; CHECK-LABEL:  ssubo.select.i32
321 ; CHECK:        cmp w0, w1
322 ; CHECK-NEXT:   csel w0, w0, w1, vs
323   %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2)
324   %obit = extractvalue {i32, i1} %t, 1
325   %ret = select i1 %obit, i32 %v1, i32 %v2
326   ret i32 %ret
327 }
328
329 define i64 @ssubo.select.i64(i64 %v1, i64 %v2) {
330 entry:
331 ; CHECK-LABEL:  ssubo.select.i64
332 ; CHECK:        cmp x0, x1
333 ; CHECK-NEXT:   csel x0, x0, x1, vs
334   %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2)
335   %obit = extractvalue {i64, i1} %t, 1
336   %ret = select i1 %obit, i64 %v1, i64 %v2
337   ret i64 %ret
338 }
339
340 define i32 @usubo.select.i32(i32 %v1, i32 %v2) {
341 entry:
342 ; CHECK-LABEL:  usubo.select.i32
343 ; CHECK:        cmp w0, w1
344 ; CHECK-NEXT:   csel w0, w0, w1, lo
345   %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2)
346   %obit = extractvalue {i32, i1} %t, 1
347   %ret = select i1 %obit, i32 %v1, i32 %v2
348   ret i32 %ret
349 }
350
351 define i64 @usubo.select.i64(i64 %v1, i64 %v2) {
352 entry:
353 ; CHECK-LABEL:  usubo.select.i64
354 ; CHECK:        cmp x0, x1
355 ; CHECK-NEXT:   csel x0, x0, x1, lo
356   %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2)
357   %obit = extractvalue {i64, i1} %t, 1
358   %ret = select i1 %obit, i64 %v1, i64 %v2
359   ret i64 %ret
360 }
361
362 define i32 @smulo.select.i32(i32 %v1, i32 %v2) {
363 entry:
364 ; CHECK-LABEL:  smulo.select.i32
365 ; CHECK:        smull   x[[MREG:[0-9]+]], w0, w1
366 ; CHECK-NEXT:   lsr     x[[SREG:[0-9]+]], x[[MREG]], #32
367 ; CHECK-NEXT:   cmp     w[[SREG]], w[[MREG]], asr #31
368 ; CHECK-NEXT:   csel    w0, w0, w1, ne
369   %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
370   %obit = extractvalue {i32, i1} %t, 1
371   %ret = select i1 %obit, i32 %v1, i32 %v2
372   ret i32 %ret
373 }
374
375 define i64 @smulo.select.i64(i64 %v1, i64 %v2) {
376 entry:
377 ; CHECK-LABEL:  smulo.select.i64
378 ; CHECK:        mul     [[MREG:x[0-9]+]], x0, x1
379 ; CHECK-NEXT:   smulh   [[HREG:x[0-9]+]], x0, x1
380 ; CHECK-NEXT:   cmp     [[HREG]], [[MREG]], asr #63
381 ; CHECK-NEXT:   csel    x0, x0, x1, ne
382   %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
383   %obit = extractvalue {i64, i1} %t, 1
384   %ret = select i1 %obit, i64 %v1, i64 %v2
385   ret i64 %ret
386 }
387
388 define i32 @umulo.select.i32(i32 %v1, i32 %v2) {
389 entry:
390 ; CHECK-LABEL:  umulo.select.i32
391 ; CHECK:        umull   [[MREG:x[0-9]+]], w0, w1
392 ; CHECK-NEXT:   cmp     xzr, [[MREG]], lsr #32
393 ; CHECK-NEXT:   csel    w0, w0, w1, ne
394   %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
395   %obit = extractvalue {i32, i1} %t, 1
396   %ret = select i1 %obit, i32 %v1, i32 %v2
397   ret i32 %ret
398 }
399
400 define i64 @umulo.select.i64(i64 %v1, i64 %v2) {
401 entry:
402 ; CHECK-LABEL:  umulo.select.i64
403 ; CHECK:        umulh   [[MREG:x[0-9]+]], x0, x1
404 ; CHECK-NEXT:   cmp     xzr, [[MREG]]
405 ; CHECK-NEXT:   csel    x0, x0, x1, ne
406   %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
407   %obit = extractvalue {i64, i1} %t, 1
408   %ret = select i1 %obit, i64 %v1, i64 %v2
409   ret i64 %ret
410 }
411
412
413 ;
414 ; Check the use of the overflow bit in combination with a branch instruction.
415 ;
416 define zeroext i1 @saddo.br.i32(i32 %v1, i32 %v2) {
417 entry:
418 ; CHECK-LABEL:  saddo.br.i32
419 ; CHECK:        cmn w0, w1
420 ; CHECK-NEXT:   b.vc
421   %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2)
422   %val = extractvalue {i32, i1} %t, 0
423   %obit = extractvalue {i32, i1} %t, 1
424   br i1 %obit, label %overflow, label %continue
425
426 overflow:
427   ret i1 false
428
429 continue:
430   ret i1 true
431 }
432
433 define zeroext i1 @saddo.br.i64(i64 %v1, i64 %v2) {
434 entry:
435 ; CHECK-LABEL:  saddo.br.i64
436 ; CHECK:        cmn x0, x1
437 ; CHECK-NEXT:   b.vc
438   %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2)
439   %val = extractvalue {i64, i1} %t, 0
440   %obit = extractvalue {i64, i1} %t, 1
441   br i1 %obit, label %overflow, label %continue
442
443 overflow:
444   ret i1 false
445
446 continue:
447   ret i1 true
448 }
449
450 define zeroext i1 @uaddo.br.i32(i32 %v1, i32 %v2) {
451 entry:
452 ; CHECK-LABEL:  uaddo.br.i32
453 ; CHECK:        cmn w0, w1
454 ; CHECK-NEXT:   b.lo
455   %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)
456   %val = extractvalue {i32, i1} %t, 0
457   %obit = extractvalue {i32, i1} %t, 1
458   br i1 %obit, label %overflow, label %continue
459
460 overflow:
461   ret i1 false
462
463 continue:
464   ret i1 true
465 }
466
467 define zeroext i1 @uaddo.br.i64(i64 %v1, i64 %v2) {
468 entry:
469 ; CHECK-LABEL:  uaddo.br.i64
470 ; CHECK:        cmn x0, x1
471 ; CHECK-NEXT:   b.lo
472   %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2)
473   %val = extractvalue {i64, i1} %t, 0
474   %obit = extractvalue {i64, i1} %t, 1
475   br i1 %obit, label %overflow, label %continue
476
477 overflow:
478   ret i1 false
479
480 continue:
481   ret i1 true
482 }
483
484 define zeroext i1 @ssubo.br.i32(i32 %v1, i32 %v2) {
485 entry:
486 ; CHECK-LABEL:  ssubo.br.i32
487 ; CHECK:        cmp w0, w1
488 ; CHECK-NEXT:   b.vc
489   %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2)
490   %val = extractvalue {i32, i1} %t, 0
491   %obit = extractvalue {i32, i1} %t, 1
492   br i1 %obit, label %overflow, label %continue
493
494 overflow:
495   ret i1 false
496
497 continue:
498   ret i1 true
499 }
500
501 define zeroext i1 @ssubo.br.i64(i64 %v1, i64 %v2) {
502 entry:
503 ; CHECK-LABEL:  ssubo.br.i64
504 ; CHECK:        cmp x0, x1
505 ; CHECK-NEXT:   b.vc
506   %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2)
507   %val = extractvalue {i64, i1} %t, 0
508   %obit = extractvalue {i64, i1} %t, 1
509   br i1 %obit, label %overflow, label %continue
510
511 overflow:
512   ret i1 false
513
514 continue:
515   ret i1 true
516 }
517
518 define zeroext i1 @usubo.br.i32(i32 %v1, i32 %v2) {
519 entry:
520 ; CHECK-LABEL:  usubo.br.i32
521 ; CHECK:        cmp w0, w1
522 ; CHECK-NEXT:   b.hs
523   %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2)
524   %val = extractvalue {i32, i1} %t, 0
525   %obit = extractvalue {i32, i1} %t, 1
526   br i1 %obit, label %overflow, label %continue
527
528 overflow:
529   ret i1 false
530
531 continue:
532   ret i1 true
533 }
534
535 define zeroext i1 @usubo.br.i64(i64 %v1, i64 %v2) {
536 entry:
537 ; CHECK-LABEL:  usubo.br.i64
538 ; CHECK:        cmp x0, x1
539 ; CHECK-NEXT:   b.hs
540   %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2)
541   %val = extractvalue {i64, i1} %t, 0
542   %obit = extractvalue {i64, i1} %t, 1
543   br i1 %obit, label %overflow, label %continue
544
545 overflow:
546   ret i1 false
547
548 continue:
549   ret i1 true
550 }
551
552 define zeroext i1 @smulo.br.i32(i32 %v1, i32 %v2) {
553 entry:
554 ; CHECK-LABEL:  smulo.br.i32
555 ; CHECK:        smull   x[[MREG:[0-9]+]], w0, w1
556 ; CHECK-NEXT:   lsr     x[[SREG:[0-9]+]], x8, #32
557 ; CHECK-NEXT:   cmp     w[[SREG]], w[[MREG]], asr #31
558 ; CHECK-NEXT:   b.eq
559   %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
560   %val = extractvalue {i32, i1} %t, 0
561   %obit = extractvalue {i32, i1} %t, 1
562   br i1 %obit, label %overflow, label %continue
563
564 overflow:
565   ret i1 false
566
567 continue:
568   ret i1 true
569 }
570
571 define zeroext i1 @smulo.br.i64(i64 %v1, i64 %v2) {
572 entry:
573 ; CHECK-LABEL:  smulo.br.i64
574 ; CHECK:        mul     [[MREG:x[0-9]+]], x0, x1
575 ; CHECK-NEXT:   smulh   [[HREG:x[0-9]+]], x0, x1
576 ; CHECK-NEXT:   cmp     [[HREG]], [[MREG]], asr #63
577 ; CHECK-NEXT:   b.eq
578   %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
579   %val = extractvalue {i64, i1} %t, 0
580   %obit = extractvalue {i64, i1} %t, 1
581   br i1 %obit, label %overflow, label %continue
582
583 overflow:
584   ret i1 false
585
586 continue:
587   ret i1 true
588 }
589
590 define zeroext i1 @smulo2.br.i64(i64 %v1) {
591 entry:
592 ; CHECK-LABEL:  smulo2.br.i64
593 ; CHECK:        cmn  x0, x0
594 ; CHECK-NEXT:   b.vc
595   %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 2)
596   %val = extractvalue {i64, i1} %t, 0
597   %obit = extractvalue {i64, i1} %t, 1
598   br i1 %obit, label %overflow, label %continue
599
600 overflow:
601   ret i1 false
602
603 continue:
604   ret i1 true
605 }
606
607 define zeroext i1 @umulo.br.i32(i32 %v1, i32 %v2) {
608 entry:
609 ; CHECK-LABEL:  umulo.br.i32
610 ; CHECK:        umull   [[MREG:x[0-9]+]], w0, w1
611 ; CHECK-NEXT:   cmp     xzr, [[MREG]], lsr #32
612 ; CHECK-NEXT:   b.eq
613   %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
614   %val = extractvalue {i32, i1} %t, 0
615   %obit = extractvalue {i32, i1} %t, 1
616   br i1 %obit, label %overflow, label %continue
617
618 overflow:
619   ret i1 false
620
621 continue:
622   ret i1 true
623 }
624
625 define zeroext i1 @umulo.br.i64(i64 %v1, i64 %v2) {
626 entry:
627 ; CHECK-LABEL:  umulo.br.i64
628 ; CHECK:        umulh   [[REG:x[0-9]+]], x0, x1
629 ; CHECK-NEXT:   {{cbz|cmp}}
630   %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
631   %val = extractvalue {i64, i1} %t, 0
632   %obit = extractvalue {i64, i1} %t, 1
633   br i1 %obit, label %overflow, label %continue
634
635 overflow:
636   ret i1 false
637
638 continue:
639   ret i1 true
640 }
641
642 define zeroext i1 @umulo2.br.i64(i64 %v1) {
643 entry:
644 ; CHECK-LABEL:  umulo2.br.i64
645 ; CHECK:        cmn  x0, x0
646 ; CHECK-NEXT:   b.lo
647   %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 2)
648   %val = extractvalue {i64, i1} %t, 0
649   %obit = extractvalue {i64, i1} %t, 1
650   br i1 %obit, label %overflow, label %continue
651
652 overflow:
653   ret i1 false
654
655 continue:
656   ret i1 true
657 }
658
659 declare {i32, i1} @llvm.sadd.with.overflow.i32(i32, i32) nounwind readnone
660 declare {i64, i1} @llvm.sadd.with.overflow.i64(i64, i64) nounwind readnone
661 declare {i32, i1} @llvm.uadd.with.overflow.i32(i32, i32) nounwind readnone
662 declare {i64, i1} @llvm.uadd.with.overflow.i64(i64, i64) nounwind readnone
663 declare {i32, i1} @llvm.ssub.with.overflow.i32(i32, i32) nounwind readnone
664 declare {i64, i1} @llvm.ssub.with.overflow.i64(i64, i64) nounwind readnone
665 declare {i32, i1} @llvm.usub.with.overflow.i32(i32, i32) nounwind readnone
666 declare {i64, i1} @llvm.usub.with.overflow.i64(i64, i64) nounwind readnone
667 declare {i32, i1} @llvm.smul.with.overflow.i32(i32, i32) nounwind readnone
668 declare {i64, i1} @llvm.smul.with.overflow.i64(i64, i64) nounwind readnone
669 declare {i32, i1} @llvm.umul.with.overflow.i32(i32, i32) nounwind readnone
670 declare {i64, i1} @llvm.umul.with.overflow.i64(i64, i64) nounwind readnone
671