1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=riscv32 -mattr=+m -verify-machineinstrs | FileCheck %s --check-prefix=RV32
3 ; RUN: llc < %s -mtriple=riscv64 -mattr=+m -verify-machineinstrs | FileCheck %s --check-prefix=RV64
4 ; RUN: llc < %s -mtriple=riscv32 -mattr=+m,+experimental-zba -verify-machineinstrs | FileCheck %s --check-prefix=RV32ZBA
5 ; RUN: llc < %s -mtriple=riscv64 -mattr=+m,+experimental-zba -verify-machineinstrs | FileCheck %s --check-prefix=RV64ZBA
8 ; Get the actual value of the overflow bit.
10 define zeroext i1 @saddo1.i32(i32 %v1, i32 %v2, i32* %res) {
11 ; RV32-LABEL: saddo1.i32:
12 ; RV32: # %bb.0: # %entry
13 ; RV32-NEXT: add a3, a0, a1
14 ; RV32-NEXT: slt a0, a3, a0
15 ; RV32-NEXT: slti a1, a1, 0
16 ; RV32-NEXT: xor a0, a1, a0
17 ; RV32-NEXT: sw a3, 0(a2)
20 ; RV64-LABEL: saddo1.i32:
21 ; RV64: # %bb.0: # %entry
22 ; RV64-NEXT: sext.w a1, a1
23 ; RV64-NEXT: sext.w a0, a0
24 ; RV64-NEXT: add a3, a0, a1
25 ; RV64-NEXT: addw a0, a0, a1
26 ; RV64-NEXT: xor a0, a0, a3
27 ; RV64-NEXT: snez a0, a0
28 ; RV64-NEXT: sw a3, 0(a2)
31 ; RV32ZBA-LABEL: saddo1.i32:
32 ; RV32ZBA: # %bb.0: # %entry
33 ; RV32ZBA-NEXT: add a3, a0, a1
34 ; RV32ZBA-NEXT: slt a0, a3, a0
35 ; RV32ZBA-NEXT: slti a1, a1, 0
36 ; RV32ZBA-NEXT: xor a0, a1, a0
37 ; RV32ZBA-NEXT: sw a3, 0(a2)
40 ; RV64ZBA-LABEL: saddo1.i32:
41 ; RV64ZBA: # %bb.0: # %entry
42 ; RV64ZBA-NEXT: sext.w a1, a1
43 ; RV64ZBA-NEXT: sext.w a0, a0
44 ; RV64ZBA-NEXT: add a3, a0, a1
45 ; RV64ZBA-NEXT: addw a0, a0, a1
46 ; RV64ZBA-NEXT: xor a0, a0, a3
47 ; RV64ZBA-NEXT: snez a0, a0
48 ; RV64ZBA-NEXT: sw a3, 0(a2)
51 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2)
52 %val = extractvalue {i32, i1} %t, 0
53 %obit = extractvalue {i32, i1} %t, 1
54 store i32 %val, i32* %res
58 ; Test the immediate version.
59 define zeroext i1 @saddo2.i32(i32 %v1, i32* %res) {
60 ; RV32-LABEL: saddo2.i32:
61 ; RV32: # %bb.0: # %entry
62 ; RV32-NEXT: addi a2, a0, 4
63 ; RV32-NEXT: slt a0, a2, a0
64 ; RV32-NEXT: sw a2, 0(a1)
67 ; RV64-LABEL: saddo2.i32:
68 ; RV64: # %bb.0: # %entry
69 ; RV64-NEXT: sext.w a0, a0
70 ; RV64-NEXT: addi a2, a0, 4
71 ; RV64-NEXT: addiw a0, a0, 4
72 ; RV64-NEXT: xor a0, a0, a2
73 ; RV64-NEXT: snez a0, a0
74 ; RV64-NEXT: sw a2, 0(a1)
77 ; RV32ZBA-LABEL: saddo2.i32:
78 ; RV32ZBA: # %bb.0: # %entry
79 ; RV32ZBA-NEXT: addi a2, a0, 4
80 ; RV32ZBA-NEXT: slt a0, a2, a0
81 ; RV32ZBA-NEXT: sw a2, 0(a1)
84 ; RV64ZBA-LABEL: saddo2.i32:
85 ; RV64ZBA: # %bb.0: # %entry
86 ; RV64ZBA-NEXT: sext.w a0, a0
87 ; RV64ZBA-NEXT: addi a2, a0, 4
88 ; RV64ZBA-NEXT: addiw a0, a0, 4
89 ; RV64ZBA-NEXT: xor a0, a0, a2
90 ; RV64ZBA-NEXT: snez a0, a0
91 ; RV64ZBA-NEXT: sw a2, 0(a1)
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, i32* %res
101 ; Test negative immediates.
102 define zeroext i1 @saddo3.i32(i32 %v1, i32* %res) {
103 ; RV32-LABEL: saddo3.i32:
104 ; RV32: # %bb.0: # %entry
105 ; RV32-NEXT: addi a2, a0, -4
106 ; RV32-NEXT: slt a0, a2, a0
107 ; RV32-NEXT: xori a0, a0, 1
108 ; RV32-NEXT: sw a2, 0(a1)
111 ; RV64-LABEL: saddo3.i32:
112 ; RV64: # %bb.0: # %entry
113 ; RV64-NEXT: sext.w a0, a0
114 ; RV64-NEXT: addi a2, a0, -4
115 ; RV64-NEXT: addiw a0, a0, -4
116 ; RV64-NEXT: xor a0, a0, a2
117 ; RV64-NEXT: snez a0, a0
118 ; RV64-NEXT: sw a2, 0(a1)
121 ; RV32ZBA-LABEL: saddo3.i32:
122 ; RV32ZBA: # %bb.0: # %entry
123 ; RV32ZBA-NEXT: addi a2, a0, -4
124 ; RV32ZBA-NEXT: slt a0, a2, a0
125 ; RV32ZBA-NEXT: xori a0, a0, 1
126 ; RV32ZBA-NEXT: sw a2, 0(a1)
129 ; RV64ZBA-LABEL: saddo3.i32:
130 ; RV64ZBA: # %bb.0: # %entry
131 ; RV64ZBA-NEXT: sext.w a0, a0
132 ; RV64ZBA-NEXT: addi a2, a0, -4
133 ; RV64ZBA-NEXT: addiw a0, a0, -4
134 ; RV64ZBA-NEXT: xor a0, a0, a2
135 ; RV64ZBA-NEXT: snez a0, a0
136 ; RV64ZBA-NEXT: sw a2, 0(a1)
139 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 -4)
140 %val = extractvalue {i32, i1} %t, 0
141 %obit = extractvalue {i32, i1} %t, 1
142 store i32 %val, i32* %res
146 ; Test immediates that are too large to be encoded.
147 define zeroext i1 @saddo4.i32(i32 %v1, i32* %res) {
148 ; RV32-LABEL: saddo4.i32:
149 ; RV32: # %bb.0: # %entry
150 ; RV32-NEXT: lui a2, 4096
151 ; RV32-NEXT: addi a2, a2, -1
152 ; RV32-NEXT: add a2, a0, a2
153 ; RV32-NEXT: slt a0, a2, a0
154 ; RV32-NEXT: sw a2, 0(a1)
157 ; RV64-LABEL: saddo4.i32:
158 ; RV64: # %bb.0: # %entry
159 ; RV64-NEXT: sext.w a0, a0
160 ; RV64-NEXT: lui a2, 4096
161 ; RV64-NEXT: addiw a2, a2, -1
162 ; RV64-NEXT: add a3, a0, a2
163 ; RV64-NEXT: addw a0, a0, a2
164 ; RV64-NEXT: xor a0, a0, a3
165 ; RV64-NEXT: snez a0, a0
166 ; RV64-NEXT: sw a3, 0(a1)
169 ; RV32ZBA-LABEL: saddo4.i32:
170 ; RV32ZBA: # %bb.0: # %entry
171 ; RV32ZBA-NEXT: lui a2, 4096
172 ; RV32ZBA-NEXT: addi a2, a2, -1
173 ; RV32ZBA-NEXT: add a2, a0, a2
174 ; RV32ZBA-NEXT: slt a0, a2, a0
175 ; RV32ZBA-NEXT: sw a2, 0(a1)
178 ; RV64ZBA-LABEL: saddo4.i32:
179 ; RV64ZBA: # %bb.0: # %entry
180 ; RV64ZBA-NEXT: sext.w a0, a0
181 ; RV64ZBA-NEXT: lui a2, 4096
182 ; RV64ZBA-NEXT: addiw a2, a2, -1
183 ; RV64ZBA-NEXT: add a3, a0, a2
184 ; RV64ZBA-NEXT: addw a0, a0, a2
185 ; RV64ZBA-NEXT: xor a0, a0, a3
186 ; RV64ZBA-NEXT: snez a0, a0
187 ; RV64ZBA-NEXT: sw a3, 0(a1)
190 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 16777215)
191 %val = extractvalue {i32, i1} %t, 0
192 %obit = extractvalue {i32, i1} %t, 1
193 store i32 %val, i32* %res
197 define zeroext i1 @saddo1.i64(i64 %v1, i64 %v2, i64* %res) {
198 ; RV32-LABEL: saddo1.i64:
199 ; RV32: # %bb.0: # %entry
200 ; RV32-NEXT: add a5, a1, a3
201 ; RV32-NEXT: add a2, a0, a2
202 ; RV32-NEXT: sltu a0, a2, a0
203 ; RV32-NEXT: add a5, a5, a0
204 ; RV32-NEXT: xor a0, a1, a5
205 ; RV32-NEXT: xor a1, a1, a3
206 ; RV32-NEXT: not a1, a1
207 ; RV32-NEXT: and a0, a1, a0
208 ; RV32-NEXT: slti a0, a0, 0
209 ; RV32-NEXT: sw a2, 0(a4)
210 ; RV32-NEXT: sw a5, 4(a4)
213 ; RV64-LABEL: saddo1.i64:
214 ; RV64: # %bb.0: # %entry
215 ; RV64-NEXT: add a3, a0, a1
216 ; RV64-NEXT: slt a0, a3, a0
217 ; RV64-NEXT: slti a1, a1, 0
218 ; RV64-NEXT: xor a0, a1, a0
219 ; RV64-NEXT: sd a3, 0(a2)
222 ; RV32ZBA-LABEL: saddo1.i64:
223 ; RV32ZBA: # %bb.0: # %entry
224 ; RV32ZBA-NEXT: add a5, a1, a3
225 ; RV32ZBA-NEXT: add a2, a0, a2
226 ; RV32ZBA-NEXT: sltu a0, a2, a0
227 ; RV32ZBA-NEXT: add a5, a5, a0
228 ; RV32ZBA-NEXT: xor a0, a1, a5
229 ; RV32ZBA-NEXT: xor a1, a1, a3
230 ; RV32ZBA-NEXT: not a1, a1
231 ; RV32ZBA-NEXT: and a0, a1, a0
232 ; RV32ZBA-NEXT: slti a0, a0, 0
233 ; RV32ZBA-NEXT: sw a2, 0(a4)
234 ; RV32ZBA-NEXT: sw a5, 4(a4)
237 ; RV64ZBA-LABEL: saddo1.i64:
238 ; RV64ZBA: # %bb.0: # %entry
239 ; RV64ZBA-NEXT: add a3, a0, a1
240 ; RV64ZBA-NEXT: slt a0, a3, a0
241 ; RV64ZBA-NEXT: slti a1, a1, 0
242 ; RV64ZBA-NEXT: xor a0, a1, a0
243 ; RV64ZBA-NEXT: sd a3, 0(a2)
246 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2)
247 %val = extractvalue {i64, i1} %t, 0
248 %obit = extractvalue {i64, i1} %t, 1
249 store i64 %val, i64* %res
253 define zeroext i1 @saddo2.i64(i64 %v1, i64* %res) {
254 ; RV32-LABEL: saddo2.i64:
255 ; RV32: # %bb.0: # %entry
256 ; RV32-NEXT: addi a3, a0, 4
257 ; RV32-NEXT: sltu a0, a3, a0
258 ; RV32-NEXT: add a4, a1, a0
259 ; RV32-NEXT: xor a0, a1, a4
260 ; RV32-NEXT: not a1, a1
261 ; RV32-NEXT: and a0, a1, a0
262 ; RV32-NEXT: slti a0, a0, 0
263 ; RV32-NEXT: sw a3, 0(a2)
264 ; RV32-NEXT: sw a4, 4(a2)
267 ; RV64-LABEL: saddo2.i64:
268 ; RV64: # %bb.0: # %entry
269 ; RV64-NEXT: addi a2, a0, 4
270 ; RV64-NEXT: slt a0, a2, a0
271 ; RV64-NEXT: sd a2, 0(a1)
274 ; RV32ZBA-LABEL: saddo2.i64:
275 ; RV32ZBA: # %bb.0: # %entry
276 ; RV32ZBA-NEXT: addi a3, a0, 4
277 ; RV32ZBA-NEXT: sltu a0, a3, a0
278 ; RV32ZBA-NEXT: add a4, a1, a0
279 ; RV32ZBA-NEXT: xor a0, a1, a4
280 ; RV32ZBA-NEXT: not a1, a1
281 ; RV32ZBA-NEXT: and a0, a1, a0
282 ; RV32ZBA-NEXT: slti a0, a0, 0
283 ; RV32ZBA-NEXT: sw a3, 0(a2)
284 ; RV32ZBA-NEXT: sw a4, 4(a2)
287 ; RV64ZBA-LABEL: saddo2.i64:
288 ; RV64ZBA: # %bb.0: # %entry
289 ; RV64ZBA-NEXT: addi a2, a0, 4
290 ; RV64ZBA-NEXT: slt a0, a2, a0
291 ; RV64ZBA-NEXT: sd a2, 0(a1)
294 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 4)
295 %val = extractvalue {i64, i1} %t, 0
296 %obit = extractvalue {i64, i1} %t, 1
297 store i64 %val, i64* %res
301 define zeroext i1 @saddo3.i64(i64 %v1, i64* %res) {
302 ; RV32-LABEL: saddo3.i64:
303 ; RV32: # %bb.0: # %entry
304 ; RV32-NEXT: addi a3, a0, -4
305 ; RV32-NEXT: sltu a0, a3, a0
306 ; RV32-NEXT: add a0, a1, a0
307 ; RV32-NEXT: addi a4, a0, -1
308 ; RV32-NEXT: xor a0, a1, a4
309 ; RV32-NEXT: and a0, a1, a0
310 ; RV32-NEXT: slti a0, a0, 0
311 ; RV32-NEXT: sw a3, 0(a2)
312 ; RV32-NEXT: sw a4, 4(a2)
315 ; RV64-LABEL: saddo3.i64:
316 ; RV64: # %bb.0: # %entry
317 ; RV64-NEXT: addi a2, a0, -4
318 ; RV64-NEXT: slt a0, a2, a0
319 ; RV64-NEXT: xori a0, a0, 1
320 ; RV64-NEXT: sd a2, 0(a1)
323 ; RV32ZBA-LABEL: saddo3.i64:
324 ; RV32ZBA: # %bb.0: # %entry
325 ; RV32ZBA-NEXT: addi a3, a0, -4
326 ; RV32ZBA-NEXT: sltu a0, a3, a0
327 ; RV32ZBA-NEXT: add a0, a1, a0
328 ; RV32ZBA-NEXT: addi a4, a0, -1
329 ; RV32ZBA-NEXT: xor a0, a1, a4
330 ; RV32ZBA-NEXT: and a0, a1, a0
331 ; RV32ZBA-NEXT: slti a0, a0, 0
332 ; RV32ZBA-NEXT: sw a3, 0(a2)
333 ; RV32ZBA-NEXT: sw a4, 4(a2)
336 ; RV64ZBA-LABEL: saddo3.i64:
337 ; RV64ZBA: # %bb.0: # %entry
338 ; RV64ZBA-NEXT: addi a2, a0, -4
339 ; RV64ZBA-NEXT: slt a0, a2, a0
340 ; RV64ZBA-NEXT: xori a0, a0, 1
341 ; RV64ZBA-NEXT: sd a2, 0(a1)
344 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 -4)
345 %val = extractvalue {i64, i1} %t, 0
346 %obit = extractvalue {i64, i1} %t, 1
347 store i64 %val, i64* %res
351 define zeroext i1 @uaddo.i32(i32 %v1, i32 %v2, i32* %res) {
352 ; RV32-LABEL: uaddo.i32:
353 ; RV32: # %bb.0: # %entry
354 ; RV32-NEXT: add a1, a0, a1
355 ; RV32-NEXT: sltu a0, a1, a0
356 ; RV32-NEXT: sw a1, 0(a2)
359 ; RV64-LABEL: uaddo.i32:
360 ; RV64: # %bb.0: # %entry
361 ; RV64-NEXT: addw a1, a0, a1
362 ; RV64-NEXT: sext.w a0, a0
363 ; RV64-NEXT: sltu a0, a1, a0
364 ; RV64-NEXT: sw a1, 0(a2)
367 ; RV32ZBA-LABEL: uaddo.i32:
368 ; RV32ZBA: # %bb.0: # %entry
369 ; RV32ZBA-NEXT: add a1, a0, a1
370 ; RV32ZBA-NEXT: sltu a0, a1, a0
371 ; RV32ZBA-NEXT: sw a1, 0(a2)
374 ; RV64ZBA-LABEL: uaddo.i32:
375 ; RV64ZBA: # %bb.0: # %entry
376 ; RV64ZBA-NEXT: addw a1, a0, a1
377 ; RV64ZBA-NEXT: sext.w a0, a0
378 ; RV64ZBA-NEXT: sltu a0, a1, a0
379 ; RV64ZBA-NEXT: sw a1, 0(a2)
382 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)
383 %val = extractvalue {i32, i1} %t, 0
384 %obit = extractvalue {i32, i1} %t, 1
385 store i32 %val, i32* %res
389 define zeroext i1 @uaddo.i32.constant(i32 %v1, i32* %res) {
390 ; RV32-LABEL: uaddo.i32.constant:
391 ; RV32: # %bb.0: # %entry
392 ; RV32-NEXT: addi a2, a0, -2
393 ; RV32-NEXT: sltu a0, a2, a0
394 ; RV32-NEXT: sw a2, 0(a1)
397 ; RV64-LABEL: uaddo.i32.constant:
398 ; RV64: # %bb.0: # %entry
399 ; RV64-NEXT: sext.w a2, a0
400 ; RV64-NEXT: addiw a3, a0, -2
401 ; RV64-NEXT: sltu a0, a3, a2
402 ; RV64-NEXT: sw a3, 0(a1)
405 ; RV32ZBA-LABEL: uaddo.i32.constant:
406 ; RV32ZBA: # %bb.0: # %entry
407 ; RV32ZBA-NEXT: addi a2, a0, -2
408 ; RV32ZBA-NEXT: sltu a0, a2, a0
409 ; RV32ZBA-NEXT: sw a2, 0(a1)
412 ; RV64ZBA-LABEL: uaddo.i32.constant:
413 ; RV64ZBA: # %bb.0: # %entry
414 ; RV64ZBA-NEXT: sext.w a2, a0
415 ; RV64ZBA-NEXT: addiw a3, a0, -2
416 ; RV64ZBA-NEXT: sltu a0, a3, a2
417 ; RV64ZBA-NEXT: sw a3, 0(a1)
420 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 -2)
421 %val = extractvalue {i32, i1} %t, 0
422 %obit = extractvalue {i32, i1} %t, 1
423 store i32 %val, i32* %res
427 define zeroext i1 @uaddo.i64(i64 %v1, i64 %v2, i64* %res) {
428 ; RV32-LABEL: uaddo.i64:
429 ; RV32: # %bb.0: # %entry
430 ; RV32-NEXT: add a3, a1, a3
431 ; RV32-NEXT: add a2, a0, a2
432 ; RV32-NEXT: sltu a0, a2, a0
433 ; RV32-NEXT: add a3, a3, a0
434 ; RV32-NEXT: beq a3, a1, .LBB9_2
435 ; RV32-NEXT: # %bb.1: # %entry
436 ; RV32-NEXT: sltu a0, a3, a1
437 ; RV32-NEXT: .LBB9_2: # %entry
438 ; RV32-NEXT: sw a2, 0(a4)
439 ; RV32-NEXT: sw a3, 4(a4)
442 ; RV64-LABEL: uaddo.i64:
443 ; RV64: # %bb.0: # %entry
444 ; RV64-NEXT: add a1, a0, a1
445 ; RV64-NEXT: sltu a0, a1, a0
446 ; RV64-NEXT: sd a1, 0(a2)
449 ; RV32ZBA-LABEL: uaddo.i64:
450 ; RV32ZBA: # %bb.0: # %entry
451 ; RV32ZBA-NEXT: add a3, a1, a3
452 ; RV32ZBA-NEXT: add a2, a0, a2
453 ; RV32ZBA-NEXT: sltu a0, a2, a0
454 ; RV32ZBA-NEXT: add a3, a3, a0
455 ; RV32ZBA-NEXT: beq a3, a1, .LBB9_2
456 ; RV32ZBA-NEXT: # %bb.1: # %entry
457 ; RV32ZBA-NEXT: sltu a0, a3, a1
458 ; RV32ZBA-NEXT: .LBB9_2: # %entry
459 ; RV32ZBA-NEXT: sw a2, 0(a4)
460 ; RV32ZBA-NEXT: sw a3, 4(a4)
463 ; RV64ZBA-LABEL: uaddo.i64:
464 ; RV64ZBA: # %bb.0: # %entry
465 ; RV64ZBA-NEXT: add a1, a0, a1
466 ; RV64ZBA-NEXT: sltu a0, a1, a0
467 ; RV64ZBA-NEXT: sd a1, 0(a2)
470 %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2)
471 %val = extractvalue {i64, i1} %t, 0
472 %obit = extractvalue {i64, i1} %t, 1
473 store i64 %val, i64* %res
477 define zeroext i1 @ssubo1.i32(i32 %v1, i32 %v2, i32* %res) {
478 ; RV32-LABEL: ssubo1.i32:
479 ; RV32: # %bb.0: # %entry
480 ; RV32-NEXT: sgtz a3, a1
481 ; RV32-NEXT: sub a1, a0, a1
482 ; RV32-NEXT: slt a0, a1, a0
483 ; RV32-NEXT: xor a0, a3, a0
484 ; RV32-NEXT: sw a1, 0(a2)
487 ; RV64-LABEL: ssubo1.i32:
488 ; RV64: # %bb.0: # %entry
489 ; RV64-NEXT: sext.w a1, a1
490 ; RV64-NEXT: sext.w a0, a0
491 ; RV64-NEXT: sub a3, a0, a1
492 ; RV64-NEXT: subw a0, a0, a1
493 ; RV64-NEXT: xor a0, a0, a3
494 ; RV64-NEXT: snez a0, a0
495 ; RV64-NEXT: sw a3, 0(a2)
498 ; RV32ZBA-LABEL: ssubo1.i32:
499 ; RV32ZBA: # %bb.0: # %entry
500 ; RV32ZBA-NEXT: sgtz a3, a1
501 ; RV32ZBA-NEXT: sub a1, a0, a1
502 ; RV32ZBA-NEXT: slt a0, a1, a0
503 ; RV32ZBA-NEXT: xor a0, a3, a0
504 ; RV32ZBA-NEXT: sw a1, 0(a2)
507 ; RV64ZBA-LABEL: ssubo1.i32:
508 ; RV64ZBA: # %bb.0: # %entry
509 ; RV64ZBA-NEXT: sext.w a1, a1
510 ; RV64ZBA-NEXT: sext.w a0, a0
511 ; RV64ZBA-NEXT: sub a3, a0, a1
512 ; RV64ZBA-NEXT: subw a0, a0, a1
513 ; RV64ZBA-NEXT: xor a0, a0, a3
514 ; RV64ZBA-NEXT: snez a0, a0
515 ; RV64ZBA-NEXT: sw a3, 0(a2)
518 %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2)
519 %val = extractvalue {i32, i1} %t, 0
520 %obit = extractvalue {i32, i1} %t, 1
521 store i32 %val, i32* %res
525 define zeroext i1 @ssubo2.i32(i32 %v1, i32* %res) {
526 ; RV32-LABEL: ssubo2.i32:
527 ; RV32: # %bb.0: # %entry
528 ; RV32-NEXT: addi a2, a0, 4
529 ; RV32-NEXT: slt a0, a2, a0
530 ; RV32-NEXT: sw a2, 0(a1)
533 ; RV64-LABEL: ssubo2.i32:
534 ; RV64: # %bb.0: # %entry
535 ; RV64-NEXT: sext.w a0, a0
536 ; RV64-NEXT: addi a2, a0, 4
537 ; RV64-NEXT: addiw a0, a0, 4
538 ; RV64-NEXT: xor a0, a0, a2
539 ; RV64-NEXT: snez a0, a0
540 ; RV64-NEXT: sw a2, 0(a1)
543 ; RV32ZBA-LABEL: ssubo2.i32:
544 ; RV32ZBA: # %bb.0: # %entry
545 ; RV32ZBA-NEXT: addi a2, a0, 4
546 ; RV32ZBA-NEXT: slt a0, a2, a0
547 ; RV32ZBA-NEXT: sw a2, 0(a1)
550 ; RV64ZBA-LABEL: ssubo2.i32:
551 ; RV64ZBA: # %bb.0: # %entry
552 ; RV64ZBA-NEXT: sext.w a0, a0
553 ; RV64ZBA-NEXT: addi a2, a0, 4
554 ; RV64ZBA-NEXT: addiw a0, a0, 4
555 ; RV64ZBA-NEXT: xor a0, a0, a2
556 ; RV64ZBA-NEXT: snez a0, a0
557 ; RV64ZBA-NEXT: sw a2, 0(a1)
560 %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 -4)
561 %val = extractvalue {i32, i1} %t, 0
562 %obit = extractvalue {i32, i1} %t, 1
563 store i32 %val, i32* %res
567 define zeroext i1 @ssubo.i64(i64 %v1, i64 %v2, i64* %res) {
568 ; RV32-LABEL: ssubo.i64:
569 ; RV32: # %bb.0: # %entry
570 ; RV32-NEXT: sltu a6, a0, a2
571 ; RV32-NEXT: sub a5, a1, a3
572 ; RV32-NEXT: sub a5, a5, a6
573 ; RV32-NEXT: xor a6, a1, a5
574 ; RV32-NEXT: xor a1, a1, a3
575 ; RV32-NEXT: and a1, a1, a6
576 ; RV32-NEXT: slti a1, a1, 0
577 ; RV32-NEXT: sub a0, a0, a2
578 ; RV32-NEXT: sw a0, 0(a4)
579 ; RV32-NEXT: sw a5, 4(a4)
580 ; RV32-NEXT: mv a0, a1
583 ; RV64-LABEL: ssubo.i64:
584 ; RV64: # %bb.0: # %entry
585 ; RV64-NEXT: sgtz a3, a1
586 ; RV64-NEXT: sub a1, a0, a1
587 ; RV64-NEXT: slt a0, a1, a0
588 ; RV64-NEXT: xor a0, a3, a0
589 ; RV64-NEXT: sd a1, 0(a2)
592 ; RV32ZBA-LABEL: ssubo.i64:
593 ; RV32ZBA: # %bb.0: # %entry
594 ; RV32ZBA-NEXT: sltu a6, a0, a2
595 ; RV32ZBA-NEXT: sub a5, a1, a3
596 ; RV32ZBA-NEXT: sub a5, a5, a6
597 ; RV32ZBA-NEXT: xor a6, a1, a5
598 ; RV32ZBA-NEXT: xor a1, a1, a3
599 ; RV32ZBA-NEXT: and a1, a1, a6
600 ; RV32ZBA-NEXT: slti a1, a1, 0
601 ; RV32ZBA-NEXT: sub a0, a0, a2
602 ; RV32ZBA-NEXT: sw a0, 0(a4)
603 ; RV32ZBA-NEXT: sw a5, 4(a4)
604 ; RV32ZBA-NEXT: mv a0, a1
607 ; RV64ZBA-LABEL: ssubo.i64:
608 ; RV64ZBA: # %bb.0: # %entry
609 ; RV64ZBA-NEXT: sgtz a3, a1
610 ; RV64ZBA-NEXT: sub a1, a0, a1
611 ; RV64ZBA-NEXT: slt a0, a1, a0
612 ; RV64ZBA-NEXT: xor a0, a3, a0
613 ; RV64ZBA-NEXT: sd a1, 0(a2)
616 %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2)
617 %val = extractvalue {i64, i1} %t, 0
618 %obit = extractvalue {i64, i1} %t, 1
619 store i64 %val, i64* %res
623 define zeroext i1 @usubo.i32(i32 %v1, i32 %v2, i32* %res) {
624 ; RV32-LABEL: usubo.i32:
625 ; RV32: # %bb.0: # %entry
626 ; RV32-NEXT: sub a1, a0, a1
627 ; RV32-NEXT: sltu a0, a0, a1
628 ; RV32-NEXT: sw a1, 0(a2)
631 ; RV64-LABEL: usubo.i32:
632 ; RV64: # %bb.0: # %entry
633 ; RV64-NEXT: subw a1, a0, a1
634 ; RV64-NEXT: sext.w a0, a0
635 ; RV64-NEXT: sltu a0, a0, a1
636 ; RV64-NEXT: sw a1, 0(a2)
639 ; RV32ZBA-LABEL: usubo.i32:
640 ; RV32ZBA: # %bb.0: # %entry
641 ; RV32ZBA-NEXT: sub a1, a0, a1
642 ; RV32ZBA-NEXT: sltu a0, a0, a1
643 ; RV32ZBA-NEXT: sw a1, 0(a2)
646 ; RV64ZBA-LABEL: usubo.i32:
647 ; RV64ZBA: # %bb.0: # %entry
648 ; RV64ZBA-NEXT: subw a1, a0, a1
649 ; RV64ZBA-NEXT: sext.w a0, a0
650 ; RV64ZBA-NEXT: sltu a0, a0, a1
651 ; RV64ZBA-NEXT: sw a1, 0(a2)
654 %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2)
655 %val = extractvalue {i32, i1} %t, 0
656 %obit = extractvalue {i32, i1} %t, 1
657 store i32 %val, i32* %res
661 define zeroext i1 @usubo.i32.constant.rhs(i32 %v1, i32* %res) {
662 ; RV32-LABEL: usubo.i32.constant.rhs:
663 ; RV32: # %bb.0: # %entry
664 ; RV32-NEXT: addi a2, a0, 2
665 ; RV32-NEXT: sltu a0, a0, a2
666 ; RV32-NEXT: sw a2, 0(a1)
669 ; RV64-LABEL: usubo.i32.constant.rhs:
670 ; RV64: # %bb.0: # %entry
671 ; RV64-NEXT: addiw a2, a0, 2
672 ; RV64-NEXT: sext.w a0, a0
673 ; RV64-NEXT: sltu a0, a0, a2
674 ; RV64-NEXT: sw a2, 0(a1)
677 ; RV32ZBA-LABEL: usubo.i32.constant.rhs:
678 ; RV32ZBA: # %bb.0: # %entry
679 ; RV32ZBA-NEXT: addi a2, a0, 2
680 ; RV32ZBA-NEXT: sltu a0, a0, a2
681 ; RV32ZBA-NEXT: sw a2, 0(a1)
684 ; RV64ZBA-LABEL: usubo.i32.constant.rhs:
685 ; RV64ZBA: # %bb.0: # %entry
686 ; RV64ZBA-NEXT: addiw a2, a0, 2
687 ; RV64ZBA-NEXT: sext.w a0, a0
688 ; RV64ZBA-NEXT: sltu a0, a0, a2
689 ; RV64ZBA-NEXT: sw a2, 0(a1)
692 %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 -2)
693 %val = extractvalue {i32, i1} %t, 0
694 %obit = extractvalue {i32, i1} %t, 1
695 store i32 %val, i32* %res
699 define zeroext i1 @usubo.i32.constant.lhs(i32 %v1, i32* %res) {
700 ; RV32-LABEL: usubo.i32.constant.lhs:
701 ; RV32: # %bb.0: # %entry
702 ; RV32-NEXT: addi a2, zero, -2
703 ; RV32-NEXT: sub a2, a2, a0
704 ; RV32-NEXT: addi a0, a2, 1
705 ; RV32-NEXT: seqz a0, a0
706 ; RV32-NEXT: sw a2, 0(a1)
709 ; RV64-LABEL: usubo.i32.constant.lhs:
710 ; RV64: # %bb.0: # %entry
711 ; RV64-NEXT: addi a2, zero, -2
712 ; RV64-NEXT: subw a2, a2, a0
713 ; RV64-NEXT: addi a0, a2, 1
714 ; RV64-NEXT: seqz a0, a0
715 ; RV64-NEXT: sw a2, 0(a1)
718 ; RV32ZBA-LABEL: usubo.i32.constant.lhs:
719 ; RV32ZBA: # %bb.0: # %entry
720 ; RV32ZBA-NEXT: addi a2, zero, -2
721 ; RV32ZBA-NEXT: sub a2, a2, a0
722 ; RV32ZBA-NEXT: addi a0, a2, 1
723 ; RV32ZBA-NEXT: seqz a0, a0
724 ; RV32ZBA-NEXT: sw a2, 0(a1)
727 ; RV64ZBA-LABEL: usubo.i32.constant.lhs:
728 ; RV64ZBA: # %bb.0: # %entry
729 ; RV64ZBA-NEXT: addi a2, zero, -2
730 ; RV64ZBA-NEXT: subw a2, a2, a0
731 ; RV64ZBA-NEXT: addi a0, a2, 1
732 ; RV64ZBA-NEXT: seqz a0, a0
733 ; RV64ZBA-NEXT: sw a2, 0(a1)
736 %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 -2, i32 %v1)
737 %val = extractvalue {i32, i1} %t, 0
738 %obit = extractvalue {i32, i1} %t, 1
739 store i32 %val, i32* %res
743 define zeroext i1 @usubo.i64(i64 %v1, i64 %v2, i64* %res) {
744 ; RV32-LABEL: usubo.i64:
745 ; RV32: # %bb.0: # %entry
746 ; RV32-NEXT: sltu a5, a0, a2
747 ; RV32-NEXT: sub a3, a1, a3
748 ; RV32-NEXT: sub a3, a3, a5
749 ; RV32-NEXT: sub a2, a0, a2
750 ; RV32-NEXT: beq a3, a1, .LBB16_2
751 ; RV32-NEXT: # %bb.1: # %entry
752 ; RV32-NEXT: sltu a0, a1, a3
753 ; RV32-NEXT: j .LBB16_3
754 ; RV32-NEXT: .LBB16_2:
755 ; RV32-NEXT: sltu a0, a0, a2
756 ; RV32-NEXT: .LBB16_3: # %entry
757 ; RV32-NEXT: sw a2, 0(a4)
758 ; RV32-NEXT: sw a3, 4(a4)
761 ; RV64-LABEL: usubo.i64:
762 ; RV64: # %bb.0: # %entry
763 ; RV64-NEXT: sub a1, a0, a1
764 ; RV64-NEXT: sltu a0, a0, a1
765 ; RV64-NEXT: sd a1, 0(a2)
768 ; RV32ZBA-LABEL: usubo.i64:
769 ; RV32ZBA: # %bb.0: # %entry
770 ; RV32ZBA-NEXT: sltu a5, a0, a2
771 ; RV32ZBA-NEXT: sub a3, a1, a3
772 ; RV32ZBA-NEXT: sub a3, a3, a5
773 ; RV32ZBA-NEXT: sub a2, a0, a2
774 ; RV32ZBA-NEXT: beq a3, a1, .LBB16_2
775 ; RV32ZBA-NEXT: # %bb.1: # %entry
776 ; RV32ZBA-NEXT: sltu a0, a1, a3
777 ; RV32ZBA-NEXT: j .LBB16_3
778 ; RV32ZBA-NEXT: .LBB16_2:
779 ; RV32ZBA-NEXT: sltu a0, a0, a2
780 ; RV32ZBA-NEXT: .LBB16_3: # %entry
781 ; RV32ZBA-NEXT: sw a2, 0(a4)
782 ; RV32ZBA-NEXT: sw a3, 4(a4)
785 ; RV64ZBA-LABEL: usubo.i64:
786 ; RV64ZBA: # %bb.0: # %entry
787 ; RV64ZBA-NEXT: sub a1, a0, a1
788 ; RV64ZBA-NEXT: sltu a0, a0, a1
789 ; RV64ZBA-NEXT: sd a1, 0(a2)
792 %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2)
793 %val = extractvalue {i64, i1} %t, 0
794 %obit = extractvalue {i64, i1} %t, 1
795 store i64 %val, i64* %res
799 define zeroext i1 @smulo.i32(i32 %v1, i32 %v2, i32* %res) {
800 ; RV32-LABEL: smulo.i32:
801 ; RV32: # %bb.0: # %entry
802 ; RV32-NEXT: mulh a3, a0, a1
803 ; RV32-NEXT: mul a1, a0, a1
804 ; RV32-NEXT: srai a0, a1, 31
805 ; RV32-NEXT: xor a0, a3, a0
806 ; RV32-NEXT: snez a0, a0
807 ; RV32-NEXT: sw a1, 0(a2)
810 ; RV64-LABEL: smulo.i32:
811 ; RV64: # %bb.0: # %entry
812 ; RV64-NEXT: sext.w a1, a1
813 ; RV64-NEXT: sext.w a0, a0
814 ; RV64-NEXT: mul a3, a0, a1
815 ; RV64-NEXT: mulw a0, a0, a1
816 ; RV64-NEXT: xor a0, a0, a3
817 ; RV64-NEXT: snez a0, a0
818 ; RV64-NEXT: sw a3, 0(a2)
821 ; RV32ZBA-LABEL: smulo.i32:
822 ; RV32ZBA: # %bb.0: # %entry
823 ; RV32ZBA-NEXT: mulh a3, a0, a1
824 ; RV32ZBA-NEXT: mul a1, a0, a1
825 ; RV32ZBA-NEXT: srai a0, a1, 31
826 ; RV32ZBA-NEXT: xor a0, a3, a0
827 ; RV32ZBA-NEXT: snez a0, a0
828 ; RV32ZBA-NEXT: sw a1, 0(a2)
831 ; RV64ZBA-LABEL: smulo.i32:
832 ; RV64ZBA: # %bb.0: # %entry
833 ; RV64ZBA-NEXT: sext.w a1, a1
834 ; RV64ZBA-NEXT: sext.w a0, a0
835 ; RV64ZBA-NEXT: mul a3, a0, a1
836 ; RV64ZBA-NEXT: mulw a0, a0, a1
837 ; RV64ZBA-NEXT: xor a0, a0, a3
838 ; RV64ZBA-NEXT: snez a0, a0
839 ; RV64ZBA-NEXT: sw a3, 0(a2)
842 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
843 %val = extractvalue {i32, i1} %t, 0
844 %obit = extractvalue {i32, i1} %t, 1
845 store i32 %val, i32* %res
849 define zeroext i1 @smulo2.i32(i32 %v1, i32* %res) {
850 ; RV32-LABEL: smulo2.i32:
851 ; RV32: # %bb.0: # %entry
852 ; RV32-NEXT: addi a2, zero, 13
853 ; RV32-NEXT: mulh a3, a0, a2
854 ; RV32-NEXT: mul a2, a0, a2
855 ; RV32-NEXT: srai a0, a2, 31
856 ; RV32-NEXT: xor a0, a3, a0
857 ; RV32-NEXT: snez a0, a0
858 ; RV32-NEXT: sw a2, 0(a1)
861 ; RV64-LABEL: smulo2.i32:
862 ; RV64: # %bb.0: # %entry
863 ; RV64-NEXT: sext.w a0, a0
864 ; RV64-NEXT: addi a2, zero, 13
865 ; RV64-NEXT: mul a3, a0, a2
866 ; RV64-NEXT: mulw a0, a0, a2
867 ; RV64-NEXT: xor a0, a0, a3
868 ; RV64-NEXT: snez a0, a0
869 ; RV64-NEXT: sw a3, 0(a1)
872 ; RV32ZBA-LABEL: smulo2.i32:
873 ; RV32ZBA: # %bb.0: # %entry
874 ; RV32ZBA-NEXT: addi a2, zero, 13
875 ; RV32ZBA-NEXT: mulh a3, a0, a2
876 ; RV32ZBA-NEXT: mul a2, a0, a2
877 ; RV32ZBA-NEXT: srai a0, a2, 31
878 ; RV32ZBA-NEXT: xor a0, a3, a0
879 ; RV32ZBA-NEXT: snez a0, a0
880 ; RV32ZBA-NEXT: sw a2, 0(a1)
883 ; RV64ZBA-LABEL: smulo2.i32:
884 ; RV64ZBA: # %bb.0: # %entry
885 ; RV64ZBA-NEXT: sext.w a0, a0
886 ; RV64ZBA-NEXT: sh1add a2, a0, a0
887 ; RV64ZBA-NEXT: sh2add a2, a2, a0
888 ; RV64ZBA-NEXT: sext.w a0, a2
889 ; RV64ZBA-NEXT: xor a0, a0, a2
890 ; RV64ZBA-NEXT: snez a0, a0
891 ; RV64ZBA-NEXT: sw a2, 0(a1)
894 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 13)
895 %val = extractvalue {i32, i1} %t, 0
896 %obit = extractvalue {i32, i1} %t, 1
897 store i32 %val, i32* %res
901 define zeroext i1 @smulo.i64(i64 %v1, i64 %v2, i64* %res) {
902 ; RV32-LABEL: smulo.i64:
903 ; RV32: # %bb.0: # %entry
904 ; RV32-NEXT: addi sp, sp, -16
905 ; RV32-NEXT: .cfi_def_cfa_offset 16
906 ; RV32-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
907 ; RV32-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
908 ; RV32-NEXT: .cfi_offset ra, -4
909 ; RV32-NEXT: .cfi_offset s0, -8
910 ; RV32-NEXT: mv s0, a4
911 ; RV32-NEXT: sw zero, 4(sp)
912 ; RV32-NEXT: addi a4, sp, 4
913 ; RV32-NEXT: call __mulodi4@plt
914 ; RV32-NEXT: lw a2, 4(sp)
915 ; RV32-NEXT: snez a2, a2
916 ; RV32-NEXT: sw a1, 4(s0)
917 ; RV32-NEXT: sw a0, 0(s0)
918 ; RV32-NEXT: mv a0, a2
919 ; RV32-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
920 ; RV32-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
921 ; RV32-NEXT: addi sp, sp, 16
924 ; RV64-LABEL: smulo.i64:
925 ; RV64: # %bb.0: # %entry
926 ; RV64-NEXT: mulh a3, a0, a1
927 ; RV64-NEXT: mul a1, a0, a1
928 ; RV64-NEXT: srai a0, a1, 63
929 ; RV64-NEXT: xor a0, a3, a0
930 ; RV64-NEXT: snez a0, a0
931 ; RV64-NEXT: sd a1, 0(a2)
934 ; RV32ZBA-LABEL: smulo.i64:
935 ; RV32ZBA: # %bb.0: # %entry
936 ; RV32ZBA-NEXT: addi sp, sp, -16
937 ; RV32ZBA-NEXT: .cfi_def_cfa_offset 16
938 ; RV32ZBA-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
939 ; RV32ZBA-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
940 ; RV32ZBA-NEXT: .cfi_offset ra, -4
941 ; RV32ZBA-NEXT: .cfi_offset s0, -8
942 ; RV32ZBA-NEXT: mv s0, a4
943 ; RV32ZBA-NEXT: sw zero, 4(sp)
944 ; RV32ZBA-NEXT: addi a4, sp, 4
945 ; RV32ZBA-NEXT: call __mulodi4@plt
946 ; RV32ZBA-NEXT: lw a2, 4(sp)
947 ; RV32ZBA-NEXT: snez a2, a2
948 ; RV32ZBA-NEXT: sw a1, 4(s0)
949 ; RV32ZBA-NEXT: sw a0, 0(s0)
950 ; RV32ZBA-NEXT: mv a0, a2
951 ; RV32ZBA-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
952 ; RV32ZBA-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
953 ; RV32ZBA-NEXT: addi sp, sp, 16
956 ; RV64ZBA-LABEL: smulo.i64:
957 ; RV64ZBA: # %bb.0: # %entry
958 ; RV64ZBA-NEXT: mulh a3, a0, a1
959 ; RV64ZBA-NEXT: mul a1, a0, a1
960 ; RV64ZBA-NEXT: srai a0, a1, 63
961 ; RV64ZBA-NEXT: xor a0, a3, a0
962 ; RV64ZBA-NEXT: snez a0, a0
963 ; RV64ZBA-NEXT: sd a1, 0(a2)
966 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
967 %val = extractvalue {i64, i1} %t, 0
968 %obit = extractvalue {i64, i1} %t, 1
969 store i64 %val, i64* %res
973 define zeroext i1 @smulo2.i64(i64 %v1, i64* %res) {
974 ; RV32-LABEL: smulo2.i64:
975 ; RV32: # %bb.0: # %entry
976 ; RV32-NEXT: addi sp, sp, -16
977 ; RV32-NEXT: .cfi_def_cfa_offset 16
978 ; RV32-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
979 ; RV32-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
980 ; RV32-NEXT: .cfi_offset ra, -4
981 ; RV32-NEXT: .cfi_offset s0, -8
982 ; RV32-NEXT: mv s0, a2
983 ; RV32-NEXT: sw zero, 4(sp)
984 ; RV32-NEXT: addi a2, zero, 13
985 ; RV32-NEXT: addi a4, sp, 4
986 ; RV32-NEXT: mv a3, zero
987 ; RV32-NEXT: call __mulodi4@plt
988 ; RV32-NEXT: lw a2, 4(sp)
989 ; RV32-NEXT: snez a2, a2
990 ; RV32-NEXT: sw a1, 4(s0)
991 ; RV32-NEXT: sw a0, 0(s0)
992 ; RV32-NEXT: mv a0, a2
993 ; RV32-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
994 ; RV32-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
995 ; RV32-NEXT: addi sp, sp, 16
998 ; RV64-LABEL: smulo2.i64:
999 ; RV64: # %bb.0: # %entry
1000 ; RV64-NEXT: addi a2, zero, 13
1001 ; RV64-NEXT: mulh a3, a0, a2
1002 ; RV64-NEXT: mul a2, a0, a2
1003 ; RV64-NEXT: srai a0, a2, 63
1004 ; RV64-NEXT: xor a0, a3, a0
1005 ; RV64-NEXT: snez a0, a0
1006 ; RV64-NEXT: sd a2, 0(a1)
1009 ; RV32ZBA-LABEL: smulo2.i64:
1010 ; RV32ZBA: # %bb.0: # %entry
1011 ; RV32ZBA-NEXT: addi sp, sp, -16
1012 ; RV32ZBA-NEXT: .cfi_def_cfa_offset 16
1013 ; RV32ZBA-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
1014 ; RV32ZBA-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
1015 ; RV32ZBA-NEXT: .cfi_offset ra, -4
1016 ; RV32ZBA-NEXT: .cfi_offset s0, -8
1017 ; RV32ZBA-NEXT: mv s0, a2
1018 ; RV32ZBA-NEXT: sw zero, 4(sp)
1019 ; RV32ZBA-NEXT: addi a2, zero, 13
1020 ; RV32ZBA-NEXT: addi a4, sp, 4
1021 ; RV32ZBA-NEXT: mv a3, zero
1022 ; RV32ZBA-NEXT: call __mulodi4@plt
1023 ; RV32ZBA-NEXT: lw a2, 4(sp)
1024 ; RV32ZBA-NEXT: snez a2, a2
1025 ; RV32ZBA-NEXT: sw a1, 4(s0)
1026 ; RV32ZBA-NEXT: sw a0, 0(s0)
1027 ; RV32ZBA-NEXT: mv a0, a2
1028 ; RV32ZBA-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
1029 ; RV32ZBA-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
1030 ; RV32ZBA-NEXT: addi sp, sp, 16
1033 ; RV64ZBA-LABEL: smulo2.i64:
1034 ; RV64ZBA: # %bb.0: # %entry
1035 ; RV64ZBA-NEXT: addi a2, zero, 13
1036 ; RV64ZBA-NEXT: mulh a3, a0, a2
1037 ; RV64ZBA-NEXT: mul a2, a0, a2
1038 ; RV64ZBA-NEXT: srai a0, a2, 63
1039 ; RV64ZBA-NEXT: xor a0, a3, a0
1040 ; RV64ZBA-NEXT: snez a0, a0
1041 ; RV64ZBA-NEXT: sd a2, 0(a1)
1044 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 13)
1045 %val = extractvalue {i64, i1} %t, 0
1046 %obit = extractvalue {i64, i1} %t, 1
1047 store i64 %val, i64* %res
1051 define zeroext i1 @umulo.i32(i32 %v1, i32 %v2, i32* %res) {
1052 ; RV32-LABEL: umulo.i32:
1053 ; RV32: # %bb.0: # %entry
1054 ; RV32-NEXT: mulhu a3, a0, a1
1055 ; RV32-NEXT: snez a3, a3
1056 ; RV32-NEXT: mul a0, a0, a1
1057 ; RV32-NEXT: sw a0, 0(a2)
1058 ; RV32-NEXT: mv a0, a3
1061 ; RV64-LABEL: umulo.i32:
1062 ; RV64: # %bb.0: # %entry
1063 ; RV64-NEXT: slli a1, a1, 32
1064 ; RV64-NEXT: slli a0, a0, 32
1065 ; RV64-NEXT: mulhu a1, a0, a1
1066 ; RV64-NEXT: srli a0, a1, 32
1067 ; RV64-NEXT: snez a0, a0
1068 ; RV64-NEXT: sw a1, 0(a2)
1071 ; RV32ZBA-LABEL: umulo.i32:
1072 ; RV32ZBA: # %bb.0: # %entry
1073 ; RV32ZBA-NEXT: mulhu a3, a0, a1
1074 ; RV32ZBA-NEXT: snez a3, a3
1075 ; RV32ZBA-NEXT: mul a0, a0, a1
1076 ; RV32ZBA-NEXT: sw a0, 0(a2)
1077 ; RV32ZBA-NEXT: mv a0, a3
1080 ; RV64ZBA-LABEL: umulo.i32:
1081 ; RV64ZBA: # %bb.0: # %entry
1082 ; RV64ZBA-NEXT: zext.w a1, a1
1083 ; RV64ZBA-NEXT: zext.w a0, a0
1084 ; RV64ZBA-NEXT: mul a1, a0, a1
1085 ; RV64ZBA-NEXT: srli a0, a1, 32
1086 ; RV64ZBA-NEXT: snez a0, a0
1087 ; RV64ZBA-NEXT: sw a1, 0(a2)
1090 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
1091 %val = extractvalue {i32, i1} %t, 0
1092 %obit = extractvalue {i32, i1} %t, 1
1093 store i32 %val, i32* %res
1097 define zeroext i1 @umulo2.i32(i32 %v1, i32* %res) {
1098 ; RV32-LABEL: umulo2.i32:
1099 ; RV32: # %bb.0: # %entry
1100 ; RV32-NEXT: addi a3, zero, 13
1101 ; RV32-NEXT: mulhu a2, a0, a3
1102 ; RV32-NEXT: snez a2, a2
1103 ; RV32-NEXT: mul a0, a0, a3
1104 ; RV32-NEXT: sw a0, 0(a1)
1105 ; RV32-NEXT: mv a0, a2
1108 ; RV64-LABEL: umulo2.i32:
1109 ; RV64: # %bb.0: # %entry
1110 ; RV64-NEXT: slli a0, a0, 32
1111 ; RV64-NEXT: srli a0, a0, 32
1112 ; RV64-NEXT: addi a2, zero, 13
1113 ; RV64-NEXT: mul a2, a0, a2
1114 ; RV64-NEXT: srli a0, a2, 32
1115 ; RV64-NEXT: snez a0, a0
1116 ; RV64-NEXT: sw a2, 0(a1)
1119 ; RV32ZBA-LABEL: umulo2.i32:
1120 ; RV32ZBA: # %bb.0: # %entry
1121 ; RV32ZBA-NEXT: addi a3, zero, 13
1122 ; RV32ZBA-NEXT: mulhu a2, a0, a3
1123 ; RV32ZBA-NEXT: snez a2, a2
1124 ; RV32ZBA-NEXT: mul a0, a0, a3
1125 ; RV32ZBA-NEXT: sw a0, 0(a1)
1126 ; RV32ZBA-NEXT: mv a0, a2
1129 ; RV64ZBA-LABEL: umulo2.i32:
1130 ; RV64ZBA: # %bb.0: # %entry
1131 ; RV64ZBA-NEXT: zext.w a0, a0
1132 ; RV64ZBA-NEXT: sh1add a2, a0, a0
1133 ; RV64ZBA-NEXT: sh2add a2, a2, a0
1134 ; RV64ZBA-NEXT: srli a0, a2, 32
1135 ; RV64ZBA-NEXT: snez a0, a0
1136 ; RV64ZBA-NEXT: sw a2, 0(a1)
1139 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 13)
1140 %val = extractvalue {i32, i1} %t, 0
1141 %obit = extractvalue {i32, i1} %t, 1
1142 store i32 %val, i32* %res
1146 ; Similar to umulo.i32, but storing the overflow and returning the result.
1147 define signext i32 @umulo3.i32(i32 signext %0, i32 signext %1, i32* %2) {
1148 ; RV32-LABEL: umulo3.i32:
1150 ; RV32-NEXT: mul a3, a0, a1
1151 ; RV32-NEXT: mulhu a0, a0, a1
1152 ; RV32-NEXT: snez a0, a0
1153 ; RV32-NEXT: sw a0, 0(a2)
1154 ; RV32-NEXT: mv a0, a3
1157 ; RV64-LABEL: umulo3.i32:
1159 ; RV64-NEXT: slli a1, a1, 32
1160 ; RV64-NEXT: slli a0, a0, 32
1161 ; RV64-NEXT: mulhu a0, a0, a1
1162 ; RV64-NEXT: srli a1, a0, 32
1163 ; RV64-NEXT: snez a1, a1
1164 ; RV64-NEXT: sext.w a0, a0
1165 ; RV64-NEXT: sw a1, 0(a2)
1168 ; RV32ZBA-LABEL: umulo3.i32:
1170 ; RV32ZBA-NEXT: mul a3, a0, a1
1171 ; RV32ZBA-NEXT: mulhu a0, a0, a1
1172 ; RV32ZBA-NEXT: snez a0, a0
1173 ; RV32ZBA-NEXT: sw a0, 0(a2)
1174 ; RV32ZBA-NEXT: mv a0, a3
1177 ; RV64ZBA-LABEL: umulo3.i32:
1179 ; RV64ZBA-NEXT: zext.w a1, a1
1180 ; RV64ZBA-NEXT: zext.w a0, a0
1181 ; RV64ZBA-NEXT: mul a3, a0, a1
1182 ; RV64ZBA-NEXT: srli a3, a3, 32
1183 ; RV64ZBA-NEXT: snez a3, a3
1184 ; RV64ZBA-NEXT: mulw a0, a0, a1
1185 ; RV64ZBA-NEXT: sw a3, 0(a2)
1187 %4 = tail call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %0, i32 %1)
1188 %5 = extractvalue { i32, i1 } %4, 1
1189 %6 = extractvalue { i32, i1 } %4, 0
1190 %7 = zext i1 %5 to i32
1191 store i32 %7, i32* %2, align 4
1195 define zeroext i1 @umulo.i64(i64 %v1, i64 %v2, i64* %res) {
1196 ; RV32-LABEL: umulo.i64:
1197 ; RV32: # %bb.0: # %entry
1198 ; RV32-NEXT: mul a6, a3, a0
1199 ; RV32-NEXT: mul a5, a1, a2
1200 ; RV32-NEXT: add a6, a5, a6
1201 ; RV32-NEXT: mulhu a5, a0, a2
1202 ; RV32-NEXT: add a6, a5, a6
1203 ; RV32-NEXT: sltu a7, a6, a5
1204 ; RV32-NEXT: snez t0, a3
1205 ; RV32-NEXT: snez a5, a1
1206 ; RV32-NEXT: and a5, a5, t0
1207 ; RV32-NEXT: mulhu a1, a1, a2
1208 ; RV32-NEXT: snez a1, a1
1209 ; RV32-NEXT: or a1, a5, a1
1210 ; RV32-NEXT: mulhu a3, a3, a0
1211 ; RV32-NEXT: snez a3, a3
1212 ; RV32-NEXT: or a1, a1, a3
1213 ; RV32-NEXT: or a1, a1, a7
1214 ; RV32-NEXT: mul a0, a0, a2
1215 ; RV32-NEXT: sw a0, 0(a4)
1216 ; RV32-NEXT: sw a6, 4(a4)
1217 ; RV32-NEXT: mv a0, a1
1220 ; RV64-LABEL: umulo.i64:
1221 ; RV64: # %bb.0: # %entry
1222 ; RV64-NEXT: mulhu a3, a0, a1
1223 ; RV64-NEXT: snez a3, a3
1224 ; RV64-NEXT: mul a0, a0, a1
1225 ; RV64-NEXT: sd a0, 0(a2)
1226 ; RV64-NEXT: mv a0, a3
1229 ; RV32ZBA-LABEL: umulo.i64:
1230 ; RV32ZBA: # %bb.0: # %entry
1231 ; RV32ZBA-NEXT: mul a6, a3, a0
1232 ; RV32ZBA-NEXT: mul a5, a1, a2
1233 ; RV32ZBA-NEXT: add a6, a5, a6
1234 ; RV32ZBA-NEXT: mulhu a5, a0, a2
1235 ; RV32ZBA-NEXT: add a6, a5, a6
1236 ; RV32ZBA-NEXT: sltu a7, a6, a5
1237 ; RV32ZBA-NEXT: snez t0, a3
1238 ; RV32ZBA-NEXT: snez a5, a1
1239 ; RV32ZBA-NEXT: and a5, a5, t0
1240 ; RV32ZBA-NEXT: mulhu a1, a1, a2
1241 ; RV32ZBA-NEXT: snez a1, a1
1242 ; RV32ZBA-NEXT: or a1, a5, a1
1243 ; RV32ZBA-NEXT: mulhu a3, a3, a0
1244 ; RV32ZBA-NEXT: snez a3, a3
1245 ; RV32ZBA-NEXT: or a1, a1, a3
1246 ; RV32ZBA-NEXT: or a1, a1, a7
1247 ; RV32ZBA-NEXT: mul a0, a0, a2
1248 ; RV32ZBA-NEXT: sw a0, 0(a4)
1249 ; RV32ZBA-NEXT: sw a6, 4(a4)
1250 ; RV32ZBA-NEXT: mv a0, a1
1253 ; RV64ZBA-LABEL: umulo.i64:
1254 ; RV64ZBA: # %bb.0: # %entry
1255 ; RV64ZBA-NEXT: mulhu a3, a0, a1
1256 ; RV64ZBA-NEXT: snez a3, a3
1257 ; RV64ZBA-NEXT: mul a0, a0, a1
1258 ; RV64ZBA-NEXT: sd a0, 0(a2)
1259 ; RV64ZBA-NEXT: mv a0, a3
1262 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
1263 %val = extractvalue {i64, i1} %t, 0
1264 %obit = extractvalue {i64, i1} %t, 1
1265 store i64 %val, i64* %res
1269 define zeroext i1 @umulo2.i64(i64 %v1, i64* %res) {
1270 ; RV32-LABEL: umulo2.i64:
1271 ; RV32: # %bb.0: # %entry
1272 ; RV32-NEXT: addi a3, zero, 13
1273 ; RV32-NEXT: mul a4, a1, a3
1274 ; RV32-NEXT: mulhu a5, a0, a3
1275 ; RV32-NEXT: add a4, a5, a4
1276 ; RV32-NEXT: sltu a5, a4, a5
1277 ; RV32-NEXT: mulhu a1, a1, a3
1278 ; RV32-NEXT: snez a1, a1
1279 ; RV32-NEXT: or a1, a1, a5
1280 ; RV32-NEXT: mul a0, a0, a3
1281 ; RV32-NEXT: sw a0, 0(a2)
1282 ; RV32-NEXT: sw a4, 4(a2)
1283 ; RV32-NEXT: mv a0, a1
1286 ; RV64-LABEL: umulo2.i64:
1287 ; RV64: # %bb.0: # %entry
1288 ; RV64-NEXT: addi a3, zero, 13
1289 ; RV64-NEXT: mulhu a2, a0, a3
1290 ; RV64-NEXT: snez a2, a2
1291 ; RV64-NEXT: mul a0, a0, a3
1292 ; RV64-NEXT: sd a0, 0(a1)
1293 ; RV64-NEXT: mv a0, a2
1296 ; RV32ZBA-LABEL: umulo2.i64:
1297 ; RV32ZBA: # %bb.0: # %entry
1298 ; RV32ZBA-NEXT: addi a3, zero, 13
1299 ; RV32ZBA-NEXT: mul a4, a1, a3
1300 ; RV32ZBA-NEXT: mulhu a5, a0, a3
1301 ; RV32ZBA-NEXT: add a4, a5, a4
1302 ; RV32ZBA-NEXT: sltu a5, a4, a5
1303 ; RV32ZBA-NEXT: mulhu a1, a1, a3
1304 ; RV32ZBA-NEXT: snez a1, a1
1305 ; RV32ZBA-NEXT: or a1, a1, a5
1306 ; RV32ZBA-NEXT: mul a0, a0, a3
1307 ; RV32ZBA-NEXT: sw a0, 0(a2)
1308 ; RV32ZBA-NEXT: sw a4, 4(a2)
1309 ; RV32ZBA-NEXT: mv a0, a1
1312 ; RV64ZBA-LABEL: umulo2.i64:
1313 ; RV64ZBA: # %bb.0: # %entry
1314 ; RV64ZBA-NEXT: addi a3, zero, 13
1315 ; RV64ZBA-NEXT: mulhu a2, a0, a3
1316 ; RV64ZBA-NEXT: snez a2, a2
1317 ; RV64ZBA-NEXT: mul a0, a0, a3
1318 ; RV64ZBA-NEXT: sd a0, 0(a1)
1319 ; RV64ZBA-NEXT: mv a0, a2
1322 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 13)
1323 %val = extractvalue {i64, i1} %t, 0
1324 %obit = extractvalue {i64, i1} %t, 1
1325 store i64 %val, i64* %res
1331 ; Check the use of the overflow bit in combination with a select instruction.
1333 define i32 @saddo.select.i32(i32 %v1, i32 %v2) {
1334 ; RV32-LABEL: saddo.select.i32:
1335 ; RV32: # %bb.0: # %entry
1336 ; RV32-NEXT: add a2, a0, a1
1337 ; RV32-NEXT: slt a2, a2, a0
1338 ; RV32-NEXT: slti a3, a1, 0
1339 ; RV32-NEXT: bne a3, a2, .LBB26_2
1340 ; RV32-NEXT: # %bb.1: # %entry
1341 ; RV32-NEXT: mv a0, a1
1342 ; RV32-NEXT: .LBB26_2: # %entry
1345 ; RV64-LABEL: saddo.select.i32:
1346 ; RV64: # %bb.0: # %entry
1347 ; RV64-NEXT: sext.w a2, a1
1348 ; RV64-NEXT: sext.w a3, a0
1349 ; RV64-NEXT: add a4, a3, a2
1350 ; RV64-NEXT: addw a2, a3, a2
1351 ; RV64-NEXT: bne a2, a4, .LBB26_2
1352 ; RV64-NEXT: # %bb.1: # %entry
1353 ; RV64-NEXT: mv a0, a1
1354 ; RV64-NEXT: .LBB26_2: # %entry
1357 ; RV32ZBA-LABEL: saddo.select.i32:
1358 ; RV32ZBA: # %bb.0: # %entry
1359 ; RV32ZBA-NEXT: add a2, a0, a1
1360 ; RV32ZBA-NEXT: slt a2, a2, a0
1361 ; RV32ZBA-NEXT: slti a3, a1, 0
1362 ; RV32ZBA-NEXT: bne a3, a2, .LBB26_2
1363 ; RV32ZBA-NEXT: # %bb.1: # %entry
1364 ; RV32ZBA-NEXT: mv a0, a1
1365 ; RV32ZBA-NEXT: .LBB26_2: # %entry
1368 ; RV64ZBA-LABEL: saddo.select.i32:
1369 ; RV64ZBA: # %bb.0: # %entry
1370 ; RV64ZBA-NEXT: sext.w a2, a1
1371 ; RV64ZBA-NEXT: sext.w a3, a0
1372 ; RV64ZBA-NEXT: add a4, a3, a2
1373 ; RV64ZBA-NEXT: addw a2, a3, a2
1374 ; RV64ZBA-NEXT: bne a2, a4, .LBB26_2
1375 ; RV64ZBA-NEXT: # %bb.1: # %entry
1376 ; RV64ZBA-NEXT: mv a0, a1
1377 ; RV64ZBA-NEXT: .LBB26_2: # %entry
1380 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2)
1381 %obit = extractvalue {i32, i1} %t, 1
1382 %ret = select i1 %obit, i32 %v1, i32 %v2
1386 define i1 @saddo.not.i32(i32 %v1, i32 %v2) {
1387 ; RV32-LABEL: saddo.not.i32:
1388 ; RV32: # %bb.0: # %entry
1389 ; RV32-NEXT: add a2, a0, a1
1390 ; RV32-NEXT: slt a0, a2, a0
1391 ; RV32-NEXT: slti a1, a1, 0
1392 ; RV32-NEXT: xor a0, a1, a0
1393 ; RV32-NEXT: xori a0, a0, 1
1396 ; RV64-LABEL: saddo.not.i32:
1397 ; RV64: # %bb.0: # %entry
1398 ; RV64-NEXT: sext.w a1, a1
1399 ; RV64-NEXT: sext.w a0, a0
1400 ; RV64-NEXT: add a2, a0, a1
1401 ; RV64-NEXT: addw a0, a0, a1
1402 ; RV64-NEXT: xor a0, a0, a2
1403 ; RV64-NEXT: seqz a0, a0
1406 ; RV32ZBA-LABEL: saddo.not.i32:
1407 ; RV32ZBA: # %bb.0: # %entry
1408 ; RV32ZBA-NEXT: add a2, a0, a1
1409 ; RV32ZBA-NEXT: slt a0, a2, a0
1410 ; RV32ZBA-NEXT: slti a1, a1, 0
1411 ; RV32ZBA-NEXT: xor a0, a1, a0
1412 ; RV32ZBA-NEXT: xori a0, a0, 1
1415 ; RV64ZBA-LABEL: saddo.not.i32:
1416 ; RV64ZBA: # %bb.0: # %entry
1417 ; RV64ZBA-NEXT: sext.w a1, a1
1418 ; RV64ZBA-NEXT: sext.w a0, a0
1419 ; RV64ZBA-NEXT: add a2, a0, a1
1420 ; RV64ZBA-NEXT: addw a0, a0, a1
1421 ; RV64ZBA-NEXT: xor a0, a0, a2
1422 ; RV64ZBA-NEXT: seqz a0, a0
1425 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2)
1426 %obit = extractvalue {i32, i1} %t, 1
1427 %ret = xor i1 %obit, true
1431 define i64 @saddo.select.i64(i64 %v1, i64 %v2) {
1432 ; RV32-LABEL: saddo.select.i64:
1433 ; RV32: # %bb.0: # %entry
1434 ; RV32-NEXT: add a4, a1, a3
1435 ; RV32-NEXT: add a5, a0, a2
1436 ; RV32-NEXT: sltu a5, a5, a0
1437 ; RV32-NEXT: add a4, a4, a5
1438 ; RV32-NEXT: xor a4, a1, a4
1439 ; RV32-NEXT: xor a5, a1, a3
1440 ; RV32-NEXT: not a5, a5
1441 ; RV32-NEXT: and a4, a5, a4
1442 ; RV32-NEXT: bltz a4, .LBB28_2
1443 ; RV32-NEXT: # %bb.1: # %entry
1444 ; RV32-NEXT: mv a0, a2
1445 ; RV32-NEXT: mv a1, a3
1446 ; RV32-NEXT: .LBB28_2: # %entry
1449 ; RV64-LABEL: saddo.select.i64:
1450 ; RV64: # %bb.0: # %entry
1451 ; RV64-NEXT: add a2, a0, a1
1452 ; RV64-NEXT: slt a2, a2, a0
1453 ; RV64-NEXT: slti a3, a1, 0
1454 ; RV64-NEXT: bne a3, a2, .LBB28_2
1455 ; RV64-NEXT: # %bb.1: # %entry
1456 ; RV64-NEXT: mv a0, a1
1457 ; RV64-NEXT: .LBB28_2: # %entry
1460 ; RV32ZBA-LABEL: saddo.select.i64:
1461 ; RV32ZBA: # %bb.0: # %entry
1462 ; RV32ZBA-NEXT: add a4, a1, a3
1463 ; RV32ZBA-NEXT: add a5, a0, a2
1464 ; RV32ZBA-NEXT: sltu a5, a5, a0
1465 ; RV32ZBA-NEXT: add a4, a4, a5
1466 ; RV32ZBA-NEXT: xor a4, a1, a4
1467 ; RV32ZBA-NEXT: xor a5, a1, a3
1468 ; RV32ZBA-NEXT: not a5, a5
1469 ; RV32ZBA-NEXT: and a4, a5, a4
1470 ; RV32ZBA-NEXT: bltz a4, .LBB28_2
1471 ; RV32ZBA-NEXT: # %bb.1: # %entry
1472 ; RV32ZBA-NEXT: mv a0, a2
1473 ; RV32ZBA-NEXT: mv a1, a3
1474 ; RV32ZBA-NEXT: .LBB28_2: # %entry
1477 ; RV64ZBA-LABEL: saddo.select.i64:
1478 ; RV64ZBA: # %bb.0: # %entry
1479 ; RV64ZBA-NEXT: add a2, a0, a1
1480 ; RV64ZBA-NEXT: slt a2, a2, a0
1481 ; RV64ZBA-NEXT: slti a3, a1, 0
1482 ; RV64ZBA-NEXT: bne a3, a2, .LBB28_2
1483 ; RV64ZBA-NEXT: # %bb.1: # %entry
1484 ; RV64ZBA-NEXT: mv a0, a1
1485 ; RV64ZBA-NEXT: .LBB28_2: # %entry
1488 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2)
1489 %obit = extractvalue {i64, i1} %t, 1
1490 %ret = select i1 %obit, i64 %v1, i64 %v2
1494 define i1 @saddo.not.i64(i64 %v1, i64 %v2) {
1495 ; RV32-LABEL: saddo.not.i64:
1496 ; RV32: # %bb.0: # %entry
1497 ; RV32-NEXT: add a4, a1, a3
1498 ; RV32-NEXT: add a2, a0, a2
1499 ; RV32-NEXT: sltu a0, a2, a0
1500 ; RV32-NEXT: add a0, a4, a0
1501 ; RV32-NEXT: xor a0, a1, a0
1502 ; RV32-NEXT: xor a1, a1, a3
1503 ; RV32-NEXT: not a1, a1
1504 ; RV32-NEXT: and a0, a1, a0
1505 ; RV32-NEXT: addi a1, zero, -1
1506 ; RV32-NEXT: slt a0, a1, a0
1509 ; RV64-LABEL: saddo.not.i64:
1510 ; RV64: # %bb.0: # %entry
1511 ; RV64-NEXT: add a2, a0, a1
1512 ; RV64-NEXT: slt a0, a2, a0
1513 ; RV64-NEXT: slti a1, a1, 0
1514 ; RV64-NEXT: xor a0, a1, a0
1515 ; RV64-NEXT: xori a0, a0, 1
1518 ; RV32ZBA-LABEL: saddo.not.i64:
1519 ; RV32ZBA: # %bb.0: # %entry
1520 ; RV32ZBA-NEXT: add a4, a1, a3
1521 ; RV32ZBA-NEXT: add a2, a0, a2
1522 ; RV32ZBA-NEXT: sltu a0, a2, a0
1523 ; RV32ZBA-NEXT: add a0, a4, a0
1524 ; RV32ZBA-NEXT: xor a0, a1, a0
1525 ; RV32ZBA-NEXT: xor a1, a1, a3
1526 ; RV32ZBA-NEXT: not a1, a1
1527 ; RV32ZBA-NEXT: and a0, a1, a0
1528 ; RV32ZBA-NEXT: addi a1, zero, -1
1529 ; RV32ZBA-NEXT: slt a0, a1, a0
1532 ; RV64ZBA-LABEL: saddo.not.i64:
1533 ; RV64ZBA: # %bb.0: # %entry
1534 ; RV64ZBA-NEXT: add a2, a0, a1
1535 ; RV64ZBA-NEXT: slt a0, a2, a0
1536 ; RV64ZBA-NEXT: slti a1, a1, 0
1537 ; RV64ZBA-NEXT: xor a0, a1, a0
1538 ; RV64ZBA-NEXT: xori a0, a0, 1
1541 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2)
1542 %obit = extractvalue {i64, i1} %t, 1
1543 %ret = xor i1 %obit, true
1547 define i32 @uaddo.select.i32(i32 %v1, i32 %v2) {
1548 ; RV32-LABEL: uaddo.select.i32:
1549 ; RV32: # %bb.0: # %entry
1550 ; RV32-NEXT: add a2, a0, a1
1551 ; RV32-NEXT: bltu a2, a0, .LBB30_2
1552 ; RV32-NEXT: # %bb.1: # %entry
1553 ; RV32-NEXT: mv a0, a1
1554 ; RV32-NEXT: .LBB30_2: # %entry
1557 ; RV64-LABEL: uaddo.select.i32:
1558 ; RV64: # %bb.0: # %entry
1559 ; RV64-NEXT: addw a2, a0, a1
1560 ; RV64-NEXT: sext.w a3, a0
1561 ; RV64-NEXT: bltu a2, a3, .LBB30_2
1562 ; RV64-NEXT: # %bb.1: # %entry
1563 ; RV64-NEXT: mv a0, a1
1564 ; RV64-NEXT: .LBB30_2: # %entry
1567 ; RV32ZBA-LABEL: uaddo.select.i32:
1568 ; RV32ZBA: # %bb.0: # %entry
1569 ; RV32ZBA-NEXT: add a2, a0, a1
1570 ; RV32ZBA-NEXT: bltu a2, a0, .LBB30_2
1571 ; RV32ZBA-NEXT: # %bb.1: # %entry
1572 ; RV32ZBA-NEXT: mv a0, a1
1573 ; RV32ZBA-NEXT: .LBB30_2: # %entry
1576 ; RV64ZBA-LABEL: uaddo.select.i32:
1577 ; RV64ZBA: # %bb.0: # %entry
1578 ; RV64ZBA-NEXT: addw a2, a0, a1
1579 ; RV64ZBA-NEXT: sext.w a3, a0
1580 ; RV64ZBA-NEXT: bltu a2, a3, .LBB30_2
1581 ; RV64ZBA-NEXT: # %bb.1: # %entry
1582 ; RV64ZBA-NEXT: mv a0, a1
1583 ; RV64ZBA-NEXT: .LBB30_2: # %entry
1586 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)
1587 %obit = extractvalue {i32, i1} %t, 1
1588 %ret = select i1 %obit, i32 %v1, i32 %v2
1592 define i1 @uaddo.not.i32(i32 %v1, i32 %v2) {
1593 ; RV32-LABEL: uaddo.not.i32:
1594 ; RV32: # %bb.0: # %entry
1595 ; RV32-NEXT: add a1, a0, a1
1596 ; RV32-NEXT: sltu a0, a1, a0
1597 ; RV32-NEXT: xori a0, a0, 1
1600 ; RV64-LABEL: uaddo.not.i32:
1601 ; RV64: # %bb.0: # %entry
1602 ; RV64-NEXT: addw a1, a0, a1
1603 ; RV64-NEXT: sext.w a0, a0
1604 ; RV64-NEXT: sltu a0, a1, a0
1605 ; RV64-NEXT: xori a0, a0, 1
1608 ; RV32ZBA-LABEL: uaddo.not.i32:
1609 ; RV32ZBA: # %bb.0: # %entry
1610 ; RV32ZBA-NEXT: add a1, a0, a1
1611 ; RV32ZBA-NEXT: sltu a0, a1, a0
1612 ; RV32ZBA-NEXT: xori a0, a0, 1
1615 ; RV64ZBA-LABEL: uaddo.not.i32:
1616 ; RV64ZBA: # %bb.0: # %entry
1617 ; RV64ZBA-NEXT: addw a1, a0, a1
1618 ; RV64ZBA-NEXT: sext.w a0, a0
1619 ; RV64ZBA-NEXT: sltu a0, a1, a0
1620 ; RV64ZBA-NEXT: xori a0, a0, 1
1623 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)
1624 %obit = extractvalue {i32, i1} %t, 1
1625 %ret = xor i1 %obit, true
1629 define i64 @uaddo.select.i64(i64 %v1, i64 %v2) {
1630 ; RV32-LABEL: uaddo.select.i64:
1631 ; RV32: # %bb.0: # %entry
1632 ; RV32-NEXT: add a5, a1, a3
1633 ; RV32-NEXT: add a4, a0, a2
1634 ; RV32-NEXT: sltu a4, a4, a0
1635 ; RV32-NEXT: add a5, a5, a4
1636 ; RV32-NEXT: bne a5, a1, .LBB32_3
1637 ; RV32-NEXT: # %bb.1: # %entry
1638 ; RV32-NEXT: beqz a4, .LBB32_4
1639 ; RV32-NEXT: .LBB32_2: # %entry
1641 ; RV32-NEXT: .LBB32_3: # %entry
1642 ; RV32-NEXT: sltu a4, a5, a1
1643 ; RV32-NEXT: bnez a4, .LBB32_2
1644 ; RV32-NEXT: .LBB32_4: # %entry
1645 ; RV32-NEXT: mv a0, a2
1646 ; RV32-NEXT: mv a1, a3
1649 ; RV64-LABEL: uaddo.select.i64:
1650 ; RV64: # %bb.0: # %entry
1651 ; RV64-NEXT: add a2, a0, a1
1652 ; RV64-NEXT: bltu a2, a0, .LBB32_2
1653 ; RV64-NEXT: # %bb.1: # %entry
1654 ; RV64-NEXT: mv a0, a1
1655 ; RV64-NEXT: .LBB32_2: # %entry
1658 ; RV32ZBA-LABEL: uaddo.select.i64:
1659 ; RV32ZBA: # %bb.0: # %entry
1660 ; RV32ZBA-NEXT: add a5, a1, a3
1661 ; RV32ZBA-NEXT: add a4, a0, a2
1662 ; RV32ZBA-NEXT: sltu a4, a4, a0
1663 ; RV32ZBA-NEXT: add a5, a5, a4
1664 ; RV32ZBA-NEXT: bne a5, a1, .LBB32_3
1665 ; RV32ZBA-NEXT: # %bb.1: # %entry
1666 ; RV32ZBA-NEXT: beqz a4, .LBB32_4
1667 ; RV32ZBA-NEXT: .LBB32_2: # %entry
1669 ; RV32ZBA-NEXT: .LBB32_3: # %entry
1670 ; RV32ZBA-NEXT: sltu a4, a5, a1
1671 ; RV32ZBA-NEXT: bnez a4, .LBB32_2
1672 ; RV32ZBA-NEXT: .LBB32_4: # %entry
1673 ; RV32ZBA-NEXT: mv a0, a2
1674 ; RV32ZBA-NEXT: mv a1, a3
1677 ; RV64ZBA-LABEL: uaddo.select.i64:
1678 ; RV64ZBA: # %bb.0: # %entry
1679 ; RV64ZBA-NEXT: add a2, a0, a1
1680 ; RV64ZBA-NEXT: bltu a2, a0, .LBB32_2
1681 ; RV64ZBA-NEXT: # %bb.1: # %entry
1682 ; RV64ZBA-NEXT: mv a0, a1
1683 ; RV64ZBA-NEXT: .LBB32_2: # %entry
1686 %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2)
1687 %obit = extractvalue {i64, i1} %t, 1
1688 %ret = select i1 %obit, i64 %v1, i64 %v2
1692 define i1 @uaddo.not.i64(i64 %v1, i64 %v2) {
1693 ; RV32-LABEL: uaddo.not.i64:
1694 ; RV32: # %bb.0: # %entry
1695 ; RV32-NEXT: add a3, a1, a3
1696 ; RV32-NEXT: add a2, a0, a2
1697 ; RV32-NEXT: sltu a0, a2, a0
1698 ; RV32-NEXT: add a2, a3, a0
1699 ; RV32-NEXT: beq a2, a1, .LBB33_2
1700 ; RV32-NEXT: # %bb.1: # %entry
1701 ; RV32-NEXT: sltu a0, a2, a1
1702 ; RV32-NEXT: .LBB33_2: # %entry
1703 ; RV32-NEXT: xori a0, a0, 1
1706 ; RV64-LABEL: uaddo.not.i64:
1707 ; RV64: # %bb.0: # %entry
1708 ; RV64-NEXT: add a1, a0, a1
1709 ; RV64-NEXT: sltu a0, a1, a0
1710 ; RV64-NEXT: xori a0, a0, 1
1713 ; RV32ZBA-LABEL: uaddo.not.i64:
1714 ; RV32ZBA: # %bb.0: # %entry
1715 ; RV32ZBA-NEXT: add a3, a1, a3
1716 ; RV32ZBA-NEXT: add a2, a0, a2
1717 ; RV32ZBA-NEXT: sltu a0, a2, a0
1718 ; RV32ZBA-NEXT: add a2, a3, a0
1719 ; RV32ZBA-NEXT: beq a2, a1, .LBB33_2
1720 ; RV32ZBA-NEXT: # %bb.1: # %entry
1721 ; RV32ZBA-NEXT: sltu a0, a2, a1
1722 ; RV32ZBA-NEXT: .LBB33_2: # %entry
1723 ; RV32ZBA-NEXT: xori a0, a0, 1
1726 ; RV64ZBA-LABEL: uaddo.not.i64:
1727 ; RV64ZBA: # %bb.0: # %entry
1728 ; RV64ZBA-NEXT: add a1, a0, a1
1729 ; RV64ZBA-NEXT: sltu a0, a1, a0
1730 ; RV64ZBA-NEXT: xori a0, a0, 1
1733 %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2)
1734 %obit = extractvalue {i64, i1} %t, 1
1735 %ret = xor i1 %obit, true
1739 define i32 @ssubo.select.i32(i32 %v1, i32 %v2) {
1740 ; RV32-LABEL: ssubo.select.i32:
1741 ; RV32: # %bb.0: # %entry
1742 ; RV32-NEXT: sgtz a2, a1
1743 ; RV32-NEXT: sub a3, a0, a1
1744 ; RV32-NEXT: slt a3, a3, a0
1745 ; RV32-NEXT: bne a2, a3, .LBB34_2
1746 ; RV32-NEXT: # %bb.1: # %entry
1747 ; RV32-NEXT: mv a0, a1
1748 ; RV32-NEXT: .LBB34_2: # %entry
1751 ; RV64-LABEL: ssubo.select.i32:
1752 ; RV64: # %bb.0: # %entry
1753 ; RV64-NEXT: sext.w a2, a1
1754 ; RV64-NEXT: sext.w a3, a0
1755 ; RV64-NEXT: sub a4, a3, a2
1756 ; RV64-NEXT: subw a2, a3, a2
1757 ; RV64-NEXT: bne a2, a4, .LBB34_2
1758 ; RV64-NEXT: # %bb.1: # %entry
1759 ; RV64-NEXT: mv a0, a1
1760 ; RV64-NEXT: .LBB34_2: # %entry
1763 ; RV32ZBA-LABEL: ssubo.select.i32:
1764 ; RV32ZBA: # %bb.0: # %entry
1765 ; RV32ZBA-NEXT: sgtz a2, a1
1766 ; RV32ZBA-NEXT: sub a3, a0, a1
1767 ; RV32ZBA-NEXT: slt a3, a3, a0
1768 ; RV32ZBA-NEXT: bne a2, a3, .LBB34_2
1769 ; RV32ZBA-NEXT: # %bb.1: # %entry
1770 ; RV32ZBA-NEXT: mv a0, a1
1771 ; RV32ZBA-NEXT: .LBB34_2: # %entry
1774 ; RV64ZBA-LABEL: ssubo.select.i32:
1775 ; RV64ZBA: # %bb.0: # %entry
1776 ; RV64ZBA-NEXT: sext.w a2, a1
1777 ; RV64ZBA-NEXT: sext.w a3, a0
1778 ; RV64ZBA-NEXT: sub a4, a3, a2
1779 ; RV64ZBA-NEXT: subw a2, a3, a2
1780 ; RV64ZBA-NEXT: bne a2, a4, .LBB34_2
1781 ; RV64ZBA-NEXT: # %bb.1: # %entry
1782 ; RV64ZBA-NEXT: mv a0, a1
1783 ; RV64ZBA-NEXT: .LBB34_2: # %entry
1786 %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2)
1787 %obit = extractvalue {i32, i1} %t, 1
1788 %ret = select i1 %obit, i32 %v1, i32 %v2
1792 define i1 @ssubo.not.i32(i32 %v1, i32 %v2) {
1793 ; RV32-LABEL: ssubo.not.i32:
1794 ; RV32: # %bb.0: # %entry
1795 ; RV32-NEXT: sgtz a2, a1
1796 ; RV32-NEXT: sub a1, a0, a1
1797 ; RV32-NEXT: slt a0, a1, a0
1798 ; RV32-NEXT: xor a0, a2, a0
1799 ; RV32-NEXT: xori a0, a0, 1
1802 ; RV64-LABEL: ssubo.not.i32:
1803 ; RV64: # %bb.0: # %entry
1804 ; RV64-NEXT: sext.w a1, a1
1805 ; RV64-NEXT: sext.w a0, a0
1806 ; RV64-NEXT: sub a2, a0, a1
1807 ; RV64-NEXT: subw a0, a0, a1
1808 ; RV64-NEXT: xor a0, a0, a2
1809 ; RV64-NEXT: seqz a0, a0
1812 ; RV32ZBA-LABEL: ssubo.not.i32:
1813 ; RV32ZBA: # %bb.0: # %entry
1814 ; RV32ZBA-NEXT: sgtz a2, a1
1815 ; RV32ZBA-NEXT: sub a1, a0, a1
1816 ; RV32ZBA-NEXT: slt a0, a1, a0
1817 ; RV32ZBA-NEXT: xor a0, a2, a0
1818 ; RV32ZBA-NEXT: xori a0, a0, 1
1821 ; RV64ZBA-LABEL: ssubo.not.i32:
1822 ; RV64ZBA: # %bb.0: # %entry
1823 ; RV64ZBA-NEXT: sext.w a1, a1
1824 ; RV64ZBA-NEXT: sext.w a0, a0
1825 ; RV64ZBA-NEXT: sub a2, a0, a1
1826 ; RV64ZBA-NEXT: subw a0, a0, a1
1827 ; RV64ZBA-NEXT: xor a0, a0, a2
1828 ; RV64ZBA-NEXT: seqz a0, a0
1831 %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2)
1832 %obit = extractvalue {i32, i1} %t, 1
1833 %ret = xor i1 %obit, true
1837 define i64 @ssubo.select.i64(i64 %v1, i64 %v2) {
1838 ; RV32-LABEL: ssubo.select.i64:
1839 ; RV32: # %bb.0: # %entry
1840 ; RV32-NEXT: sltu a4, a0, a2
1841 ; RV32-NEXT: sub a5, a1, a3
1842 ; RV32-NEXT: sub a4, a5, a4
1843 ; RV32-NEXT: xor a4, a1, a4
1844 ; RV32-NEXT: xor a5, a1, a3
1845 ; RV32-NEXT: and a4, a5, a4
1846 ; RV32-NEXT: bltz a4, .LBB36_2
1847 ; RV32-NEXT: # %bb.1: # %entry
1848 ; RV32-NEXT: mv a0, a2
1849 ; RV32-NEXT: mv a1, a3
1850 ; RV32-NEXT: .LBB36_2: # %entry
1853 ; RV64-LABEL: ssubo.select.i64:
1854 ; RV64: # %bb.0: # %entry
1855 ; RV64-NEXT: sgtz a2, a1
1856 ; RV64-NEXT: sub a3, a0, a1
1857 ; RV64-NEXT: slt a3, a3, a0
1858 ; RV64-NEXT: bne a2, a3, .LBB36_2
1859 ; RV64-NEXT: # %bb.1: # %entry
1860 ; RV64-NEXT: mv a0, a1
1861 ; RV64-NEXT: .LBB36_2: # %entry
1864 ; RV32ZBA-LABEL: ssubo.select.i64:
1865 ; RV32ZBA: # %bb.0: # %entry
1866 ; RV32ZBA-NEXT: sltu a4, a0, a2
1867 ; RV32ZBA-NEXT: sub a5, a1, a3
1868 ; RV32ZBA-NEXT: sub a4, a5, a4
1869 ; RV32ZBA-NEXT: xor a4, a1, a4
1870 ; RV32ZBA-NEXT: xor a5, a1, a3
1871 ; RV32ZBA-NEXT: and a4, a5, a4
1872 ; RV32ZBA-NEXT: bltz a4, .LBB36_2
1873 ; RV32ZBA-NEXT: # %bb.1: # %entry
1874 ; RV32ZBA-NEXT: mv a0, a2
1875 ; RV32ZBA-NEXT: mv a1, a3
1876 ; RV32ZBA-NEXT: .LBB36_2: # %entry
1879 ; RV64ZBA-LABEL: ssubo.select.i64:
1880 ; RV64ZBA: # %bb.0: # %entry
1881 ; RV64ZBA-NEXT: sgtz a2, a1
1882 ; RV64ZBA-NEXT: sub a3, a0, a1
1883 ; RV64ZBA-NEXT: slt a3, a3, a0
1884 ; RV64ZBA-NEXT: bne a2, a3, .LBB36_2
1885 ; RV64ZBA-NEXT: # %bb.1: # %entry
1886 ; RV64ZBA-NEXT: mv a0, a1
1887 ; RV64ZBA-NEXT: .LBB36_2: # %entry
1890 %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2)
1891 %obit = extractvalue {i64, i1} %t, 1
1892 %ret = select i1 %obit, i64 %v1, i64 %v2
1896 define i1 @ssub.not.i64(i64 %v1, i64 %v2) {
1897 ; RV32-LABEL: ssub.not.i64:
1898 ; RV32: # %bb.0: # %entry
1899 ; RV32-NEXT: sltu a0, a0, a2
1900 ; RV32-NEXT: sub a2, a1, a3
1901 ; RV32-NEXT: sub a0, a2, a0
1902 ; RV32-NEXT: xor a0, a1, a0
1903 ; RV32-NEXT: xor a1, a1, a3
1904 ; RV32-NEXT: and a0, a1, a0
1905 ; RV32-NEXT: addi a1, zero, -1
1906 ; RV32-NEXT: slt a0, a1, a0
1909 ; RV64-LABEL: ssub.not.i64:
1910 ; RV64: # %bb.0: # %entry
1911 ; RV64-NEXT: sgtz a2, a1
1912 ; RV64-NEXT: sub a1, a0, a1
1913 ; RV64-NEXT: slt a0, a1, a0
1914 ; RV64-NEXT: xor a0, a2, a0
1915 ; RV64-NEXT: xori a0, a0, 1
1918 ; RV32ZBA-LABEL: ssub.not.i64:
1919 ; RV32ZBA: # %bb.0: # %entry
1920 ; RV32ZBA-NEXT: sltu a0, a0, a2
1921 ; RV32ZBA-NEXT: sub a2, a1, a3
1922 ; RV32ZBA-NEXT: sub a0, a2, a0
1923 ; RV32ZBA-NEXT: xor a0, a1, a0
1924 ; RV32ZBA-NEXT: xor a1, a1, a3
1925 ; RV32ZBA-NEXT: and a0, a1, a0
1926 ; RV32ZBA-NEXT: addi a1, zero, -1
1927 ; RV32ZBA-NEXT: slt a0, a1, a0
1930 ; RV64ZBA-LABEL: ssub.not.i64:
1931 ; RV64ZBA: # %bb.0: # %entry
1932 ; RV64ZBA-NEXT: sgtz a2, a1
1933 ; RV64ZBA-NEXT: sub a1, a0, a1
1934 ; RV64ZBA-NEXT: slt a0, a1, a0
1935 ; RV64ZBA-NEXT: xor a0, a2, a0
1936 ; RV64ZBA-NEXT: xori a0, a0, 1
1939 %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2)
1940 %obit = extractvalue {i64, i1} %t, 1
1941 %ret = xor i1 %obit, true
1945 define i32 @usubo.select.i32(i32 %v1, i32 %v2) {
1946 ; RV32-LABEL: usubo.select.i32:
1947 ; RV32: # %bb.0: # %entry
1948 ; RV32-NEXT: sub a2, a0, a1
1949 ; RV32-NEXT: bltu a0, a2, .LBB38_2
1950 ; RV32-NEXT: # %bb.1: # %entry
1951 ; RV32-NEXT: mv a0, a1
1952 ; RV32-NEXT: .LBB38_2: # %entry
1955 ; RV64-LABEL: usubo.select.i32:
1956 ; RV64: # %bb.0: # %entry
1957 ; RV64-NEXT: subw a2, a0, a1
1958 ; RV64-NEXT: sext.w a3, a0
1959 ; RV64-NEXT: bltu a3, a2, .LBB38_2
1960 ; RV64-NEXT: # %bb.1: # %entry
1961 ; RV64-NEXT: mv a0, a1
1962 ; RV64-NEXT: .LBB38_2: # %entry
1965 ; RV32ZBA-LABEL: usubo.select.i32:
1966 ; RV32ZBA: # %bb.0: # %entry
1967 ; RV32ZBA-NEXT: sub a2, a0, a1
1968 ; RV32ZBA-NEXT: bltu a0, a2, .LBB38_2
1969 ; RV32ZBA-NEXT: # %bb.1: # %entry
1970 ; RV32ZBA-NEXT: mv a0, a1
1971 ; RV32ZBA-NEXT: .LBB38_2: # %entry
1974 ; RV64ZBA-LABEL: usubo.select.i32:
1975 ; RV64ZBA: # %bb.0: # %entry
1976 ; RV64ZBA-NEXT: subw a2, a0, a1
1977 ; RV64ZBA-NEXT: sext.w a3, a0
1978 ; RV64ZBA-NEXT: bltu a3, a2, .LBB38_2
1979 ; RV64ZBA-NEXT: # %bb.1: # %entry
1980 ; RV64ZBA-NEXT: mv a0, a1
1981 ; RV64ZBA-NEXT: .LBB38_2: # %entry
1984 %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2)
1985 %obit = extractvalue {i32, i1} %t, 1
1986 %ret = select i1 %obit, i32 %v1, i32 %v2
1990 define i1 @usubo.not.i32(i32 %v1, i32 %v2) {
1991 ; RV32-LABEL: usubo.not.i32:
1992 ; RV32: # %bb.0: # %entry
1993 ; RV32-NEXT: sub a1, a0, a1
1994 ; RV32-NEXT: sltu a0, a0, a1
1995 ; RV32-NEXT: xori a0, a0, 1
1998 ; RV64-LABEL: usubo.not.i32:
1999 ; RV64: # %bb.0: # %entry
2000 ; RV64-NEXT: subw a1, a0, a1
2001 ; RV64-NEXT: sext.w a0, a0
2002 ; RV64-NEXT: sltu a0, a0, a1
2003 ; RV64-NEXT: xori a0, a0, 1
2006 ; RV32ZBA-LABEL: usubo.not.i32:
2007 ; RV32ZBA: # %bb.0: # %entry
2008 ; RV32ZBA-NEXT: sub a1, a0, a1
2009 ; RV32ZBA-NEXT: sltu a0, a0, a1
2010 ; RV32ZBA-NEXT: xori a0, a0, 1
2013 ; RV64ZBA-LABEL: usubo.not.i32:
2014 ; RV64ZBA: # %bb.0: # %entry
2015 ; RV64ZBA-NEXT: subw a1, a0, a1
2016 ; RV64ZBA-NEXT: sext.w a0, a0
2017 ; RV64ZBA-NEXT: sltu a0, a0, a1
2018 ; RV64ZBA-NEXT: xori a0, a0, 1
2021 %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2)
2022 %obit = extractvalue {i32, i1} %t, 1
2023 %ret = xor i1 %obit, true
2027 define i64 @usubo.select.i64(i64 %v1, i64 %v2) {
2028 ; RV32-LABEL: usubo.select.i64:
2029 ; RV32: # %bb.0: # %entry
2030 ; RV32-NEXT: sltu a4, a0, a2
2031 ; RV32-NEXT: sub a5, a1, a3
2032 ; RV32-NEXT: sub a4, a5, a4
2033 ; RV32-NEXT: beq a4, a1, .LBB40_2
2034 ; RV32-NEXT: # %bb.1: # %entry
2035 ; RV32-NEXT: sltu a4, a1, a4
2036 ; RV32-NEXT: beqz a4, .LBB40_3
2037 ; RV32-NEXT: j .LBB40_4
2038 ; RV32-NEXT: .LBB40_2:
2039 ; RV32-NEXT: sub a4, a0, a2
2040 ; RV32-NEXT: sltu a4, a0, a4
2041 ; RV32-NEXT: bnez a4, .LBB40_4
2042 ; RV32-NEXT: .LBB40_3: # %entry
2043 ; RV32-NEXT: mv a0, a2
2044 ; RV32-NEXT: mv a1, a3
2045 ; RV32-NEXT: .LBB40_4: # %entry
2048 ; RV64-LABEL: usubo.select.i64:
2049 ; RV64: # %bb.0: # %entry
2050 ; RV64-NEXT: sub a2, a0, a1
2051 ; RV64-NEXT: bltu a0, a2, .LBB40_2
2052 ; RV64-NEXT: # %bb.1: # %entry
2053 ; RV64-NEXT: mv a0, a1
2054 ; RV64-NEXT: .LBB40_2: # %entry
2057 ; RV32ZBA-LABEL: usubo.select.i64:
2058 ; RV32ZBA: # %bb.0: # %entry
2059 ; RV32ZBA-NEXT: sltu a4, a0, a2
2060 ; RV32ZBA-NEXT: sub a5, a1, a3
2061 ; RV32ZBA-NEXT: sub a4, a5, a4
2062 ; RV32ZBA-NEXT: beq a4, a1, .LBB40_2
2063 ; RV32ZBA-NEXT: # %bb.1: # %entry
2064 ; RV32ZBA-NEXT: sltu a4, a1, a4
2065 ; RV32ZBA-NEXT: beqz a4, .LBB40_3
2066 ; RV32ZBA-NEXT: j .LBB40_4
2067 ; RV32ZBA-NEXT: .LBB40_2:
2068 ; RV32ZBA-NEXT: sub a4, a0, a2
2069 ; RV32ZBA-NEXT: sltu a4, a0, a4
2070 ; RV32ZBA-NEXT: bnez a4, .LBB40_4
2071 ; RV32ZBA-NEXT: .LBB40_3: # %entry
2072 ; RV32ZBA-NEXT: mv a0, a2
2073 ; RV32ZBA-NEXT: mv a1, a3
2074 ; RV32ZBA-NEXT: .LBB40_4: # %entry
2077 ; RV64ZBA-LABEL: usubo.select.i64:
2078 ; RV64ZBA: # %bb.0: # %entry
2079 ; RV64ZBA-NEXT: sub a2, a0, a1
2080 ; RV64ZBA-NEXT: bltu a0, a2, .LBB40_2
2081 ; RV64ZBA-NEXT: # %bb.1: # %entry
2082 ; RV64ZBA-NEXT: mv a0, a1
2083 ; RV64ZBA-NEXT: .LBB40_2: # %entry
2086 %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2)
2087 %obit = extractvalue {i64, i1} %t, 1
2088 %ret = select i1 %obit, i64 %v1, i64 %v2
2092 define i1 @usubo.not.i64(i64 %v1, i64 %v2) {
2093 ; RV32-LABEL: usubo.not.i64:
2094 ; RV32: # %bb.0: # %entry
2095 ; RV32-NEXT: sltu a4, a0, a2
2096 ; RV32-NEXT: sub a3, a1, a3
2097 ; RV32-NEXT: sub a3, a3, a4
2098 ; RV32-NEXT: beq a3, a1, .LBB41_2
2099 ; RV32-NEXT: # %bb.1: # %entry
2100 ; RV32-NEXT: sltu a0, a1, a3
2101 ; RV32-NEXT: xori a0, a0, 1
2103 ; RV32-NEXT: .LBB41_2:
2104 ; RV32-NEXT: sub a1, a0, a2
2105 ; RV32-NEXT: sltu a0, a0, a1
2106 ; RV32-NEXT: xori a0, a0, 1
2109 ; RV64-LABEL: usubo.not.i64:
2110 ; RV64: # %bb.0: # %entry
2111 ; RV64-NEXT: sub a1, a0, a1
2112 ; RV64-NEXT: sltu a0, a0, a1
2113 ; RV64-NEXT: xori a0, a0, 1
2116 ; RV32ZBA-LABEL: usubo.not.i64:
2117 ; RV32ZBA: # %bb.0: # %entry
2118 ; RV32ZBA-NEXT: sltu a4, a0, a2
2119 ; RV32ZBA-NEXT: sub a3, a1, a3
2120 ; RV32ZBA-NEXT: sub a3, a3, a4
2121 ; RV32ZBA-NEXT: beq a3, a1, .LBB41_2
2122 ; RV32ZBA-NEXT: # %bb.1: # %entry
2123 ; RV32ZBA-NEXT: sltu a0, a1, a3
2124 ; RV32ZBA-NEXT: xori a0, a0, 1
2126 ; RV32ZBA-NEXT: .LBB41_2:
2127 ; RV32ZBA-NEXT: sub a1, a0, a2
2128 ; RV32ZBA-NEXT: sltu a0, a0, a1
2129 ; RV32ZBA-NEXT: xori a0, a0, 1
2132 ; RV64ZBA-LABEL: usubo.not.i64:
2133 ; RV64ZBA: # %bb.0: # %entry
2134 ; RV64ZBA-NEXT: sub a1, a0, a1
2135 ; RV64ZBA-NEXT: sltu a0, a0, a1
2136 ; RV64ZBA-NEXT: xori a0, a0, 1
2139 %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2)
2140 %obit = extractvalue {i64, i1} %t, 1
2141 %ret = xor i1 %obit, true
2145 define i32 @smulo.select.i32(i32 %v1, i32 %v2) {
2146 ; RV32-LABEL: smulo.select.i32:
2147 ; RV32: # %bb.0: # %entry
2148 ; RV32-NEXT: mulh a2, a0, a1
2149 ; RV32-NEXT: mul a3, a0, a1
2150 ; RV32-NEXT: srai a3, a3, 31
2151 ; RV32-NEXT: bne a2, a3, .LBB42_2
2152 ; RV32-NEXT: # %bb.1: # %entry
2153 ; RV32-NEXT: mv a0, a1
2154 ; RV32-NEXT: .LBB42_2: # %entry
2157 ; RV64-LABEL: smulo.select.i32:
2158 ; RV64: # %bb.0: # %entry
2159 ; RV64-NEXT: sext.w a2, a1
2160 ; RV64-NEXT: sext.w a3, a0
2161 ; RV64-NEXT: mul a4, a3, a2
2162 ; RV64-NEXT: mulw a2, a3, a2
2163 ; RV64-NEXT: bne a2, a4, .LBB42_2
2164 ; RV64-NEXT: # %bb.1: # %entry
2165 ; RV64-NEXT: mv a0, a1
2166 ; RV64-NEXT: .LBB42_2: # %entry
2169 ; RV32ZBA-LABEL: smulo.select.i32:
2170 ; RV32ZBA: # %bb.0: # %entry
2171 ; RV32ZBA-NEXT: mulh a2, a0, a1
2172 ; RV32ZBA-NEXT: mul a3, a0, a1
2173 ; RV32ZBA-NEXT: srai a3, a3, 31
2174 ; RV32ZBA-NEXT: bne a2, a3, .LBB42_2
2175 ; RV32ZBA-NEXT: # %bb.1: # %entry
2176 ; RV32ZBA-NEXT: mv a0, a1
2177 ; RV32ZBA-NEXT: .LBB42_2: # %entry
2180 ; RV64ZBA-LABEL: smulo.select.i32:
2181 ; RV64ZBA: # %bb.0: # %entry
2182 ; RV64ZBA-NEXT: sext.w a2, a1
2183 ; RV64ZBA-NEXT: sext.w a3, a0
2184 ; RV64ZBA-NEXT: mul a4, a3, a2
2185 ; RV64ZBA-NEXT: mulw a2, a3, a2
2186 ; RV64ZBA-NEXT: bne a2, a4, .LBB42_2
2187 ; RV64ZBA-NEXT: # %bb.1: # %entry
2188 ; RV64ZBA-NEXT: mv a0, a1
2189 ; RV64ZBA-NEXT: .LBB42_2: # %entry
2192 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
2193 %obit = extractvalue {i32, i1} %t, 1
2194 %ret = select i1 %obit, i32 %v1, i32 %v2
2198 define i1 @smulo.not.i32(i32 %v1, i32 %v2) {
2199 ; RV32-LABEL: smulo.not.i32:
2200 ; RV32: # %bb.0: # %entry
2201 ; RV32-NEXT: mulh a2, a0, a1
2202 ; RV32-NEXT: mul a0, a0, a1
2203 ; RV32-NEXT: srai a0, a0, 31
2204 ; RV32-NEXT: xor a0, a2, a0
2205 ; RV32-NEXT: seqz a0, a0
2208 ; RV64-LABEL: smulo.not.i32:
2209 ; RV64: # %bb.0: # %entry
2210 ; RV64-NEXT: sext.w a1, a1
2211 ; RV64-NEXT: sext.w a0, a0
2212 ; RV64-NEXT: mul a2, a0, a1
2213 ; RV64-NEXT: mulw a0, a0, a1
2214 ; RV64-NEXT: xor a0, a0, a2
2215 ; RV64-NEXT: seqz a0, a0
2218 ; RV32ZBA-LABEL: smulo.not.i32:
2219 ; RV32ZBA: # %bb.0: # %entry
2220 ; RV32ZBA-NEXT: mulh a2, a0, a1
2221 ; RV32ZBA-NEXT: mul a0, a0, a1
2222 ; RV32ZBA-NEXT: srai a0, a0, 31
2223 ; RV32ZBA-NEXT: xor a0, a2, a0
2224 ; RV32ZBA-NEXT: seqz a0, a0
2227 ; RV64ZBA-LABEL: smulo.not.i32:
2228 ; RV64ZBA: # %bb.0: # %entry
2229 ; RV64ZBA-NEXT: sext.w a1, a1
2230 ; RV64ZBA-NEXT: sext.w a0, a0
2231 ; RV64ZBA-NEXT: mul a2, a0, a1
2232 ; RV64ZBA-NEXT: mulw a0, a0, a1
2233 ; RV64ZBA-NEXT: xor a0, a0, a2
2234 ; RV64ZBA-NEXT: seqz a0, a0
2237 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
2238 %obit = extractvalue {i32, i1} %t, 1
2239 %ret = xor i1 %obit, true
2243 define i64 @smulo.select.i64(i64 %v1, i64 %v2) {
2244 ; RV32-LABEL: smulo.select.i64:
2245 ; RV32: # %bb.0: # %entry
2246 ; RV32-NEXT: addi sp, sp, -32
2247 ; RV32-NEXT: .cfi_def_cfa_offset 32
2248 ; RV32-NEXT: sw ra, 28(sp) # 4-byte Folded Spill
2249 ; RV32-NEXT: sw s0, 24(sp) # 4-byte Folded Spill
2250 ; RV32-NEXT: sw s1, 20(sp) # 4-byte Folded Spill
2251 ; RV32-NEXT: sw s2, 16(sp) # 4-byte Folded Spill
2252 ; RV32-NEXT: sw s3, 12(sp) # 4-byte Folded Spill
2253 ; RV32-NEXT: .cfi_offset ra, -4
2254 ; RV32-NEXT: .cfi_offset s0, -8
2255 ; RV32-NEXT: .cfi_offset s1, -12
2256 ; RV32-NEXT: .cfi_offset s2, -16
2257 ; RV32-NEXT: .cfi_offset s3, -20
2258 ; RV32-NEXT: mv s2, a3
2259 ; RV32-NEXT: mv s3, a2
2260 ; RV32-NEXT: mv s0, a1
2261 ; RV32-NEXT: mv s1, a0
2262 ; RV32-NEXT: sw zero, 8(sp)
2263 ; RV32-NEXT: addi a4, sp, 8
2264 ; RV32-NEXT: call __mulodi4@plt
2265 ; RV32-NEXT: lw a0, 8(sp)
2266 ; RV32-NEXT: bnez a0, .LBB44_2
2267 ; RV32-NEXT: # %bb.1: # %entry
2268 ; RV32-NEXT: mv s1, s3
2269 ; RV32-NEXT: mv s0, s2
2270 ; RV32-NEXT: .LBB44_2: # %entry
2271 ; RV32-NEXT: mv a0, s1
2272 ; RV32-NEXT: mv a1, s0
2273 ; RV32-NEXT: lw s3, 12(sp) # 4-byte Folded Reload
2274 ; RV32-NEXT: lw s2, 16(sp) # 4-byte Folded Reload
2275 ; RV32-NEXT: lw s1, 20(sp) # 4-byte Folded Reload
2276 ; RV32-NEXT: lw s0, 24(sp) # 4-byte Folded Reload
2277 ; RV32-NEXT: lw ra, 28(sp) # 4-byte Folded Reload
2278 ; RV32-NEXT: addi sp, sp, 32
2281 ; RV64-LABEL: smulo.select.i64:
2282 ; RV64: # %bb.0: # %entry
2283 ; RV64-NEXT: mulh a2, a0, a1
2284 ; RV64-NEXT: mul a3, a0, a1
2285 ; RV64-NEXT: srai a3, a3, 63
2286 ; RV64-NEXT: bne a2, a3, .LBB44_2
2287 ; RV64-NEXT: # %bb.1: # %entry
2288 ; RV64-NEXT: mv a0, a1
2289 ; RV64-NEXT: .LBB44_2: # %entry
2292 ; RV32ZBA-LABEL: smulo.select.i64:
2293 ; RV32ZBA: # %bb.0: # %entry
2294 ; RV32ZBA-NEXT: addi sp, sp, -32
2295 ; RV32ZBA-NEXT: .cfi_def_cfa_offset 32
2296 ; RV32ZBA-NEXT: sw ra, 28(sp) # 4-byte Folded Spill
2297 ; RV32ZBA-NEXT: sw s0, 24(sp) # 4-byte Folded Spill
2298 ; RV32ZBA-NEXT: sw s1, 20(sp) # 4-byte Folded Spill
2299 ; RV32ZBA-NEXT: sw s2, 16(sp) # 4-byte Folded Spill
2300 ; RV32ZBA-NEXT: sw s3, 12(sp) # 4-byte Folded Spill
2301 ; RV32ZBA-NEXT: .cfi_offset ra, -4
2302 ; RV32ZBA-NEXT: .cfi_offset s0, -8
2303 ; RV32ZBA-NEXT: .cfi_offset s1, -12
2304 ; RV32ZBA-NEXT: .cfi_offset s2, -16
2305 ; RV32ZBA-NEXT: .cfi_offset s3, -20
2306 ; RV32ZBA-NEXT: mv s2, a3
2307 ; RV32ZBA-NEXT: mv s3, a2
2308 ; RV32ZBA-NEXT: mv s0, a1
2309 ; RV32ZBA-NEXT: mv s1, a0
2310 ; RV32ZBA-NEXT: sw zero, 8(sp)
2311 ; RV32ZBA-NEXT: addi a4, sp, 8
2312 ; RV32ZBA-NEXT: call __mulodi4@plt
2313 ; RV32ZBA-NEXT: lw a0, 8(sp)
2314 ; RV32ZBA-NEXT: bnez a0, .LBB44_2
2315 ; RV32ZBA-NEXT: # %bb.1: # %entry
2316 ; RV32ZBA-NEXT: mv s1, s3
2317 ; RV32ZBA-NEXT: mv s0, s2
2318 ; RV32ZBA-NEXT: .LBB44_2: # %entry
2319 ; RV32ZBA-NEXT: mv a0, s1
2320 ; RV32ZBA-NEXT: mv a1, s0
2321 ; RV32ZBA-NEXT: lw s3, 12(sp) # 4-byte Folded Reload
2322 ; RV32ZBA-NEXT: lw s2, 16(sp) # 4-byte Folded Reload
2323 ; RV32ZBA-NEXT: lw s1, 20(sp) # 4-byte Folded Reload
2324 ; RV32ZBA-NEXT: lw s0, 24(sp) # 4-byte Folded Reload
2325 ; RV32ZBA-NEXT: lw ra, 28(sp) # 4-byte Folded Reload
2326 ; RV32ZBA-NEXT: addi sp, sp, 32
2329 ; RV64ZBA-LABEL: smulo.select.i64:
2330 ; RV64ZBA: # %bb.0: # %entry
2331 ; RV64ZBA-NEXT: mulh a2, a0, a1
2332 ; RV64ZBA-NEXT: mul a3, a0, a1
2333 ; RV64ZBA-NEXT: srai a3, a3, 63
2334 ; RV64ZBA-NEXT: bne a2, a3, .LBB44_2
2335 ; RV64ZBA-NEXT: # %bb.1: # %entry
2336 ; RV64ZBA-NEXT: mv a0, a1
2337 ; RV64ZBA-NEXT: .LBB44_2: # %entry
2340 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
2341 %obit = extractvalue {i64, i1} %t, 1
2342 %ret = select i1 %obit, i64 %v1, i64 %v2
2346 define i1 @smulo.not.i64(i64 %v1, i64 %v2) {
2347 ; RV32-LABEL: smulo.not.i64:
2348 ; RV32: # %bb.0: # %entry
2349 ; RV32-NEXT: addi sp, sp, -16
2350 ; RV32-NEXT: .cfi_def_cfa_offset 16
2351 ; RV32-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
2352 ; RV32-NEXT: .cfi_offset ra, -4
2353 ; RV32-NEXT: sw zero, 8(sp)
2354 ; RV32-NEXT: addi a4, sp, 8
2355 ; RV32-NEXT: call __mulodi4@plt
2356 ; RV32-NEXT: lw a0, 8(sp)
2357 ; RV32-NEXT: seqz a0, a0
2358 ; RV32-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
2359 ; RV32-NEXT: addi sp, sp, 16
2362 ; RV64-LABEL: smulo.not.i64:
2363 ; RV64: # %bb.0: # %entry
2364 ; RV64-NEXT: mulh a2, a0, a1
2365 ; RV64-NEXT: mul a0, a0, a1
2366 ; RV64-NEXT: srai a0, a0, 63
2367 ; RV64-NEXT: xor a0, a2, a0
2368 ; RV64-NEXT: seqz a0, a0
2371 ; RV32ZBA-LABEL: smulo.not.i64:
2372 ; RV32ZBA: # %bb.0: # %entry
2373 ; RV32ZBA-NEXT: addi sp, sp, -16
2374 ; RV32ZBA-NEXT: .cfi_def_cfa_offset 16
2375 ; RV32ZBA-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
2376 ; RV32ZBA-NEXT: .cfi_offset ra, -4
2377 ; RV32ZBA-NEXT: sw zero, 8(sp)
2378 ; RV32ZBA-NEXT: addi a4, sp, 8
2379 ; RV32ZBA-NEXT: call __mulodi4@plt
2380 ; RV32ZBA-NEXT: lw a0, 8(sp)
2381 ; RV32ZBA-NEXT: seqz a0, a0
2382 ; RV32ZBA-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
2383 ; RV32ZBA-NEXT: addi sp, sp, 16
2386 ; RV64ZBA-LABEL: smulo.not.i64:
2387 ; RV64ZBA: # %bb.0: # %entry
2388 ; RV64ZBA-NEXT: mulh a2, a0, a1
2389 ; RV64ZBA-NEXT: mul a0, a0, a1
2390 ; RV64ZBA-NEXT: srai a0, a0, 63
2391 ; RV64ZBA-NEXT: xor a0, a2, a0
2392 ; RV64ZBA-NEXT: seqz a0, a0
2395 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
2396 %obit = extractvalue {i64, i1} %t, 1
2397 %ret = xor i1 %obit, true
2401 define i32 @umulo.select.i32(i32 %v1, i32 %v2) {
2402 ; RV32-LABEL: umulo.select.i32:
2403 ; RV32: # %bb.0: # %entry
2404 ; RV32-NEXT: mulhu a2, a0, a1
2405 ; RV32-NEXT: bnez a2, .LBB46_2
2406 ; RV32-NEXT: # %bb.1: # %entry
2407 ; RV32-NEXT: mv a0, a1
2408 ; RV32-NEXT: .LBB46_2: # %entry
2411 ; RV64-LABEL: umulo.select.i32:
2412 ; RV64: # %bb.0: # %entry
2413 ; RV64-NEXT: slli a2, a1, 32
2414 ; RV64-NEXT: slli a3, a0, 32
2415 ; RV64-NEXT: mulhu a2, a3, a2
2416 ; RV64-NEXT: srli a2, a2, 32
2417 ; RV64-NEXT: bnez a2, .LBB46_2
2418 ; RV64-NEXT: # %bb.1: # %entry
2419 ; RV64-NEXT: mv a0, a1
2420 ; RV64-NEXT: .LBB46_2: # %entry
2423 ; RV32ZBA-LABEL: umulo.select.i32:
2424 ; RV32ZBA: # %bb.0: # %entry
2425 ; RV32ZBA-NEXT: mulhu a2, a0, a1
2426 ; RV32ZBA-NEXT: bnez a2, .LBB46_2
2427 ; RV32ZBA-NEXT: # %bb.1: # %entry
2428 ; RV32ZBA-NEXT: mv a0, a1
2429 ; RV32ZBA-NEXT: .LBB46_2: # %entry
2432 ; RV64ZBA-LABEL: umulo.select.i32:
2433 ; RV64ZBA: # %bb.0: # %entry
2434 ; RV64ZBA-NEXT: zext.w a2, a1
2435 ; RV64ZBA-NEXT: zext.w a3, a0
2436 ; RV64ZBA-NEXT: mul a2, a3, a2
2437 ; RV64ZBA-NEXT: srli a2, a2, 32
2438 ; RV64ZBA-NEXT: bnez a2, .LBB46_2
2439 ; RV64ZBA-NEXT: # %bb.1: # %entry
2440 ; RV64ZBA-NEXT: mv a0, a1
2441 ; RV64ZBA-NEXT: .LBB46_2: # %entry
2444 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
2445 %obit = extractvalue {i32, i1} %t, 1
2446 %ret = select i1 %obit, i32 %v1, i32 %v2
2450 define i1 @umulo.not.i32(i32 %v1, i32 %v2) {
2451 ; RV32-LABEL: umulo.not.i32:
2452 ; RV32: # %bb.0: # %entry
2453 ; RV32-NEXT: mulhu a0, a0, a1
2454 ; RV32-NEXT: seqz a0, a0
2457 ; RV64-LABEL: umulo.not.i32:
2458 ; RV64: # %bb.0: # %entry
2459 ; RV64-NEXT: slli a1, a1, 32
2460 ; RV64-NEXT: slli a0, a0, 32
2461 ; RV64-NEXT: mulhu a0, a0, a1
2462 ; RV64-NEXT: srli a0, a0, 32
2463 ; RV64-NEXT: seqz a0, a0
2466 ; RV32ZBA-LABEL: umulo.not.i32:
2467 ; RV32ZBA: # %bb.0: # %entry
2468 ; RV32ZBA-NEXT: mulhu a0, a0, a1
2469 ; RV32ZBA-NEXT: seqz a0, a0
2472 ; RV64ZBA-LABEL: umulo.not.i32:
2473 ; RV64ZBA: # %bb.0: # %entry
2474 ; RV64ZBA-NEXT: zext.w a1, a1
2475 ; RV64ZBA-NEXT: zext.w a0, a0
2476 ; RV64ZBA-NEXT: mul a0, a0, a1
2477 ; RV64ZBA-NEXT: srli a0, a0, 32
2478 ; RV64ZBA-NEXT: seqz a0, a0
2481 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
2482 %obit = extractvalue {i32, i1} %t, 1
2483 %ret = xor i1 %obit, true
2487 define i64 @umulo.select.i64(i64 %v1, i64 %v2) {
2488 ; RV32-LABEL: umulo.select.i64:
2489 ; RV32: # %bb.0: # %entry
2490 ; RV32-NEXT: mul a4, a3, a0
2491 ; RV32-NEXT: mul a5, a1, a2
2492 ; RV32-NEXT: add a4, a5, a4
2493 ; RV32-NEXT: mulhu a5, a0, a2
2494 ; RV32-NEXT: add a4, a5, a4
2495 ; RV32-NEXT: sltu a6, a4, a5
2496 ; RV32-NEXT: snez a5, a3
2497 ; RV32-NEXT: snez a4, a1
2498 ; RV32-NEXT: and a4, a4, a5
2499 ; RV32-NEXT: mulhu a5, a1, a2
2500 ; RV32-NEXT: snez a5, a5
2501 ; RV32-NEXT: or a4, a4, a5
2502 ; RV32-NEXT: mulhu a5, a3, a0
2503 ; RV32-NEXT: snez a5, a5
2504 ; RV32-NEXT: or a4, a4, a5
2505 ; RV32-NEXT: or a4, a4, a6
2506 ; RV32-NEXT: bnez a4, .LBB48_2
2507 ; RV32-NEXT: # %bb.1: # %entry
2508 ; RV32-NEXT: mv a0, a2
2509 ; RV32-NEXT: mv a1, a3
2510 ; RV32-NEXT: .LBB48_2: # %entry
2513 ; RV64-LABEL: umulo.select.i64:
2514 ; RV64: # %bb.0: # %entry
2515 ; RV64-NEXT: mulhu a2, a0, a1
2516 ; RV64-NEXT: bnez a2, .LBB48_2
2517 ; RV64-NEXT: # %bb.1: # %entry
2518 ; RV64-NEXT: mv a0, a1
2519 ; RV64-NEXT: .LBB48_2: # %entry
2522 ; RV32ZBA-LABEL: umulo.select.i64:
2523 ; RV32ZBA: # %bb.0: # %entry
2524 ; RV32ZBA-NEXT: mul a4, a3, a0
2525 ; RV32ZBA-NEXT: mul a5, a1, a2
2526 ; RV32ZBA-NEXT: add a4, a5, a4
2527 ; RV32ZBA-NEXT: mulhu a5, a0, a2
2528 ; RV32ZBA-NEXT: add a4, a5, a4
2529 ; RV32ZBA-NEXT: sltu a6, a4, a5
2530 ; RV32ZBA-NEXT: snez a5, a3
2531 ; RV32ZBA-NEXT: snez a4, a1
2532 ; RV32ZBA-NEXT: and a4, a4, a5
2533 ; RV32ZBA-NEXT: mulhu a5, a1, a2
2534 ; RV32ZBA-NEXT: snez a5, a5
2535 ; RV32ZBA-NEXT: or a4, a4, a5
2536 ; RV32ZBA-NEXT: mulhu a5, a3, a0
2537 ; RV32ZBA-NEXT: snez a5, a5
2538 ; RV32ZBA-NEXT: or a4, a4, a5
2539 ; RV32ZBA-NEXT: or a4, a4, a6
2540 ; RV32ZBA-NEXT: bnez a4, .LBB48_2
2541 ; RV32ZBA-NEXT: # %bb.1: # %entry
2542 ; RV32ZBA-NEXT: mv a0, a2
2543 ; RV32ZBA-NEXT: mv a1, a3
2544 ; RV32ZBA-NEXT: .LBB48_2: # %entry
2547 ; RV64ZBA-LABEL: umulo.select.i64:
2548 ; RV64ZBA: # %bb.0: # %entry
2549 ; RV64ZBA-NEXT: mulhu a2, a0, a1
2550 ; RV64ZBA-NEXT: bnez a2, .LBB48_2
2551 ; RV64ZBA-NEXT: # %bb.1: # %entry
2552 ; RV64ZBA-NEXT: mv a0, a1
2553 ; RV64ZBA-NEXT: .LBB48_2: # %entry
2556 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
2557 %obit = extractvalue {i64, i1} %t, 1
2558 %ret = select i1 %obit, i64 %v1, i64 %v2
2562 define i1 @umulo.not.i64(i64 %v1, i64 %v2) {
2563 ; RV32-LABEL: umulo.not.i64:
2564 ; RV32: # %bb.0: # %entry
2565 ; RV32-NEXT: mul a4, a3, a0
2566 ; RV32-NEXT: mul a5, a1, a2
2567 ; RV32-NEXT: add a4, a5, a4
2568 ; RV32-NEXT: mulhu a5, a0, a2
2569 ; RV32-NEXT: add a4, a5, a4
2570 ; RV32-NEXT: sltu a6, a4, a5
2571 ; RV32-NEXT: snez a5, a3
2572 ; RV32-NEXT: snez a4, a1
2573 ; RV32-NEXT: and a4, a4, a5
2574 ; RV32-NEXT: mulhu a1, a1, a2
2575 ; RV32-NEXT: snez a1, a1
2576 ; RV32-NEXT: or a1, a4, a1
2577 ; RV32-NEXT: mulhu a0, a3, a0
2578 ; RV32-NEXT: snez a0, a0
2579 ; RV32-NEXT: or a0, a1, a0
2580 ; RV32-NEXT: or a0, a0, a6
2581 ; RV32-NEXT: xori a0, a0, 1
2584 ; RV64-LABEL: umulo.not.i64:
2585 ; RV64: # %bb.0: # %entry
2586 ; RV64-NEXT: mulhu a0, a0, a1
2587 ; RV64-NEXT: seqz a0, a0
2590 ; RV32ZBA-LABEL: umulo.not.i64:
2591 ; RV32ZBA: # %bb.0: # %entry
2592 ; RV32ZBA-NEXT: mul a4, a3, a0
2593 ; RV32ZBA-NEXT: mul a5, a1, a2
2594 ; RV32ZBA-NEXT: add a4, a5, a4
2595 ; RV32ZBA-NEXT: mulhu a5, a0, a2
2596 ; RV32ZBA-NEXT: add a4, a5, a4
2597 ; RV32ZBA-NEXT: sltu a6, a4, a5
2598 ; RV32ZBA-NEXT: snez a5, a3
2599 ; RV32ZBA-NEXT: snez a4, a1
2600 ; RV32ZBA-NEXT: and a4, a4, a5
2601 ; RV32ZBA-NEXT: mulhu a1, a1, a2
2602 ; RV32ZBA-NEXT: snez a1, a1
2603 ; RV32ZBA-NEXT: or a1, a4, a1
2604 ; RV32ZBA-NEXT: mulhu a0, a3, a0
2605 ; RV32ZBA-NEXT: snez a0, a0
2606 ; RV32ZBA-NEXT: or a0, a1, a0
2607 ; RV32ZBA-NEXT: or a0, a0, a6
2608 ; RV32ZBA-NEXT: xori a0, a0, 1
2611 ; RV64ZBA-LABEL: umulo.not.i64:
2612 ; RV64ZBA: # %bb.0: # %entry
2613 ; RV64ZBA-NEXT: mulhu a0, a0, a1
2614 ; RV64ZBA-NEXT: seqz a0, a0
2617 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
2618 %obit = extractvalue {i64, i1} %t, 1
2619 %ret = xor i1 %obit, true
2625 ; Check the use of the overflow bit in combination with a branch instruction.
2627 define zeroext i1 @saddo.br.i32(i32 %v1, i32 %v2) {
2628 ; RV32-LABEL: saddo.br.i32:
2629 ; RV32: # %bb.0: # %entry
2630 ; RV32-NEXT: add a2, a0, a1
2631 ; RV32-NEXT: slt a0, a2, a0
2632 ; RV32-NEXT: slti a1, a1, 0
2633 ; RV32-NEXT: beq a1, a0, .LBB50_2
2634 ; RV32-NEXT: # %bb.1: # %overflow
2635 ; RV32-NEXT: mv a0, zero
2637 ; RV32-NEXT: .LBB50_2: # %continue
2638 ; RV32-NEXT: addi a0, zero, 1
2641 ; RV64-LABEL: saddo.br.i32:
2642 ; RV64: # %bb.0: # %entry
2643 ; RV64-NEXT: sext.w a1, a1
2644 ; RV64-NEXT: sext.w a0, a0
2645 ; RV64-NEXT: add a2, a0, a1
2646 ; RV64-NEXT: addw a0, a0, a1
2647 ; RV64-NEXT: beq a0, a2, .LBB50_2
2648 ; RV64-NEXT: # %bb.1: # %overflow
2649 ; RV64-NEXT: mv a0, zero
2651 ; RV64-NEXT: .LBB50_2: # %continue
2652 ; RV64-NEXT: addi a0, zero, 1
2655 ; RV32ZBA-LABEL: saddo.br.i32:
2656 ; RV32ZBA: # %bb.0: # %entry
2657 ; RV32ZBA-NEXT: add a2, a0, a1
2658 ; RV32ZBA-NEXT: slt a0, a2, a0
2659 ; RV32ZBA-NEXT: slti a1, a1, 0
2660 ; RV32ZBA-NEXT: beq a1, a0, .LBB50_2
2661 ; RV32ZBA-NEXT: # %bb.1: # %overflow
2662 ; RV32ZBA-NEXT: mv a0, zero
2664 ; RV32ZBA-NEXT: .LBB50_2: # %continue
2665 ; RV32ZBA-NEXT: addi a0, zero, 1
2668 ; RV64ZBA-LABEL: saddo.br.i32:
2669 ; RV64ZBA: # %bb.0: # %entry
2670 ; RV64ZBA-NEXT: sext.w a1, a1
2671 ; RV64ZBA-NEXT: sext.w a0, a0
2672 ; RV64ZBA-NEXT: add a2, a0, a1
2673 ; RV64ZBA-NEXT: addw a0, a0, a1
2674 ; RV64ZBA-NEXT: beq a0, a2, .LBB50_2
2675 ; RV64ZBA-NEXT: # %bb.1: # %overflow
2676 ; RV64ZBA-NEXT: mv a0, zero
2678 ; RV64ZBA-NEXT: .LBB50_2: # %continue
2679 ; RV64ZBA-NEXT: addi a0, zero, 1
2682 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2)
2683 %val = extractvalue {i32, i1} %t, 0
2684 %obit = extractvalue {i32, i1} %t, 1
2685 br i1 %obit, label %overflow, label %continue
2694 define zeroext i1 @saddo.br.i64(i64 %v1, i64 %v2) {
2695 ; RV32-LABEL: saddo.br.i64:
2696 ; RV32: # %bb.0: # %entry
2697 ; RV32-NEXT: add a4, a1, a3
2698 ; RV32-NEXT: add a2, a0, a2
2699 ; RV32-NEXT: sltu a0, a2, a0
2700 ; RV32-NEXT: add a0, a4, a0
2701 ; RV32-NEXT: xor a0, a1, a0
2702 ; RV32-NEXT: xor a1, a1, a3
2703 ; RV32-NEXT: not a1, a1
2704 ; RV32-NEXT: and a0, a1, a0
2705 ; RV32-NEXT: bgez a0, .LBB51_2
2706 ; RV32-NEXT: # %bb.1: # %overflow
2707 ; RV32-NEXT: mv a0, zero
2709 ; RV32-NEXT: .LBB51_2: # %continue
2710 ; RV32-NEXT: addi a0, zero, 1
2713 ; RV64-LABEL: saddo.br.i64:
2714 ; RV64: # %bb.0: # %entry
2715 ; RV64-NEXT: add a2, a0, a1
2716 ; RV64-NEXT: slt a0, a2, a0
2717 ; RV64-NEXT: slti a1, a1, 0
2718 ; RV64-NEXT: beq a1, a0, .LBB51_2
2719 ; RV64-NEXT: # %bb.1: # %overflow
2720 ; RV64-NEXT: mv a0, zero
2722 ; RV64-NEXT: .LBB51_2: # %continue
2723 ; RV64-NEXT: addi a0, zero, 1
2726 ; RV32ZBA-LABEL: saddo.br.i64:
2727 ; RV32ZBA: # %bb.0: # %entry
2728 ; RV32ZBA-NEXT: add a4, a1, a3
2729 ; RV32ZBA-NEXT: add a2, a0, a2
2730 ; RV32ZBA-NEXT: sltu a0, a2, a0
2731 ; RV32ZBA-NEXT: add a0, a4, a0
2732 ; RV32ZBA-NEXT: xor a0, a1, a0
2733 ; RV32ZBA-NEXT: xor a1, a1, a3
2734 ; RV32ZBA-NEXT: not a1, a1
2735 ; RV32ZBA-NEXT: and a0, a1, a0
2736 ; RV32ZBA-NEXT: bgez a0, .LBB51_2
2737 ; RV32ZBA-NEXT: # %bb.1: # %overflow
2738 ; RV32ZBA-NEXT: mv a0, zero
2740 ; RV32ZBA-NEXT: .LBB51_2: # %continue
2741 ; RV32ZBA-NEXT: addi a0, zero, 1
2744 ; RV64ZBA-LABEL: saddo.br.i64:
2745 ; RV64ZBA: # %bb.0: # %entry
2746 ; RV64ZBA-NEXT: add a2, a0, a1
2747 ; RV64ZBA-NEXT: slt a0, a2, a0
2748 ; RV64ZBA-NEXT: slti a1, a1, 0
2749 ; RV64ZBA-NEXT: beq a1, a0, .LBB51_2
2750 ; RV64ZBA-NEXT: # %bb.1: # %overflow
2751 ; RV64ZBA-NEXT: mv a0, zero
2753 ; RV64ZBA-NEXT: .LBB51_2: # %continue
2754 ; RV64ZBA-NEXT: addi a0, zero, 1
2757 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2)
2758 %val = extractvalue {i64, i1} %t, 0
2759 %obit = extractvalue {i64, i1} %t, 1
2760 br i1 %obit, label %overflow, label %continue
2769 define zeroext i1 @uaddo.br.i32(i32 %v1, i32 %v2) {
2770 ; RV32-LABEL: uaddo.br.i32:
2771 ; RV32: # %bb.0: # %entry
2772 ; RV32-NEXT: add a1, a0, a1
2773 ; RV32-NEXT: bgeu a1, a0, .LBB52_2
2774 ; RV32-NEXT: # %bb.1: # %overflow
2775 ; RV32-NEXT: mv a0, zero
2777 ; RV32-NEXT: .LBB52_2: # %continue
2778 ; RV32-NEXT: addi a0, zero, 1
2781 ; RV64-LABEL: uaddo.br.i32:
2782 ; RV64: # %bb.0: # %entry
2783 ; RV64-NEXT: addw a1, a0, a1
2784 ; RV64-NEXT: sext.w a0, a0
2785 ; RV64-NEXT: bgeu a1, a0, .LBB52_2
2786 ; RV64-NEXT: # %bb.1: # %overflow
2787 ; RV64-NEXT: mv a0, zero
2789 ; RV64-NEXT: .LBB52_2: # %continue
2790 ; RV64-NEXT: addi a0, zero, 1
2793 ; RV32ZBA-LABEL: uaddo.br.i32:
2794 ; RV32ZBA: # %bb.0: # %entry
2795 ; RV32ZBA-NEXT: add a1, a0, a1
2796 ; RV32ZBA-NEXT: bgeu a1, a0, .LBB52_2
2797 ; RV32ZBA-NEXT: # %bb.1: # %overflow
2798 ; RV32ZBA-NEXT: mv a0, zero
2800 ; RV32ZBA-NEXT: .LBB52_2: # %continue
2801 ; RV32ZBA-NEXT: addi a0, zero, 1
2804 ; RV64ZBA-LABEL: uaddo.br.i32:
2805 ; RV64ZBA: # %bb.0: # %entry
2806 ; RV64ZBA-NEXT: addw a1, a0, a1
2807 ; RV64ZBA-NEXT: sext.w a0, a0
2808 ; RV64ZBA-NEXT: bgeu a1, a0, .LBB52_2
2809 ; RV64ZBA-NEXT: # %bb.1: # %overflow
2810 ; RV64ZBA-NEXT: mv a0, zero
2812 ; RV64ZBA-NEXT: .LBB52_2: # %continue
2813 ; RV64ZBA-NEXT: addi a0, zero, 1
2816 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)
2817 %val = extractvalue {i32, i1} %t, 0
2818 %obit = extractvalue {i32, i1} %t, 1
2819 br i1 %obit, label %overflow, label %continue
2828 define zeroext i1 @uaddo.br.i64(i64 %v1, i64 %v2) {
2829 ; RV32-LABEL: uaddo.br.i64:
2830 ; RV32: # %bb.0: # %entry
2831 ; RV32-NEXT: add a3, a1, a3
2832 ; RV32-NEXT: add a2, a0, a2
2833 ; RV32-NEXT: sltu a0, a2, a0
2834 ; RV32-NEXT: add a2, a3, a0
2835 ; RV32-NEXT: beq a2, a1, .LBB53_2
2836 ; RV32-NEXT: # %bb.1: # %entry
2837 ; RV32-NEXT: sltu a0, a2, a1
2838 ; RV32-NEXT: .LBB53_2: # %entry
2839 ; RV32-NEXT: beqz a0, .LBB53_4
2840 ; RV32-NEXT: # %bb.3: # %overflow
2841 ; RV32-NEXT: mv a0, zero
2843 ; RV32-NEXT: .LBB53_4: # %continue
2844 ; RV32-NEXT: addi a0, zero, 1
2847 ; RV64-LABEL: uaddo.br.i64:
2848 ; RV64: # %bb.0: # %entry
2849 ; RV64-NEXT: add a1, a0, a1
2850 ; RV64-NEXT: bgeu a1, a0, .LBB53_2
2851 ; RV64-NEXT: # %bb.1: # %overflow
2852 ; RV64-NEXT: mv a0, zero
2854 ; RV64-NEXT: .LBB53_2: # %continue
2855 ; RV64-NEXT: addi a0, zero, 1
2858 ; RV32ZBA-LABEL: uaddo.br.i64:
2859 ; RV32ZBA: # %bb.0: # %entry
2860 ; RV32ZBA-NEXT: add a3, a1, a3
2861 ; RV32ZBA-NEXT: add a2, a0, a2
2862 ; RV32ZBA-NEXT: sltu a0, a2, a0
2863 ; RV32ZBA-NEXT: add a2, a3, a0
2864 ; RV32ZBA-NEXT: beq a2, a1, .LBB53_2
2865 ; RV32ZBA-NEXT: # %bb.1: # %entry
2866 ; RV32ZBA-NEXT: sltu a0, a2, a1
2867 ; RV32ZBA-NEXT: .LBB53_2: # %entry
2868 ; RV32ZBA-NEXT: beqz a0, .LBB53_4
2869 ; RV32ZBA-NEXT: # %bb.3: # %overflow
2870 ; RV32ZBA-NEXT: mv a0, zero
2872 ; RV32ZBA-NEXT: .LBB53_4: # %continue
2873 ; RV32ZBA-NEXT: addi a0, zero, 1
2876 ; RV64ZBA-LABEL: uaddo.br.i64:
2877 ; RV64ZBA: # %bb.0: # %entry
2878 ; RV64ZBA-NEXT: add a1, a0, a1
2879 ; RV64ZBA-NEXT: bgeu a1, a0, .LBB53_2
2880 ; RV64ZBA-NEXT: # %bb.1: # %overflow
2881 ; RV64ZBA-NEXT: mv a0, zero
2883 ; RV64ZBA-NEXT: .LBB53_2: # %continue
2884 ; RV64ZBA-NEXT: addi a0, zero, 1
2887 %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2)
2888 %val = extractvalue {i64, i1} %t, 0
2889 %obit = extractvalue {i64, i1} %t, 1
2890 br i1 %obit, label %overflow, label %continue
2899 define zeroext i1 @ssubo.br.i32(i32 %v1, i32 %v2) {
2900 ; RV32-LABEL: ssubo.br.i32:
2901 ; RV32: # %bb.0: # %entry
2902 ; RV32-NEXT: sgtz a2, a1
2903 ; RV32-NEXT: sub a1, a0, a1
2904 ; RV32-NEXT: slt a0, a1, a0
2905 ; RV32-NEXT: beq a2, a0, .LBB54_2
2906 ; RV32-NEXT: # %bb.1: # %overflow
2907 ; RV32-NEXT: mv a0, zero
2909 ; RV32-NEXT: .LBB54_2: # %continue
2910 ; RV32-NEXT: addi a0, zero, 1
2913 ; RV64-LABEL: ssubo.br.i32:
2914 ; RV64: # %bb.0: # %entry
2915 ; RV64-NEXT: sext.w a1, a1
2916 ; RV64-NEXT: sext.w a0, a0
2917 ; RV64-NEXT: sub a2, a0, a1
2918 ; RV64-NEXT: subw a0, a0, a1
2919 ; RV64-NEXT: beq a0, a2, .LBB54_2
2920 ; RV64-NEXT: # %bb.1: # %overflow
2921 ; RV64-NEXT: mv a0, zero
2923 ; RV64-NEXT: .LBB54_2: # %continue
2924 ; RV64-NEXT: addi a0, zero, 1
2927 ; RV32ZBA-LABEL: ssubo.br.i32:
2928 ; RV32ZBA: # %bb.0: # %entry
2929 ; RV32ZBA-NEXT: sgtz a2, a1
2930 ; RV32ZBA-NEXT: sub a1, a0, a1
2931 ; RV32ZBA-NEXT: slt a0, a1, a0
2932 ; RV32ZBA-NEXT: beq a2, a0, .LBB54_2
2933 ; RV32ZBA-NEXT: # %bb.1: # %overflow
2934 ; RV32ZBA-NEXT: mv a0, zero
2936 ; RV32ZBA-NEXT: .LBB54_2: # %continue
2937 ; RV32ZBA-NEXT: addi a0, zero, 1
2940 ; RV64ZBA-LABEL: ssubo.br.i32:
2941 ; RV64ZBA: # %bb.0: # %entry
2942 ; RV64ZBA-NEXT: sext.w a1, a1
2943 ; RV64ZBA-NEXT: sext.w a0, a0
2944 ; RV64ZBA-NEXT: sub a2, a0, a1
2945 ; RV64ZBA-NEXT: subw a0, a0, a1
2946 ; RV64ZBA-NEXT: beq a0, a2, .LBB54_2
2947 ; RV64ZBA-NEXT: # %bb.1: # %overflow
2948 ; RV64ZBA-NEXT: mv a0, zero
2950 ; RV64ZBA-NEXT: .LBB54_2: # %continue
2951 ; RV64ZBA-NEXT: addi a0, zero, 1
2954 %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2)
2955 %val = extractvalue {i32, i1} %t, 0
2956 %obit = extractvalue {i32, i1} %t, 1
2957 br i1 %obit, label %overflow, label %continue
2966 define zeroext i1 @ssubo.br.i64(i64 %v1, i64 %v2) {
2967 ; RV32-LABEL: ssubo.br.i64:
2968 ; RV32: # %bb.0: # %entry
2969 ; RV32-NEXT: sltu a0, a0, a2
2970 ; RV32-NEXT: sub a2, a1, a3
2971 ; RV32-NEXT: sub a0, a2, a0
2972 ; RV32-NEXT: xor a0, a1, a0
2973 ; RV32-NEXT: xor a1, a1, a3
2974 ; RV32-NEXT: and a0, a1, a0
2975 ; RV32-NEXT: bgez a0, .LBB55_2
2976 ; RV32-NEXT: # %bb.1: # %overflow
2977 ; RV32-NEXT: mv a0, zero
2979 ; RV32-NEXT: .LBB55_2: # %continue
2980 ; RV32-NEXT: addi a0, zero, 1
2983 ; RV64-LABEL: ssubo.br.i64:
2984 ; RV64: # %bb.0: # %entry
2985 ; RV64-NEXT: sgtz a2, a1
2986 ; RV64-NEXT: sub a1, a0, a1
2987 ; RV64-NEXT: slt a0, a1, a0
2988 ; RV64-NEXT: beq a2, a0, .LBB55_2
2989 ; RV64-NEXT: # %bb.1: # %overflow
2990 ; RV64-NEXT: mv a0, zero
2992 ; RV64-NEXT: .LBB55_2: # %continue
2993 ; RV64-NEXT: addi a0, zero, 1
2996 ; RV32ZBA-LABEL: ssubo.br.i64:
2997 ; RV32ZBA: # %bb.0: # %entry
2998 ; RV32ZBA-NEXT: sltu a0, a0, a2
2999 ; RV32ZBA-NEXT: sub a2, a1, a3
3000 ; RV32ZBA-NEXT: sub a0, a2, a0
3001 ; RV32ZBA-NEXT: xor a0, a1, a0
3002 ; RV32ZBA-NEXT: xor a1, a1, a3
3003 ; RV32ZBA-NEXT: and a0, a1, a0
3004 ; RV32ZBA-NEXT: bgez a0, .LBB55_2
3005 ; RV32ZBA-NEXT: # %bb.1: # %overflow
3006 ; RV32ZBA-NEXT: mv a0, zero
3008 ; RV32ZBA-NEXT: .LBB55_2: # %continue
3009 ; RV32ZBA-NEXT: addi a0, zero, 1
3012 ; RV64ZBA-LABEL: ssubo.br.i64:
3013 ; RV64ZBA: # %bb.0: # %entry
3014 ; RV64ZBA-NEXT: sgtz a2, a1
3015 ; RV64ZBA-NEXT: sub a1, a0, a1
3016 ; RV64ZBA-NEXT: slt a0, a1, a0
3017 ; RV64ZBA-NEXT: beq a2, a0, .LBB55_2
3018 ; RV64ZBA-NEXT: # %bb.1: # %overflow
3019 ; RV64ZBA-NEXT: mv a0, zero
3021 ; RV64ZBA-NEXT: .LBB55_2: # %continue
3022 ; RV64ZBA-NEXT: addi a0, zero, 1
3025 %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2)
3026 %val = extractvalue {i64, i1} %t, 0
3027 %obit = extractvalue {i64, i1} %t, 1
3028 br i1 %obit, label %overflow, label %continue
3037 define zeroext i1 @usubo.br.i32(i32 %v1, i32 %v2) {
3038 ; RV32-LABEL: usubo.br.i32:
3039 ; RV32: # %bb.0: # %entry
3040 ; RV32-NEXT: sub a1, a0, a1
3041 ; RV32-NEXT: bgeu a0, a1, .LBB56_2
3042 ; RV32-NEXT: # %bb.1: # %overflow
3043 ; RV32-NEXT: mv a0, zero
3045 ; RV32-NEXT: .LBB56_2: # %continue
3046 ; RV32-NEXT: addi a0, zero, 1
3049 ; RV64-LABEL: usubo.br.i32:
3050 ; RV64: # %bb.0: # %entry
3051 ; RV64-NEXT: subw a1, a0, a1
3052 ; RV64-NEXT: sext.w a0, a0
3053 ; RV64-NEXT: bgeu a0, a1, .LBB56_2
3054 ; RV64-NEXT: # %bb.1: # %overflow
3055 ; RV64-NEXT: mv a0, zero
3057 ; RV64-NEXT: .LBB56_2: # %continue
3058 ; RV64-NEXT: addi a0, zero, 1
3061 ; RV32ZBA-LABEL: usubo.br.i32:
3062 ; RV32ZBA: # %bb.0: # %entry
3063 ; RV32ZBA-NEXT: sub a1, a0, a1
3064 ; RV32ZBA-NEXT: bgeu a0, a1, .LBB56_2
3065 ; RV32ZBA-NEXT: # %bb.1: # %overflow
3066 ; RV32ZBA-NEXT: mv a0, zero
3068 ; RV32ZBA-NEXT: .LBB56_2: # %continue
3069 ; RV32ZBA-NEXT: addi a0, zero, 1
3072 ; RV64ZBA-LABEL: usubo.br.i32:
3073 ; RV64ZBA: # %bb.0: # %entry
3074 ; RV64ZBA-NEXT: subw a1, a0, a1
3075 ; RV64ZBA-NEXT: sext.w a0, a0
3076 ; RV64ZBA-NEXT: bgeu a0, a1, .LBB56_2
3077 ; RV64ZBA-NEXT: # %bb.1: # %overflow
3078 ; RV64ZBA-NEXT: mv a0, zero
3080 ; RV64ZBA-NEXT: .LBB56_2: # %continue
3081 ; RV64ZBA-NEXT: addi a0, zero, 1
3084 %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2)
3085 %val = extractvalue {i32, i1} %t, 0
3086 %obit = extractvalue {i32, i1} %t, 1
3087 br i1 %obit, label %overflow, label %continue
3096 define zeroext i1 @usubo.br.i64(i64 %v1, i64 %v2) {
3097 ; RV32-LABEL: usubo.br.i64:
3098 ; RV32: # %bb.0: # %entry
3099 ; RV32-NEXT: sltu a4, a0, a2
3100 ; RV32-NEXT: sub a3, a1, a3
3101 ; RV32-NEXT: sub a3, a3, a4
3102 ; RV32-NEXT: beq a3, a1, .LBB57_3
3103 ; RV32-NEXT: # %bb.1: # %entry
3104 ; RV32-NEXT: sltu a0, a1, a3
3105 ; RV32-NEXT: bnez a0, .LBB57_4
3106 ; RV32-NEXT: .LBB57_2: # %continue
3107 ; RV32-NEXT: addi a0, zero, 1
3109 ; RV32-NEXT: .LBB57_3:
3110 ; RV32-NEXT: sub a1, a0, a2
3111 ; RV32-NEXT: sltu a0, a0, a1
3112 ; RV32-NEXT: beqz a0, .LBB57_2
3113 ; RV32-NEXT: .LBB57_4: # %overflow
3114 ; RV32-NEXT: mv a0, zero
3117 ; RV64-LABEL: usubo.br.i64:
3118 ; RV64: # %bb.0: # %entry
3119 ; RV64-NEXT: sub a1, a0, a1
3120 ; RV64-NEXT: bgeu a0, a1, .LBB57_2
3121 ; RV64-NEXT: # %bb.1: # %overflow
3122 ; RV64-NEXT: mv a0, zero
3124 ; RV64-NEXT: .LBB57_2: # %continue
3125 ; RV64-NEXT: addi a0, zero, 1
3128 ; RV32ZBA-LABEL: usubo.br.i64:
3129 ; RV32ZBA: # %bb.0: # %entry
3130 ; RV32ZBA-NEXT: sltu a4, a0, a2
3131 ; RV32ZBA-NEXT: sub a3, a1, a3
3132 ; RV32ZBA-NEXT: sub a3, a3, a4
3133 ; RV32ZBA-NEXT: beq a3, a1, .LBB57_3
3134 ; RV32ZBA-NEXT: # %bb.1: # %entry
3135 ; RV32ZBA-NEXT: sltu a0, a1, a3
3136 ; RV32ZBA-NEXT: bnez a0, .LBB57_4
3137 ; RV32ZBA-NEXT: .LBB57_2: # %continue
3138 ; RV32ZBA-NEXT: addi a0, zero, 1
3140 ; RV32ZBA-NEXT: .LBB57_3:
3141 ; RV32ZBA-NEXT: sub a1, a0, a2
3142 ; RV32ZBA-NEXT: sltu a0, a0, a1
3143 ; RV32ZBA-NEXT: beqz a0, .LBB57_2
3144 ; RV32ZBA-NEXT: .LBB57_4: # %overflow
3145 ; RV32ZBA-NEXT: mv a0, zero
3148 ; RV64ZBA-LABEL: usubo.br.i64:
3149 ; RV64ZBA: # %bb.0: # %entry
3150 ; RV64ZBA-NEXT: sub a1, a0, a1
3151 ; RV64ZBA-NEXT: bgeu a0, a1, .LBB57_2
3152 ; RV64ZBA-NEXT: # %bb.1: # %overflow
3153 ; RV64ZBA-NEXT: mv a0, zero
3155 ; RV64ZBA-NEXT: .LBB57_2: # %continue
3156 ; RV64ZBA-NEXT: addi a0, zero, 1
3159 %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2)
3160 %val = extractvalue {i64, i1} %t, 0
3161 %obit = extractvalue {i64, i1} %t, 1
3162 br i1 %obit, label %overflow, label %continue
3171 define zeroext i1 @smulo.br.i32(i32 %v1, i32 %v2) {
3172 ; RV32-LABEL: smulo.br.i32:
3173 ; RV32: # %bb.0: # %entry
3174 ; RV32-NEXT: mulh a2, a0, a1
3175 ; RV32-NEXT: mul a0, a0, a1
3176 ; RV32-NEXT: srai a0, a0, 31
3177 ; RV32-NEXT: beq a2, a0, .LBB58_2
3178 ; RV32-NEXT: # %bb.1: # %overflow
3179 ; RV32-NEXT: mv a0, zero
3181 ; RV32-NEXT: .LBB58_2: # %continue
3182 ; RV32-NEXT: addi a0, zero, 1
3185 ; RV64-LABEL: smulo.br.i32:
3186 ; RV64: # %bb.0: # %entry
3187 ; RV64-NEXT: sext.w a1, a1
3188 ; RV64-NEXT: sext.w a0, a0
3189 ; RV64-NEXT: mul a2, a0, a1
3190 ; RV64-NEXT: mulw a0, a0, a1
3191 ; RV64-NEXT: beq a0, a2, .LBB58_2
3192 ; RV64-NEXT: # %bb.1: # %overflow
3193 ; RV64-NEXT: mv a0, zero
3195 ; RV64-NEXT: .LBB58_2: # %continue
3196 ; RV64-NEXT: addi a0, zero, 1
3199 ; RV32ZBA-LABEL: smulo.br.i32:
3200 ; RV32ZBA: # %bb.0: # %entry
3201 ; RV32ZBA-NEXT: mulh a2, a0, a1
3202 ; RV32ZBA-NEXT: mul a0, a0, a1
3203 ; RV32ZBA-NEXT: srai a0, a0, 31
3204 ; RV32ZBA-NEXT: beq a2, a0, .LBB58_2
3205 ; RV32ZBA-NEXT: # %bb.1: # %overflow
3206 ; RV32ZBA-NEXT: mv a0, zero
3208 ; RV32ZBA-NEXT: .LBB58_2: # %continue
3209 ; RV32ZBA-NEXT: addi a0, zero, 1
3212 ; RV64ZBA-LABEL: smulo.br.i32:
3213 ; RV64ZBA: # %bb.0: # %entry
3214 ; RV64ZBA-NEXT: sext.w a1, a1
3215 ; RV64ZBA-NEXT: sext.w a0, a0
3216 ; RV64ZBA-NEXT: mul a2, a0, a1
3217 ; RV64ZBA-NEXT: mulw a0, a0, a1
3218 ; RV64ZBA-NEXT: beq a0, a2, .LBB58_2
3219 ; RV64ZBA-NEXT: # %bb.1: # %overflow
3220 ; RV64ZBA-NEXT: mv a0, zero
3222 ; RV64ZBA-NEXT: .LBB58_2: # %continue
3223 ; RV64ZBA-NEXT: addi a0, zero, 1
3226 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
3227 %val = extractvalue {i32, i1} %t, 0
3228 %obit = extractvalue {i32, i1} %t, 1
3229 br i1 %obit, label %overflow, label %continue
3238 define zeroext i1 @smulo.br.i64(i64 %v1, i64 %v2) {
3239 ; RV32-LABEL: smulo.br.i64:
3240 ; RV32: # %bb.0: # %entry
3241 ; RV32-NEXT: addi sp, sp, -16
3242 ; RV32-NEXT: .cfi_def_cfa_offset 16
3243 ; RV32-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
3244 ; RV32-NEXT: .cfi_offset ra, -4
3245 ; RV32-NEXT: sw zero, 8(sp)
3246 ; RV32-NEXT: addi a4, sp, 8
3247 ; RV32-NEXT: call __mulodi4@plt
3248 ; RV32-NEXT: lw a0, 8(sp)
3249 ; RV32-NEXT: beqz a0, .LBB59_2
3250 ; RV32-NEXT: # %bb.1: # %overflow
3251 ; RV32-NEXT: mv a0, zero
3252 ; RV32-NEXT: j .LBB59_3
3253 ; RV32-NEXT: .LBB59_2: # %continue
3254 ; RV32-NEXT: addi a0, zero, 1
3255 ; RV32-NEXT: .LBB59_3: # %overflow
3256 ; RV32-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
3257 ; RV32-NEXT: addi sp, sp, 16
3260 ; RV64-LABEL: smulo.br.i64:
3261 ; RV64: # %bb.0: # %entry
3262 ; RV64-NEXT: mulh a2, a0, a1
3263 ; RV64-NEXT: mul a0, a0, a1
3264 ; RV64-NEXT: srai a0, a0, 63
3265 ; RV64-NEXT: beq a2, a0, .LBB59_2
3266 ; RV64-NEXT: # %bb.1: # %overflow
3267 ; RV64-NEXT: mv a0, zero
3269 ; RV64-NEXT: .LBB59_2: # %continue
3270 ; RV64-NEXT: addi a0, zero, 1
3273 ; RV32ZBA-LABEL: smulo.br.i64:
3274 ; RV32ZBA: # %bb.0: # %entry
3275 ; RV32ZBA-NEXT: addi sp, sp, -16
3276 ; RV32ZBA-NEXT: .cfi_def_cfa_offset 16
3277 ; RV32ZBA-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
3278 ; RV32ZBA-NEXT: .cfi_offset ra, -4
3279 ; RV32ZBA-NEXT: sw zero, 8(sp)
3280 ; RV32ZBA-NEXT: addi a4, sp, 8
3281 ; RV32ZBA-NEXT: call __mulodi4@plt
3282 ; RV32ZBA-NEXT: lw a0, 8(sp)
3283 ; RV32ZBA-NEXT: beqz a0, .LBB59_2
3284 ; RV32ZBA-NEXT: # %bb.1: # %overflow
3285 ; RV32ZBA-NEXT: mv a0, zero
3286 ; RV32ZBA-NEXT: j .LBB59_3
3287 ; RV32ZBA-NEXT: .LBB59_2: # %continue
3288 ; RV32ZBA-NEXT: addi a0, zero, 1
3289 ; RV32ZBA-NEXT: .LBB59_3: # %overflow
3290 ; RV32ZBA-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
3291 ; RV32ZBA-NEXT: addi sp, sp, 16
3294 ; RV64ZBA-LABEL: smulo.br.i64:
3295 ; RV64ZBA: # %bb.0: # %entry
3296 ; RV64ZBA-NEXT: mulh a2, a0, a1
3297 ; RV64ZBA-NEXT: mul a0, a0, a1
3298 ; RV64ZBA-NEXT: srai a0, a0, 63
3299 ; RV64ZBA-NEXT: beq a2, a0, .LBB59_2
3300 ; RV64ZBA-NEXT: # %bb.1: # %overflow
3301 ; RV64ZBA-NEXT: mv a0, zero
3303 ; RV64ZBA-NEXT: .LBB59_2: # %continue
3304 ; RV64ZBA-NEXT: addi a0, zero, 1
3307 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
3308 %val = extractvalue {i64, i1} %t, 0
3309 %obit = extractvalue {i64, i1} %t, 1
3310 br i1 %obit, label %overflow, label %continue
3319 define zeroext i1 @smulo2.br.i64(i64 %v1) {
3320 ; RV32-LABEL: smulo2.br.i64:
3321 ; RV32: # %bb.0: # %entry
3322 ; RV32-NEXT: addi sp, sp, -16
3323 ; RV32-NEXT: .cfi_def_cfa_offset 16
3324 ; RV32-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
3325 ; RV32-NEXT: .cfi_offset ra, -4
3326 ; RV32-NEXT: sw zero, 8(sp)
3327 ; RV32-NEXT: addi a2, zero, -13
3328 ; RV32-NEXT: addi a3, zero, -1
3329 ; RV32-NEXT: addi a4, sp, 8
3330 ; RV32-NEXT: call __mulodi4@plt
3331 ; RV32-NEXT: lw a0, 8(sp)
3332 ; RV32-NEXT: beqz a0, .LBB60_2
3333 ; RV32-NEXT: # %bb.1: # %overflow
3334 ; RV32-NEXT: mv a0, zero
3335 ; RV32-NEXT: j .LBB60_3
3336 ; RV32-NEXT: .LBB60_2: # %continue
3337 ; RV32-NEXT: addi a0, zero, 1
3338 ; RV32-NEXT: .LBB60_3: # %overflow
3339 ; RV32-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
3340 ; RV32-NEXT: addi sp, sp, 16
3343 ; RV64-LABEL: smulo2.br.i64:
3344 ; RV64: # %bb.0: # %entry
3345 ; RV64-NEXT: addi a1, zero, -13
3346 ; RV64-NEXT: mulh a2, a0, a1
3347 ; RV64-NEXT: mul a0, a0, a1
3348 ; RV64-NEXT: srai a0, a0, 63
3349 ; RV64-NEXT: beq a2, a0, .LBB60_2
3350 ; RV64-NEXT: # %bb.1: # %overflow
3351 ; RV64-NEXT: mv a0, zero
3353 ; RV64-NEXT: .LBB60_2: # %continue
3354 ; RV64-NEXT: addi a0, zero, 1
3357 ; RV32ZBA-LABEL: smulo2.br.i64:
3358 ; RV32ZBA: # %bb.0: # %entry
3359 ; RV32ZBA-NEXT: addi sp, sp, -16
3360 ; RV32ZBA-NEXT: .cfi_def_cfa_offset 16
3361 ; RV32ZBA-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
3362 ; RV32ZBA-NEXT: .cfi_offset ra, -4
3363 ; RV32ZBA-NEXT: sw zero, 8(sp)
3364 ; RV32ZBA-NEXT: addi a2, zero, -13
3365 ; RV32ZBA-NEXT: addi a3, zero, -1
3366 ; RV32ZBA-NEXT: addi a4, sp, 8
3367 ; RV32ZBA-NEXT: call __mulodi4@plt
3368 ; RV32ZBA-NEXT: lw a0, 8(sp)
3369 ; RV32ZBA-NEXT: beqz a0, .LBB60_2
3370 ; RV32ZBA-NEXT: # %bb.1: # %overflow
3371 ; RV32ZBA-NEXT: mv a0, zero
3372 ; RV32ZBA-NEXT: j .LBB60_3
3373 ; RV32ZBA-NEXT: .LBB60_2: # %continue
3374 ; RV32ZBA-NEXT: addi a0, zero, 1
3375 ; RV32ZBA-NEXT: .LBB60_3: # %overflow
3376 ; RV32ZBA-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
3377 ; RV32ZBA-NEXT: addi sp, sp, 16
3380 ; RV64ZBA-LABEL: smulo2.br.i64:
3381 ; RV64ZBA: # %bb.0: # %entry
3382 ; RV64ZBA-NEXT: addi a1, zero, -13
3383 ; RV64ZBA-NEXT: mulh a2, a0, a1
3384 ; RV64ZBA-NEXT: mul a0, a0, a1
3385 ; RV64ZBA-NEXT: srai a0, a0, 63
3386 ; RV64ZBA-NEXT: beq a2, a0, .LBB60_2
3387 ; RV64ZBA-NEXT: # %bb.1: # %overflow
3388 ; RV64ZBA-NEXT: mv a0, zero
3390 ; RV64ZBA-NEXT: .LBB60_2: # %continue
3391 ; RV64ZBA-NEXT: addi a0, zero, 1
3394 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 -13)
3395 %val = extractvalue {i64, i1} %t, 0
3396 %obit = extractvalue {i64, i1} %t, 1
3397 br i1 %obit, label %overflow, label %continue
3406 define zeroext i1 @umulo.br.i32(i32 %v1, i32 %v2) {
3407 ; RV32-LABEL: umulo.br.i32:
3408 ; RV32: # %bb.0: # %entry
3409 ; RV32-NEXT: mulhu a0, a0, a1
3410 ; RV32-NEXT: beqz a0, .LBB61_2
3411 ; RV32-NEXT: # %bb.1: # %overflow
3412 ; RV32-NEXT: mv a0, zero
3414 ; RV32-NEXT: .LBB61_2: # %continue
3415 ; RV32-NEXT: addi a0, zero, 1
3418 ; RV64-LABEL: umulo.br.i32:
3419 ; RV64: # %bb.0: # %entry
3420 ; RV64-NEXT: slli a1, a1, 32
3421 ; RV64-NEXT: slli a0, a0, 32
3422 ; RV64-NEXT: mulhu a0, a0, a1
3423 ; RV64-NEXT: srli a0, a0, 32
3424 ; RV64-NEXT: beqz a0, .LBB61_2
3425 ; RV64-NEXT: # %bb.1: # %overflow
3426 ; RV64-NEXT: mv a0, zero
3428 ; RV64-NEXT: .LBB61_2: # %continue
3429 ; RV64-NEXT: addi a0, zero, 1
3432 ; RV32ZBA-LABEL: umulo.br.i32:
3433 ; RV32ZBA: # %bb.0: # %entry
3434 ; RV32ZBA-NEXT: mulhu a0, a0, a1
3435 ; RV32ZBA-NEXT: beqz a0, .LBB61_2
3436 ; RV32ZBA-NEXT: # %bb.1: # %overflow
3437 ; RV32ZBA-NEXT: mv a0, zero
3439 ; RV32ZBA-NEXT: .LBB61_2: # %continue
3440 ; RV32ZBA-NEXT: addi a0, zero, 1
3443 ; RV64ZBA-LABEL: umulo.br.i32:
3444 ; RV64ZBA: # %bb.0: # %entry
3445 ; RV64ZBA-NEXT: zext.w a1, a1
3446 ; RV64ZBA-NEXT: zext.w a0, a0
3447 ; RV64ZBA-NEXT: mul a0, a0, a1
3448 ; RV64ZBA-NEXT: srli a0, a0, 32
3449 ; RV64ZBA-NEXT: beqz a0, .LBB61_2
3450 ; RV64ZBA-NEXT: # %bb.1: # %overflow
3451 ; RV64ZBA-NEXT: mv a0, zero
3453 ; RV64ZBA-NEXT: .LBB61_2: # %continue
3454 ; RV64ZBA-NEXT: addi a0, zero, 1
3457 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
3458 %val = extractvalue {i32, i1} %t, 0
3459 %obit = extractvalue {i32, i1} %t, 1
3460 br i1 %obit, label %overflow, label %continue
3469 define zeroext i1 @umulo.br.i64(i64 %v1, i64 %v2) {
3470 ; RV32-LABEL: umulo.br.i64:
3471 ; RV32: # %bb.0: # %entry
3472 ; RV32-NEXT: mul a4, a3, a0
3473 ; RV32-NEXT: mul a5, a1, a2
3474 ; RV32-NEXT: add a4, a5, a4
3475 ; RV32-NEXT: mulhu a5, a0, a2
3476 ; RV32-NEXT: add a4, a5, a4
3477 ; RV32-NEXT: sltu a6, a4, a5
3478 ; RV32-NEXT: snez a5, a3
3479 ; RV32-NEXT: snez a4, a1
3480 ; RV32-NEXT: and a4, a4, a5
3481 ; RV32-NEXT: mulhu a1, a1, a2
3482 ; RV32-NEXT: snez a1, a1
3483 ; RV32-NEXT: or a1, a4, a1
3484 ; RV32-NEXT: mulhu a0, a3, a0
3485 ; RV32-NEXT: snez a0, a0
3486 ; RV32-NEXT: or a0, a1, a0
3487 ; RV32-NEXT: or a0, a0, a6
3488 ; RV32-NEXT: beqz a0, .LBB62_2
3489 ; RV32-NEXT: # %bb.1: # %overflow
3490 ; RV32-NEXT: mv a0, zero
3492 ; RV32-NEXT: .LBB62_2: # %continue
3493 ; RV32-NEXT: addi a0, zero, 1
3496 ; RV64-LABEL: umulo.br.i64:
3497 ; RV64: # %bb.0: # %entry
3498 ; RV64-NEXT: mulhu a0, a0, a1
3499 ; RV64-NEXT: beqz a0, .LBB62_2
3500 ; RV64-NEXT: # %bb.1: # %overflow
3501 ; RV64-NEXT: mv a0, zero
3503 ; RV64-NEXT: .LBB62_2: # %continue
3504 ; RV64-NEXT: addi a0, zero, 1
3507 ; RV32ZBA-LABEL: umulo.br.i64:
3508 ; RV32ZBA: # %bb.0: # %entry
3509 ; RV32ZBA-NEXT: mul a4, a3, a0
3510 ; RV32ZBA-NEXT: mul a5, a1, a2
3511 ; RV32ZBA-NEXT: add a4, a5, a4
3512 ; RV32ZBA-NEXT: mulhu a5, a0, a2
3513 ; RV32ZBA-NEXT: add a4, a5, a4
3514 ; RV32ZBA-NEXT: sltu a6, a4, a5
3515 ; RV32ZBA-NEXT: snez a5, a3
3516 ; RV32ZBA-NEXT: snez a4, a1
3517 ; RV32ZBA-NEXT: and a4, a4, a5
3518 ; RV32ZBA-NEXT: mulhu a1, a1, a2
3519 ; RV32ZBA-NEXT: snez a1, a1
3520 ; RV32ZBA-NEXT: or a1, a4, a1
3521 ; RV32ZBA-NEXT: mulhu a0, a3, a0
3522 ; RV32ZBA-NEXT: snez a0, a0
3523 ; RV32ZBA-NEXT: or a0, a1, a0
3524 ; RV32ZBA-NEXT: or a0, a0, a6
3525 ; RV32ZBA-NEXT: beqz a0, .LBB62_2
3526 ; RV32ZBA-NEXT: # %bb.1: # %overflow
3527 ; RV32ZBA-NEXT: mv a0, zero
3529 ; RV32ZBA-NEXT: .LBB62_2: # %continue
3530 ; RV32ZBA-NEXT: addi a0, zero, 1
3533 ; RV64ZBA-LABEL: umulo.br.i64:
3534 ; RV64ZBA: # %bb.0: # %entry
3535 ; RV64ZBA-NEXT: mulhu a0, a0, a1
3536 ; RV64ZBA-NEXT: beqz a0, .LBB62_2
3537 ; RV64ZBA-NEXT: # %bb.1: # %overflow
3538 ; RV64ZBA-NEXT: mv a0, zero
3540 ; RV64ZBA-NEXT: .LBB62_2: # %continue
3541 ; RV64ZBA-NEXT: addi a0, zero, 1
3544 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
3545 %val = extractvalue {i64, i1} %t, 0
3546 %obit = extractvalue {i64, i1} %t, 1
3547 br i1 %obit, label %overflow, label %continue
3556 define zeroext i1 @umulo2.br.i64(i64 %v1) {
3557 ; RV32-LABEL: umulo2.br.i64:
3558 ; RV32: # %bb.0: # %entry
3559 ; RV32-NEXT: add a2, a0, a0
3560 ; RV32-NEXT: sltu a0, a2, a0
3561 ; RV32-NEXT: add a2, a1, a1
3562 ; RV32-NEXT: add a2, a2, a0
3563 ; RV32-NEXT: beq a2, a1, .LBB63_2
3564 ; RV32-NEXT: # %bb.1: # %entry
3565 ; RV32-NEXT: sltu a0, a2, a1
3566 ; RV32-NEXT: .LBB63_2: # %entry
3567 ; RV32-NEXT: beqz a0, .LBB63_4
3568 ; RV32-NEXT: # %bb.3: # %overflow
3569 ; RV32-NEXT: mv a0, zero
3571 ; RV32-NEXT: .LBB63_4: # %continue
3572 ; RV32-NEXT: addi a0, zero, 1
3575 ; RV64-LABEL: umulo2.br.i64:
3576 ; RV64: # %bb.0: # %entry
3577 ; RV64-NEXT: add a1, a0, a0
3578 ; RV64-NEXT: bgeu a1, a0, .LBB63_2
3579 ; RV64-NEXT: # %bb.1: # %overflow
3580 ; RV64-NEXT: mv a0, zero
3582 ; RV64-NEXT: .LBB63_2: # %continue
3583 ; RV64-NEXT: addi a0, zero, 1
3586 ; RV32ZBA-LABEL: umulo2.br.i64:
3587 ; RV32ZBA: # %bb.0: # %entry
3588 ; RV32ZBA-NEXT: add a2, a0, a0
3589 ; RV32ZBA-NEXT: sltu a0, a2, a0
3590 ; RV32ZBA-NEXT: add a2, a1, a1
3591 ; RV32ZBA-NEXT: add a2, a2, a0
3592 ; RV32ZBA-NEXT: beq a2, a1, .LBB63_2
3593 ; RV32ZBA-NEXT: # %bb.1: # %entry
3594 ; RV32ZBA-NEXT: sltu a0, a2, a1
3595 ; RV32ZBA-NEXT: .LBB63_2: # %entry
3596 ; RV32ZBA-NEXT: beqz a0, .LBB63_4
3597 ; RV32ZBA-NEXT: # %bb.3: # %overflow
3598 ; RV32ZBA-NEXT: mv a0, zero
3600 ; RV32ZBA-NEXT: .LBB63_4: # %continue
3601 ; RV32ZBA-NEXT: addi a0, zero, 1
3604 ; RV64ZBA-LABEL: umulo2.br.i64:
3605 ; RV64ZBA: # %bb.0: # %entry
3606 ; RV64ZBA-NEXT: add a1, a0, a0
3607 ; RV64ZBA-NEXT: bgeu a1, a0, .LBB63_2
3608 ; RV64ZBA-NEXT: # %bb.1: # %overflow
3609 ; RV64ZBA-NEXT: mv a0, zero
3611 ; RV64ZBA-NEXT: .LBB63_2: # %continue
3612 ; RV64ZBA-NEXT: addi a0, zero, 1
3615 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 2)
3616 %val = extractvalue {i64, i1} %t, 0
3617 %obit = extractvalue {i64, i1} %t, 1
3618 br i1 %obit, label %overflow, label %continue
3627 declare {i32, i1} @llvm.sadd.with.overflow.i32(i32, i32) nounwind readnone
3628 declare {i64, i1} @llvm.sadd.with.overflow.i64(i64, i64) nounwind readnone
3629 declare {i32, i1} @llvm.uadd.with.overflow.i32(i32, i32) nounwind readnone
3630 declare {i64, i1} @llvm.uadd.with.overflow.i64(i64, i64) nounwind readnone
3631 declare {i32, i1} @llvm.ssub.with.overflow.i32(i32, i32) nounwind readnone
3632 declare {i64, i1} @llvm.ssub.with.overflow.i64(i64, i64) nounwind readnone
3633 declare {i32, i1} @llvm.usub.with.overflow.i32(i32, i32) nounwind readnone
3634 declare {i64, i1} @llvm.usub.with.overflow.i64(i64, i64) nounwind readnone
3635 declare {i32, i1} @llvm.smul.with.overflow.i32(i32, i32) nounwind readnone
3636 declare {i64, i1} @llvm.smul.with.overflow.i64(i64, i64) nounwind readnone
3637 declare {i32, i1} @llvm.umul.with.overflow.i32(i32, i32) nounwind readnone
3638 declare {i64, i1} @llvm.umul.with.overflow.i64(i64, i64) nounwind readnone