[FastISel][AArch64] Fix the immediate versions of the {s|u}{add|sub}.with.overflow...
[oota-llvm.git] / test / CodeGen / AArch64 / arm64-xaluo.ll
1 ; RUN: llc -march=arm64 -aarch64-atomic-cfg-tidy=0                             < %s | FileCheck %s
2 ; RUN: llc -march=arm64 -aarch64-atomic-cfg-tidy=0 -fast-isel -fast-isel-abort < %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 define zeroext i1 @saddo1.i64(i64 %v1, i64 %v2, i64* %res) {
59 entry:
60 ; CHECK-LABEL:  saddo1.i64
61 ; CHECK:        adds {{x[0-9]+}}, x0, x1
62 ; CHECK-NEXT:   cset {{w[0-9]+}}, vs
63   %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2)
64   %val = extractvalue {i64, i1} %t, 0
65   %obit = extractvalue {i64, i1} %t, 1
66   store i64 %val, i64* %res
67   ret i1 %obit
68 }
69
70 define zeroext i1 @saddo2.i64(i64 %v1, i64* %res) {
71 entry:
72 ; CHECK-LABEL:  saddo2.i64
73 ; CHECK:        adds {{x[0-9]+}}, x0, #4
74 ; CHECK-NEXT:   cset {{w[0-9]+}}, vs
75   %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 4)
76   %val = extractvalue {i64, i1} %t, 0
77   %obit = extractvalue {i64, i1} %t, 1
78   store i64 %val, i64* %res
79   ret i1 %obit
80 }
81
82 define zeroext i1 @saddo3.i64(i64 %v1, i64* %res) {
83 entry:
84 ; CHECK-LABEL:  saddo3.i64
85 ; CHECK:        subs {{x[0-9]+}}, x0, #4
86 ; CHECK-NEXT:   cset {{w[0-9]+}}, vs
87   %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 -4)
88   %val = extractvalue {i64, i1} %t, 0
89   %obit = extractvalue {i64, i1} %t, 1
90   store i64 %val, i64* %res
91   ret i1 %obit
92 }
93
94 define zeroext i1 @uaddo.i32(i32 %v1, i32 %v2, i32* %res) {
95 entry:
96 ; CHECK-LABEL:  uaddo.i32
97 ; CHECK:        adds {{w[0-9]+}}, w0, w1
98 ; CHECK-NEXT:   cset {{w[0-9]+}}, hs
99   %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)
100   %val = extractvalue {i32, i1} %t, 0
101   %obit = extractvalue {i32, i1} %t, 1
102   store i32 %val, i32* %res
103   ret i1 %obit
104 }
105
106 define zeroext i1 @uaddo.i64(i64 %v1, i64 %v2, i64* %res) {
107 entry:
108 ; CHECK-LABEL:  uaddo.i64
109 ; CHECK:        adds {{x[0-9]+}}, x0, x1
110 ; CHECK-NEXT:   cset {{w[0-9]+}}, hs
111   %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2)
112   %val = extractvalue {i64, i1} %t, 0
113   %obit = extractvalue {i64, i1} %t, 1
114   store i64 %val, i64* %res
115   ret i1 %obit
116 }
117
118 define zeroext i1 @ssubo1.i32(i32 %v1, i32 %v2, i32* %res) {
119 entry:
120 ; CHECK-LABEL:  ssubo1.i32
121 ; CHECK:        subs {{w[0-9]+}}, w0, w1
122 ; CHECK-NEXT:   cset {{w[0-9]+}}, vs
123   %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2)
124   %val = extractvalue {i32, i1} %t, 0
125   %obit = extractvalue {i32, i1} %t, 1
126   store i32 %val, i32* %res
127   ret i1 %obit
128 }
129
130 define zeroext i1 @ssubo2.i32(i32 %v1, i32* %res) {
131 entry:
132 ; CHECK-LABEL:  ssubo2.i32
133 ; CHECK:        adds {{w[0-9]+}}, w0, #4
134 ; CHECK-NEXT:   cset {{w[0-9]+}}, vs
135   %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 -4)
136   %val = extractvalue {i32, i1} %t, 0
137   %obit = extractvalue {i32, i1} %t, 1
138   store i32 %val, i32* %res
139   ret i1 %obit
140 }
141
142 define zeroext i1 @ssubo.i64(i64 %v1, i64 %v2, i64* %res) {
143 entry:
144 ; CHECK-LABEL:  ssubo.i64
145 ; CHECK:        subs {{x[0-9]+}}, x0, x1
146 ; CHECK-NEXT:   cset {{w[0-9]+}}, vs
147   %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2)
148   %val = extractvalue {i64, i1} %t, 0
149   %obit = extractvalue {i64, i1} %t, 1
150   store i64 %val, i64* %res
151   ret i1 %obit
152 }
153
154 define zeroext i1 @usubo.i32(i32 %v1, i32 %v2, i32* %res) {
155 entry:
156 ; CHECK-LABEL:  usubo.i32
157 ; CHECK:        subs {{w[0-9]+}}, w0, w1
158 ; CHECK-NEXT:   cset {{w[0-9]+}}, lo
159   %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2)
160   %val = extractvalue {i32, i1} %t, 0
161   %obit = extractvalue {i32, i1} %t, 1
162   store i32 %val, i32* %res
163   ret i1 %obit
164 }
165
166 define zeroext i1 @usubo.i64(i64 %v1, i64 %v2, i64* %res) {
167 entry:
168 ; CHECK-LABEL:  usubo.i64
169 ; CHECK:        subs {{x[0-9]+}}, x0, x1
170 ; CHECK-NEXT:   cset {{w[0-9]+}}, lo
171   %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2)
172   %val = extractvalue {i64, i1} %t, 0
173   %obit = extractvalue {i64, i1} %t, 1
174   store i64 %val, i64* %res
175   ret i1 %obit
176 }
177
178 define zeroext i1 @smulo.i32(i32 %v1, i32 %v2, i32* %res) {
179 entry:
180 ; CHECK-LABEL:  smulo.i32
181 ; CHECK:        smull x[[MREG:[0-9]+]], w0, w1
182 ; CHECK-NEXT:   lsr x[[SREG:[0-9]+]], x[[MREG]], #32
183 ; CHECK-NEXT:   cmp w[[SREG]], w[[MREG]], asr #31
184 ; CHECK-NEXT:   cset {{w[0-9]+}}, ne
185   %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
186   %val = extractvalue {i32, i1} %t, 0
187   %obit = extractvalue {i32, i1} %t, 1
188   store i32 %val, i32* %res
189   ret i1 %obit
190 }
191
192 define zeroext i1 @smulo.i64(i64 %v1, i64 %v2, i64* %res) {
193 entry:
194 ; CHECK-LABEL:  smulo.i64
195 ; CHECK:        mul [[MREG:x[0-9]+]], x0, x1
196 ; CHECK-NEXT:   smulh [[HREG:x[0-9]+]], x0, x1
197 ; CHECK-NEXT:   cmp [[HREG]], [[MREG]], asr #63
198 ; CHECK-NEXT:   cset {{w[0-9]+}}, ne
199   %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
200   %val = extractvalue {i64, i1} %t, 0
201   %obit = extractvalue {i64, i1} %t, 1
202   store i64 %val, i64* %res
203   ret i1 %obit
204 }
205
206 define zeroext i1 @umulo.i32(i32 %v1, i32 %v2, i32* %res) {
207 entry:
208 ; CHECK-LABEL:  umulo.i32
209 ; CHECK:        umull [[MREG:x[0-9]+]], w0, w1
210 ; CHECK-NEXT:   cmp xzr, [[MREG]], lsr #32
211 ; CHECK-NEXT:   cset {{w[0-9]+}}, ne
212   %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
213   %val = extractvalue {i32, i1} %t, 0
214   %obit = extractvalue {i32, i1} %t, 1
215   store i32 %val, i32* %res
216   ret i1 %obit
217 }
218
219 define zeroext i1 @umulo.i64(i64 %v1, i64 %v2, i64* %res) {
220 entry:
221 ; CHECK-LABEL:  umulo.i64
222 ; CHECK:        umulh [[MREG:x[0-9]+]], x0, x1
223 ; CHECK-NEXT:   cmp xzr, [[MREG]]
224 ; CHECK-NEXT:   cset {{w[0-9]+}}, ne
225   %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
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
233 ;
234 ; Check the use of the overflow bit in combination with a select instruction.
235 ;
236 define i32 @saddo.select.i32(i32 %v1, i32 %v2) {
237 entry:
238 ; CHECK-LABEL:  saddo.select.i32
239 ; CHECK:        cmn w0, w1
240 ; CHECK-NEXT:   csel w0, w0, w1, vs
241   %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2)
242   %obit = extractvalue {i32, i1} %t, 1
243   %ret = select i1 %obit, i32 %v1, i32 %v2
244   ret i32 %ret
245 }
246
247 define i64 @saddo.select.i64(i64 %v1, i64 %v2) {
248 entry:
249 ; CHECK-LABEL:  saddo.select.i64
250 ; CHECK:        cmn x0, x1
251 ; CHECK-NEXT:   csel x0, x0, x1, vs
252   %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2)
253   %obit = extractvalue {i64, i1} %t, 1
254   %ret = select i1 %obit, i64 %v1, i64 %v2
255   ret i64 %ret
256 }
257
258 define i32 @uaddo.select.i32(i32 %v1, i32 %v2) {
259 entry:
260 ; CHECK-LABEL:  uaddo.select.i32
261 ; CHECK:        cmn w0, w1
262 ; CHECK-NEXT:   csel w0, w0, w1, hs
263   %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)
264   %obit = extractvalue {i32, i1} %t, 1
265   %ret = select i1 %obit, i32 %v1, i32 %v2
266   ret i32 %ret
267 }
268
269 define i64 @uaddo.select.i64(i64 %v1, i64 %v2) {
270 entry:
271 ; CHECK-LABEL:  uaddo.select.i64
272 ; CHECK:        cmn x0, x1
273 ; CHECK-NEXT:   csel x0, x0, x1, hs
274   %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2)
275   %obit = extractvalue {i64, i1} %t, 1
276   %ret = select i1 %obit, i64 %v1, i64 %v2
277   ret i64 %ret
278 }
279
280 define i32 @ssubo.select.i32(i32 %v1, i32 %v2) {
281 entry:
282 ; CHECK-LABEL:  ssubo.select.i32
283 ; CHECK:        cmp w0, w1
284 ; CHECK-NEXT:   csel w0, w0, w1, vs
285   %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2)
286   %obit = extractvalue {i32, i1} %t, 1
287   %ret = select i1 %obit, i32 %v1, i32 %v2
288   ret i32 %ret
289 }
290
291 define i64 @ssubo.select.i64(i64 %v1, i64 %v2) {
292 entry:
293 ; CHECK-LABEL:  ssubo.select.i64
294 ; CHECK:        cmp x0, x1
295 ; CHECK-NEXT:   csel x0, x0, x1, vs
296   %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2)
297   %obit = extractvalue {i64, i1} %t, 1
298   %ret = select i1 %obit, i64 %v1, i64 %v2
299   ret i64 %ret
300 }
301
302 define i32 @usubo.select.i32(i32 %v1, i32 %v2) {
303 entry:
304 ; CHECK-LABEL:  usubo.select.i32
305 ; CHECK:        cmp w0, w1
306 ; CHECK-NEXT:   csel w0, w0, w1, lo
307   %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2)
308   %obit = extractvalue {i32, i1} %t, 1
309   %ret = select i1 %obit, i32 %v1, i32 %v2
310   ret i32 %ret
311 }
312
313 define i64 @usubo.select.i64(i64 %v1, i64 %v2) {
314 entry:
315 ; CHECK-LABEL:  usubo.select.i64
316 ; CHECK:        cmp x0, x1
317 ; CHECK-NEXT:   csel x0, x0, x1, lo
318   %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2)
319   %obit = extractvalue {i64, i1} %t, 1
320   %ret = select i1 %obit, i64 %v1, i64 %v2
321   ret i64 %ret
322 }
323
324 define i32 @smulo.select.i32(i32 %v1, i32 %v2) {
325 entry:
326 ; CHECK-LABEL:  smulo.select.i32
327 ; CHECK:        smull   x[[MREG:[0-9]+]], w0, w1
328 ; CHECK-NEXT:   lsr     x[[SREG:[0-9]+]], x[[MREG]], #32
329 ; CHECK-NEXT:   cmp     w[[SREG]], w[[MREG]], asr #31
330 ; CHECK-NEXT:   csel    w0, w0, w1, ne
331   %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
332   %obit = extractvalue {i32, i1} %t, 1
333   %ret = select i1 %obit, i32 %v1, i32 %v2
334   ret i32 %ret
335 }
336
337 define i64 @smulo.select.i64(i64 %v1, i64 %v2) {
338 entry:
339 ; CHECK-LABEL:  smulo.select.i64
340 ; CHECK:        mul     [[MREG:x[0-9]+]], x0, x1
341 ; CHECK-NEXT:   smulh   [[HREG:x[0-9]+]], x0, x1
342 ; CHECK-NEXT:   cmp     [[HREG]], [[MREG]], asr #63
343 ; CHECK-NEXT:   csel    x0, x0, x1, ne
344   %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
345   %obit = extractvalue {i64, i1} %t, 1
346   %ret = select i1 %obit, i64 %v1, i64 %v2
347   ret i64 %ret
348 }
349
350 define i32 @umulo.select.i32(i32 %v1, i32 %v2) {
351 entry:
352 ; CHECK-LABEL:  umulo.select.i32
353 ; CHECK:        umull   [[MREG:x[0-9]+]], w0, w1
354 ; CHECK-NEXT:   cmp     xzr, [[MREG]], lsr #32
355 ; CHECK-NEXT:   csel    w0, w0, w1, ne
356   %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
357   %obit = extractvalue {i32, i1} %t, 1
358   %ret = select i1 %obit, i32 %v1, i32 %v2
359   ret i32 %ret
360 }
361
362 define i64 @umulo.select.i64(i64 %v1, i64 %v2) {
363 entry:
364 ; CHECK-LABEL:  umulo.select.i64
365 ; CHECK:        umulh   [[MREG:x[0-9]+]], x0, x1
366 ; CHECK-NEXT:   cmp     xzr, [[MREG]]
367 ; CHECK-NEXT:   csel    x0, x0, x1, ne
368   %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
369   %obit = extractvalue {i64, i1} %t, 1
370   %ret = select i1 %obit, i64 %v1, i64 %v2
371   ret i64 %ret
372 }
373
374
375 ;
376 ; Check the use of the overflow bit in combination with a branch instruction.
377 ;
378 define zeroext i1 @saddo.br.i32(i32 %v1, i32 %v2) {
379 entry:
380 ; CHECK-LABEL:  saddo.br.i32
381 ; CHECK:        cmn w0, w1
382 ; CHECK-NEXT:   b.vc
383   %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2)
384   %val = extractvalue {i32, i1} %t, 0
385   %obit = extractvalue {i32, i1} %t, 1
386   br i1 %obit, label %overflow, label %continue
387
388 overflow:
389   ret i1 false
390
391 continue:
392   ret i1 true
393 }
394
395 define zeroext i1 @saddo.br.i64(i64 %v1, i64 %v2) {
396 entry:
397 ; CHECK-LABEL:  saddo.br.i64
398 ; CHECK:        cmn x0, x1
399 ; CHECK-NEXT:   b.vc
400   %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2)
401   %val = extractvalue {i64, i1} %t, 0
402   %obit = extractvalue {i64, i1} %t, 1
403   br i1 %obit, label %overflow, label %continue
404
405 overflow:
406   ret i1 false
407
408 continue:
409   ret i1 true
410 }
411
412 define zeroext i1 @uaddo.br.i32(i32 %v1, i32 %v2) {
413 entry:
414 ; CHECK-LABEL:  uaddo.br.i32
415 ; CHECK:        cmn w0, w1
416 ; CHECK-NEXT:   b.lo
417   %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)
418   %val = extractvalue {i32, i1} %t, 0
419   %obit = extractvalue {i32, i1} %t, 1
420   br i1 %obit, label %overflow, label %continue
421
422 overflow:
423   ret i1 false
424
425 continue:
426   ret i1 true
427 }
428
429 define zeroext i1 @uaddo.br.i64(i64 %v1, i64 %v2) {
430 entry:
431 ; CHECK-LABEL:  uaddo.br.i64
432 ; CHECK:        cmn x0, x1
433 ; CHECK-NEXT:   b.lo
434   %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2)
435   %val = extractvalue {i64, i1} %t, 0
436   %obit = extractvalue {i64, i1} %t, 1
437   br i1 %obit, label %overflow, label %continue
438
439 overflow:
440   ret i1 false
441
442 continue:
443   ret i1 true
444 }
445
446 define zeroext i1 @ssubo.br.i32(i32 %v1, i32 %v2) {
447 entry:
448 ; CHECK-LABEL:  ssubo.br.i32
449 ; CHECK:        cmp w0, w1
450 ; CHECK-NEXT:   b.vc
451   %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2)
452   %val = extractvalue {i32, i1} %t, 0
453   %obit = extractvalue {i32, i1} %t, 1
454   br i1 %obit, label %overflow, label %continue
455
456 overflow:
457   ret i1 false
458
459 continue:
460   ret i1 true
461 }
462
463 define zeroext i1 @ssubo.br.i64(i64 %v1, i64 %v2) {
464 entry:
465 ; CHECK-LABEL:  ssubo.br.i64
466 ; CHECK:        cmp x0, x1
467 ; CHECK-NEXT:   b.vc
468   %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2)
469   %val = extractvalue {i64, i1} %t, 0
470   %obit = extractvalue {i64, i1} %t, 1
471   br i1 %obit, label %overflow, label %continue
472
473 overflow:
474   ret i1 false
475
476 continue:
477   ret i1 true
478 }
479
480 define zeroext i1 @usubo.br.i32(i32 %v1, i32 %v2) {
481 entry:
482 ; CHECK-LABEL:  usubo.br.i32
483 ; CHECK:        cmp w0, w1
484 ; CHECK-NEXT:   b.hs
485   %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2)
486   %val = extractvalue {i32, i1} %t, 0
487   %obit = extractvalue {i32, i1} %t, 1
488   br i1 %obit, label %overflow, label %continue
489
490 overflow:
491   ret i1 false
492
493 continue:
494   ret i1 true
495 }
496
497 define zeroext i1 @usubo.br.i64(i64 %v1, i64 %v2) {
498 entry:
499 ; CHECK-LABEL:  usubo.br.i64
500 ; CHECK:        cmp x0, x1
501 ; CHECK-NEXT:   b.hs
502   %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2)
503   %val = extractvalue {i64, i1} %t, 0
504   %obit = extractvalue {i64, i1} %t, 1
505   br i1 %obit, label %overflow, label %continue
506
507 overflow:
508   ret i1 false
509
510 continue:
511   ret i1 true
512 }
513
514 define zeroext i1 @smulo.br.i32(i32 %v1, i32 %v2) {
515 entry:
516 ; CHECK-LABEL:  smulo.br.i32
517 ; CHECK:        smull   x[[MREG:[0-9]+]], w0, w1
518 ; CHECK-NEXT:   lsr     x[[SREG:[0-9]+]], x8, #32
519 ; CHECK-NEXT:   cmp     w[[SREG]], w[[MREG]], asr #31
520 ; CHECK-NEXT:   b.eq
521   %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
522   %val = extractvalue {i32, i1} %t, 0
523   %obit = extractvalue {i32, i1} %t, 1
524   br i1 %obit, label %overflow, label %continue
525
526 overflow:
527   ret i1 false
528
529 continue:
530   ret i1 true
531 }
532
533 define zeroext i1 @smulo.br.i64(i64 %v1, i64 %v2) {
534 entry:
535 ; CHECK-LABEL:  smulo.br.i64
536 ; CHECK:        mul     [[MREG:x[0-9]+]], x0, x1
537 ; CHECK-NEXT:   smulh   [[HREG:x[0-9]+]], x0, x1
538 ; CHECK-NEXT:   cmp     [[HREG]], [[MREG]], asr #63
539 ; CHECK-NEXT:   b.eq
540   %t = call {i64, i1} @llvm.smul.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 @umulo.br.i32(i32 %v1, i32 %v2) {
553 entry:
554 ; CHECK-LABEL:  umulo.br.i32
555 ; CHECK:        umull   [[MREG:x[0-9]+]], w0, w1
556 ; CHECK-NEXT:   cmp     xzr, [[MREG]], lsr #32
557 ; CHECK-NEXT:   b.eq
558   %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
559   %val = extractvalue {i32, i1} %t, 0
560   %obit = extractvalue {i32, i1} %t, 1
561   br i1 %obit, label %overflow, label %continue
562
563 overflow:
564   ret i1 false
565
566 continue:
567   ret i1 true
568 }
569
570 define zeroext i1 @umulo.br.i64(i64 %v1, i64 %v2) {
571 entry:
572 ; CHECK-LABEL:  umulo.br.i64
573 ; CHECK:        umulh   [[REG:x[0-9]+]], x0, x1
574 ; CHECK-NEXT:   {{cbz|cmp}}
575   %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
576   %val = extractvalue {i64, i1} %t, 0
577   %obit = extractvalue {i64, i1} %t, 1
578   br i1 %obit, label %overflow, label %continue
579
580 overflow:
581   ret i1 false
582
583 continue:
584   ret i1 true
585 }
586
587 declare {i32, i1} @llvm.sadd.with.overflow.i32(i32, i32) nounwind readnone
588 declare {i64, i1} @llvm.sadd.with.overflow.i64(i64, i64) nounwind readnone
589 declare {i32, i1} @llvm.uadd.with.overflow.i32(i32, i32) nounwind readnone
590 declare {i64, i1} @llvm.uadd.with.overflow.i64(i64, i64) nounwind readnone
591 declare {i32, i1} @llvm.ssub.with.overflow.i32(i32, i32) nounwind readnone
592 declare {i64, i1} @llvm.ssub.with.overflow.i64(i64, i64) nounwind readnone
593 declare {i32, i1} @llvm.usub.with.overflow.i32(i32, i32) nounwind readnone
594 declare {i64, i1} @llvm.usub.with.overflow.i64(i64, i64) nounwind readnone
595 declare {i32, i1} @llvm.smul.with.overflow.i32(i32, i32) nounwind readnone
596 declare {i64, i1} @llvm.smul.with.overflow.i64(i64, i64) nounwind readnone
597 declare {i32, i1} @llvm.umul.with.overflow.i32(i32, i32) nounwind readnone
598 declare {i64, i1} @llvm.umul.with.overflow.i64(i64, i64) nounwind readnone
599