[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / CodeGen / RISCV / xaluo.ll
blob2695508b40ae5c373411d48f025a123c4c22c40b
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)
18 ; RV32-NEXT:    ret
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)
29 ; RV64-NEXT:    ret
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)
38 ; RV32ZBA-NEXT:    ret
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)
49 ; RV64ZBA-NEXT:    ret
50 entry:
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
55   ret i1 %obit
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)
65 ; RV32-NEXT:    ret
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)
75 ; RV64-NEXT:    ret
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)
82 ; RV32ZBA-NEXT:    ret
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)
92 ; RV64ZBA-NEXT:    ret
93 entry:
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
98   ret i1 %obit
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)
109 ; RV32-NEXT:    ret
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)
119 ; RV64-NEXT:    ret
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)
127 ; RV32ZBA-NEXT:    ret
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)
137 ; RV64ZBA-NEXT:    ret
138 entry:
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
143   ret i1 %obit
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)
155 ; RV32-NEXT:    ret
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)
167 ; RV64-NEXT:    ret
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)
176 ; RV32ZBA-NEXT:    ret
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)
188 ; RV64ZBA-NEXT:    ret
189 entry:
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
194   ret i1 %obit
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)
211 ; RV32-NEXT:    ret
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)
220 ; RV64-NEXT:    ret
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)
235 ; RV32ZBA-NEXT:    ret
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)
244 ; RV64ZBA-NEXT:    ret
245 entry:
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
250   ret i1 %obit
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)
265 ; RV32-NEXT:    ret
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)
272 ; RV64-NEXT:    ret
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)
285 ; RV32ZBA-NEXT:    ret
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)
292 ; RV64ZBA-NEXT:    ret
293 entry:
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
298   ret i1 %obit
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)
313 ; RV32-NEXT:    ret
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)
321 ; RV64-NEXT:    ret
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)
334 ; RV32ZBA-NEXT:    ret
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)
342 ; RV64ZBA-NEXT:    ret
343 entry:
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
348   ret i1 %obit
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)
357 ; RV32-NEXT:    ret
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)
365 ; RV64-NEXT:    ret
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)
372 ; RV32ZBA-NEXT:    ret
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)
380 ; RV64ZBA-NEXT:    ret
381 entry:
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
386   ret i1 %obit
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)
395 ; RV32-NEXT:    ret
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)
403 ; RV64-NEXT:    ret
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)
410 ; RV32ZBA-NEXT:    ret
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)
418 ; RV64ZBA-NEXT:    ret
419 entry:
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
424   ret i1 %obit
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)
440 ; RV32-NEXT:    ret
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)
447 ; RV64-NEXT:    ret
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)
461 ; RV32ZBA-NEXT:    ret
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)
468 ; RV64ZBA-NEXT:    ret
469 entry:
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
474   ret i1 %obit
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)
485 ; RV32-NEXT:    ret
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)
496 ; RV64-NEXT:    ret
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)
505 ; RV32ZBA-NEXT:    ret
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)
516 ; RV64ZBA-NEXT:    ret
517 entry:
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
522   ret i1 %obit
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)
531 ; RV32-NEXT:    ret
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)
541 ; RV64-NEXT:    ret
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)
548 ; RV32ZBA-NEXT:    ret
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)
558 ; RV64ZBA-NEXT:    ret
559 entry:
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
564   ret i1 %obit
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
581 ; RV32-NEXT:    ret
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)
590 ; RV64-NEXT:    ret
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
605 ; RV32ZBA-NEXT:    ret
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)
614 ; RV64ZBA-NEXT:    ret
615 entry:
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
620   ret i1 %obit
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)
629 ; RV32-NEXT:    ret
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)
637 ; RV64-NEXT:    ret
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)
644 ; RV32ZBA-NEXT:    ret
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)
652 ; RV64ZBA-NEXT:    ret
653 entry:
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
658   ret i1 %obit
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)
667 ; RV32-NEXT:    ret
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)
675 ; RV64-NEXT:    ret
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)
682 ; RV32ZBA-NEXT:    ret
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)
690 ; RV64ZBA-NEXT:    ret
691 entry:
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
696   ret i1 %obit
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)
707 ; RV32-NEXT:    ret
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)
716 ; RV64-NEXT:    ret
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)
725 ; RV32ZBA-NEXT:    ret
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)
734 ; RV64ZBA-NEXT:    ret
735 entry:
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
740   ret i1 %obit
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)
759 ; RV32-NEXT:    ret
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)
766 ; RV64-NEXT:    ret
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)
783 ; RV32ZBA-NEXT:    ret
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)
790 ; RV64ZBA-NEXT:    ret
791 entry:
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
796   ret i1 %obit
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)
808 ; RV32-NEXT:    ret
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)
819 ; RV64-NEXT:    ret
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)
829 ; RV32ZBA-NEXT:    ret
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)
840 ; RV64ZBA-NEXT:    ret
841 entry:
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
846   ret i1 %obit
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)
859 ; RV32-NEXT:    ret
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)
870 ; RV64-NEXT:    ret
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)
881 ; RV32ZBA-NEXT:    ret
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)
892 ; RV64ZBA-NEXT:    ret
893 entry:
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
898   ret i1 %obit
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
922 ; RV32-NEXT:    ret
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)
932 ; RV64-NEXT:    ret
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
954 ; RV32ZBA-NEXT:    ret
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)
964 ; RV64ZBA-NEXT:    ret
965 entry:
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
970   ret i1 %obit
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
996 ; RV32-NEXT:    ret
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)
1007 ; RV64-NEXT:    ret
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
1031 ; RV32ZBA-NEXT:    ret
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)
1042 ; RV64ZBA-NEXT:    ret
1043 entry:
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
1048   ret i1 %obit
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
1059 ; RV32-NEXT:    ret
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)
1069 ; RV64-NEXT:    ret
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
1078 ; RV32ZBA-NEXT:    ret
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)
1088 ; RV64ZBA-NEXT:    ret
1089 entry:
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
1094   ret i1 %obit
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
1106 ; RV32-NEXT:    ret
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)
1117 ; RV64-NEXT:    ret
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
1127 ; RV32ZBA-NEXT:    ret
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)
1137 ; RV64ZBA-NEXT:    ret
1138 entry:
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
1143   ret i1 %obit
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:
1149 ; RV32:       # %bb.0:
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
1155 ; RV32-NEXT:    ret
1157 ; RV64-LABEL: umulo3.i32:
1158 ; RV64:       # %bb.0:
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)
1166 ; RV64-NEXT:    ret
1168 ; RV32ZBA-LABEL: umulo3.i32:
1169 ; RV32ZBA:       # %bb.0:
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
1175 ; RV32ZBA-NEXT:    ret
1177 ; RV64ZBA-LABEL: umulo3.i32:
1178 ; RV64ZBA:       # %bb.0:
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)
1186 ; RV64ZBA-NEXT:    ret
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
1192   ret i32 %6
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
1218 ; RV32-NEXT:    ret
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
1227 ; RV64-NEXT:    ret
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
1251 ; RV32ZBA-NEXT:    ret
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
1260 ; RV64ZBA-NEXT:    ret
1261 entry:
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
1266   ret i1 %obit
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
1284 ; RV32-NEXT:    ret
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
1294 ; RV64-NEXT:    ret
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
1310 ; RV32ZBA-NEXT:    ret
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
1320 ; RV64ZBA-NEXT:    ret
1321 entry:
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
1326   ret i1 %obit
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
1343 ; RV32-NEXT:    ret
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
1355 ; RV64-NEXT:    ret
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
1366 ; RV32ZBA-NEXT:    ret
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
1378 ; RV64ZBA-NEXT:    ret
1379 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
1383   ret i32 %ret
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
1394 ; RV32-NEXT:    ret
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
1404 ; RV64-NEXT:    ret
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
1413 ; RV32ZBA-NEXT:    ret
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
1423 ; RV64ZBA-NEXT:    ret
1424 entry:
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
1428   ret i1 %ret
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
1447 ; RV32-NEXT:    ret
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
1458 ; RV64-NEXT:    ret
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
1475 ; RV32ZBA-NEXT:    ret
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
1486 ; RV64ZBA-NEXT:    ret
1487 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
1491   ret i64 %ret
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
1507 ; RV32-NEXT:    ret
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
1516 ; RV64-NEXT:    ret
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
1530 ; RV32ZBA-NEXT:    ret
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
1539 ; RV64ZBA-NEXT:    ret
1540 entry:
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
1544   ret i1 %ret
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
1555 ; RV32-NEXT:    ret
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
1565 ; RV64-NEXT:    ret
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
1574 ; RV32ZBA-NEXT:    ret
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
1584 ; RV64ZBA-NEXT:    ret
1585 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
1589   ret i32 %ret
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
1598 ; RV32-NEXT:    ret
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
1606 ; RV64-NEXT:    ret
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
1613 ; RV32ZBA-NEXT:    ret
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
1621 ; RV64ZBA-NEXT:    ret
1622 entry:
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
1626   ret i1 %ret
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
1640 ; RV32-NEXT:    ret
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
1647 ; RV32-NEXT:    ret
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
1656 ; RV64-NEXT:    ret
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
1668 ; RV32ZBA-NEXT:    ret
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
1675 ; RV32ZBA-NEXT:    ret
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
1684 ; RV64ZBA-NEXT:    ret
1685 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
1689   ret i64 %ret
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
1704 ; RV32-NEXT:    ret
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
1711 ; RV64-NEXT:    ret
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
1724 ; RV32ZBA-NEXT:    ret
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
1731 ; RV64ZBA-NEXT:    ret
1732 entry:
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
1736   ret i1 %ret
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
1749 ; RV32-NEXT:    ret
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
1761 ; RV64-NEXT:    ret
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
1772 ; RV32ZBA-NEXT:    ret
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
1784 ; RV64ZBA-NEXT:    ret
1785 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
1789   ret i32 %ret
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
1800 ; RV32-NEXT:    ret
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
1810 ; RV64-NEXT:    ret
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
1819 ; RV32ZBA-NEXT:    ret
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
1829 ; RV64ZBA-NEXT:    ret
1830 entry:
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
1834   ret i1 %ret
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
1851 ; RV32-NEXT:    ret
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
1862 ; RV64-NEXT:    ret
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
1877 ; RV32ZBA-NEXT:    ret
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
1888 ; RV64ZBA-NEXT:    ret
1889 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
1893   ret i64 %ret
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
1907 ; RV32-NEXT:    ret
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
1916 ; RV64-NEXT:    ret
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
1928 ; RV32ZBA-NEXT:    ret
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
1937 ; RV64ZBA-NEXT:    ret
1938 entry:
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
1942   ret i1 %ret
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
1953 ; RV32-NEXT:    ret
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
1963 ; RV64-NEXT:    ret
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
1972 ; RV32ZBA-NEXT:    ret
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
1982 ; RV64ZBA-NEXT:    ret
1983 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
1987   ret i32 %ret
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
1996 ; RV32-NEXT:    ret
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
2004 ; RV64-NEXT:    ret
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
2011 ; RV32ZBA-NEXT:    ret
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
2019 ; RV64ZBA-NEXT:    ret
2020 entry:
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
2024   ret i1 %ret
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
2046 ; RV32-NEXT:    ret
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
2055 ; RV64-NEXT:    ret
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
2075 ; RV32ZBA-NEXT:    ret
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
2084 ; RV64ZBA-NEXT:    ret
2085 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
2089   ret i64 %ret
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
2102 ; RV32-NEXT:    ret
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
2107 ; RV32-NEXT:    ret
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
2114 ; RV64-NEXT:    ret
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
2125 ; RV32ZBA-NEXT:    ret
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
2130 ; RV32ZBA-NEXT:    ret
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
2137 ; RV64ZBA-NEXT:    ret
2138 entry:
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
2142   ret i1 %ret
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
2155 ; RV32-NEXT:    ret
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
2167 ; RV64-NEXT:    ret
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
2178 ; RV32ZBA-NEXT:    ret
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
2190 ; RV64ZBA-NEXT:    ret
2191 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
2195   ret i32 %ret
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
2206 ; RV32-NEXT:    ret
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
2216 ; RV64-NEXT:    ret
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
2225 ; RV32ZBA-NEXT:    ret
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
2235 ; RV64ZBA-NEXT:    ret
2236 entry:
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
2240   ret i1 %ret
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
2279 ; RV32-NEXT:    ret
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
2290 ; RV64-NEXT:    ret
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
2327 ; RV32ZBA-NEXT:    ret
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
2338 ; RV64ZBA-NEXT:    ret
2339 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
2343   ret i64 %ret
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
2360 ; RV32-NEXT:    ret
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
2369 ; RV64-NEXT:    ret
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
2384 ; RV32ZBA-NEXT:    ret
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
2393 ; RV64ZBA-NEXT:    ret
2394 entry:
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
2398   ret i1 %ret
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
2409 ; RV32-NEXT:    ret
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
2421 ; RV64-NEXT:    ret
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
2430 ; RV32ZBA-NEXT:    ret
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
2442 ; RV64ZBA-NEXT:    ret
2443 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
2447   ret i32 %ret
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
2455 ; RV32-NEXT:    ret
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
2464 ; RV64-NEXT:    ret
2466 ; RV32ZBA-LABEL: umulo.not.i32:
2467 ; RV32ZBA:       # %bb.0: # %entry
2468 ; RV32ZBA-NEXT:    mulhu a0, a0, a1
2469 ; RV32ZBA-NEXT:    seqz a0, a0
2470 ; RV32ZBA-NEXT:    ret
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
2479 ; RV64ZBA-NEXT:    ret
2480 entry:
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
2484   ret i1 %ret
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
2511 ; RV32-NEXT:    ret
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
2520 ; RV64-NEXT:    ret
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
2545 ; RV32ZBA-NEXT:    ret
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
2554 ; RV64ZBA-NEXT:    ret
2555 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
2559   ret i64 %ret
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
2582 ; RV32-NEXT:    ret
2584 ; RV64-LABEL: umulo.not.i64:
2585 ; RV64:       # %bb.0: # %entry
2586 ; RV64-NEXT:    mulhu a0, a0, a1
2587 ; RV64-NEXT:    seqz a0, a0
2588 ; RV64-NEXT:    ret
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
2609 ; RV32ZBA-NEXT:    ret
2611 ; RV64ZBA-LABEL: umulo.not.i64:
2612 ; RV64ZBA:       # %bb.0: # %entry
2613 ; RV64ZBA-NEXT:    mulhu a0, a0, a1
2614 ; RV64ZBA-NEXT:    seqz a0, a0
2615 ; RV64ZBA-NEXT:    ret
2616 entry:
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
2620   ret i1 %ret
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
2636 ; RV32-NEXT:    ret
2637 ; RV32-NEXT:  .LBB50_2: # %continue
2638 ; RV32-NEXT:    addi a0, zero, 1
2639 ; RV32-NEXT:    ret
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
2650 ; RV64-NEXT:    ret
2651 ; RV64-NEXT:  .LBB50_2: # %continue
2652 ; RV64-NEXT:    addi a0, zero, 1
2653 ; RV64-NEXT:    ret
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
2663 ; RV32ZBA-NEXT:    ret
2664 ; RV32ZBA-NEXT:  .LBB50_2: # %continue
2665 ; RV32ZBA-NEXT:    addi a0, zero, 1
2666 ; RV32ZBA-NEXT:    ret
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
2677 ; RV64ZBA-NEXT:    ret
2678 ; RV64ZBA-NEXT:  .LBB50_2: # %continue
2679 ; RV64ZBA-NEXT:    addi a0, zero, 1
2680 ; RV64ZBA-NEXT:    ret
2681 entry:
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
2687 overflow:
2688   ret i1 false
2690 continue:
2691   ret i1 true
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
2708 ; RV32-NEXT:    ret
2709 ; RV32-NEXT:  .LBB51_2: # %continue
2710 ; RV32-NEXT:    addi a0, zero, 1
2711 ; RV32-NEXT:    ret
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
2721 ; RV64-NEXT:    ret
2722 ; RV64-NEXT:  .LBB51_2: # %continue
2723 ; RV64-NEXT:    addi a0, zero, 1
2724 ; RV64-NEXT:    ret
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
2739 ; RV32ZBA-NEXT:    ret
2740 ; RV32ZBA-NEXT:  .LBB51_2: # %continue
2741 ; RV32ZBA-NEXT:    addi a0, zero, 1
2742 ; RV32ZBA-NEXT:    ret
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
2752 ; RV64ZBA-NEXT:    ret
2753 ; RV64ZBA-NEXT:  .LBB51_2: # %continue
2754 ; RV64ZBA-NEXT:    addi a0, zero, 1
2755 ; RV64ZBA-NEXT:    ret
2756 entry:
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
2762 overflow:
2763   ret i1 false
2765 continue:
2766   ret i1 true
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
2776 ; RV32-NEXT:    ret
2777 ; RV32-NEXT:  .LBB52_2: # %continue
2778 ; RV32-NEXT:    addi a0, zero, 1
2779 ; RV32-NEXT:    ret
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
2788 ; RV64-NEXT:    ret
2789 ; RV64-NEXT:  .LBB52_2: # %continue
2790 ; RV64-NEXT:    addi a0, zero, 1
2791 ; RV64-NEXT:    ret
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
2799 ; RV32ZBA-NEXT:    ret
2800 ; RV32ZBA-NEXT:  .LBB52_2: # %continue
2801 ; RV32ZBA-NEXT:    addi a0, zero, 1
2802 ; RV32ZBA-NEXT:    ret
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
2811 ; RV64ZBA-NEXT:    ret
2812 ; RV64ZBA-NEXT:  .LBB52_2: # %continue
2813 ; RV64ZBA-NEXT:    addi a0, zero, 1
2814 ; RV64ZBA-NEXT:    ret
2815 entry:
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
2821 overflow:
2822   ret i1 false
2824 continue:
2825   ret i1 true
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
2842 ; RV32-NEXT:    ret
2843 ; RV32-NEXT:  .LBB53_4: # %continue
2844 ; RV32-NEXT:    addi a0, zero, 1
2845 ; RV32-NEXT:    ret
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
2853 ; RV64-NEXT:    ret
2854 ; RV64-NEXT:  .LBB53_2: # %continue
2855 ; RV64-NEXT:    addi a0, zero, 1
2856 ; RV64-NEXT:    ret
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
2871 ; RV32ZBA-NEXT:    ret
2872 ; RV32ZBA-NEXT:  .LBB53_4: # %continue
2873 ; RV32ZBA-NEXT:    addi a0, zero, 1
2874 ; RV32ZBA-NEXT:    ret
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
2882 ; RV64ZBA-NEXT:    ret
2883 ; RV64ZBA-NEXT:  .LBB53_2: # %continue
2884 ; RV64ZBA-NEXT:    addi a0, zero, 1
2885 ; RV64ZBA-NEXT:    ret
2886 entry:
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
2892 overflow:
2893   ret i1 false
2895 continue:
2896   ret i1 true
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
2908 ; RV32-NEXT:    ret
2909 ; RV32-NEXT:  .LBB54_2: # %continue
2910 ; RV32-NEXT:    addi a0, zero, 1
2911 ; RV32-NEXT:    ret
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
2922 ; RV64-NEXT:    ret
2923 ; RV64-NEXT:  .LBB54_2: # %continue
2924 ; RV64-NEXT:    addi a0, zero, 1
2925 ; RV64-NEXT:    ret
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
2935 ; RV32ZBA-NEXT:    ret
2936 ; RV32ZBA-NEXT:  .LBB54_2: # %continue
2937 ; RV32ZBA-NEXT:    addi a0, zero, 1
2938 ; RV32ZBA-NEXT:    ret
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
2949 ; RV64ZBA-NEXT:    ret
2950 ; RV64ZBA-NEXT:  .LBB54_2: # %continue
2951 ; RV64ZBA-NEXT:    addi a0, zero, 1
2952 ; RV64ZBA-NEXT:    ret
2953 entry:
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
2959 overflow:
2960   ret i1 false
2962 continue:
2963   ret i1 true
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
2978 ; RV32-NEXT:    ret
2979 ; RV32-NEXT:  .LBB55_2: # %continue
2980 ; RV32-NEXT:    addi a0, zero, 1
2981 ; RV32-NEXT:    ret
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
2991 ; RV64-NEXT:    ret
2992 ; RV64-NEXT:  .LBB55_2: # %continue
2993 ; RV64-NEXT:    addi a0, zero, 1
2994 ; RV64-NEXT:    ret
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
3007 ; RV32ZBA-NEXT:    ret
3008 ; RV32ZBA-NEXT:  .LBB55_2: # %continue
3009 ; RV32ZBA-NEXT:    addi a0, zero, 1
3010 ; RV32ZBA-NEXT:    ret
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
3020 ; RV64ZBA-NEXT:    ret
3021 ; RV64ZBA-NEXT:  .LBB55_2: # %continue
3022 ; RV64ZBA-NEXT:    addi a0, zero, 1
3023 ; RV64ZBA-NEXT:    ret
3024 entry:
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
3030 overflow:
3031   ret i1 false
3033 continue:
3034   ret i1 true
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
3044 ; RV32-NEXT:    ret
3045 ; RV32-NEXT:  .LBB56_2: # %continue
3046 ; RV32-NEXT:    addi a0, zero, 1
3047 ; RV32-NEXT:    ret
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
3056 ; RV64-NEXT:    ret
3057 ; RV64-NEXT:  .LBB56_2: # %continue
3058 ; RV64-NEXT:    addi a0, zero, 1
3059 ; RV64-NEXT:    ret
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
3067 ; RV32ZBA-NEXT:    ret
3068 ; RV32ZBA-NEXT:  .LBB56_2: # %continue
3069 ; RV32ZBA-NEXT:    addi a0, zero, 1
3070 ; RV32ZBA-NEXT:    ret
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
3079 ; RV64ZBA-NEXT:    ret
3080 ; RV64ZBA-NEXT:  .LBB56_2: # %continue
3081 ; RV64ZBA-NEXT:    addi a0, zero, 1
3082 ; RV64ZBA-NEXT:    ret
3083 entry:
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
3089 overflow:
3090   ret i1 false
3092 continue:
3093   ret i1 true
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
3108 ; RV32-NEXT:    ret
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
3115 ; RV32-NEXT:    ret
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
3123 ; RV64-NEXT:    ret
3124 ; RV64-NEXT:  .LBB57_2: # %continue
3125 ; RV64-NEXT:    addi a0, zero, 1
3126 ; RV64-NEXT:    ret
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
3139 ; RV32ZBA-NEXT:    ret
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
3146 ; RV32ZBA-NEXT:    ret
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
3154 ; RV64ZBA-NEXT:    ret
3155 ; RV64ZBA-NEXT:  .LBB57_2: # %continue
3156 ; RV64ZBA-NEXT:    addi a0, zero, 1
3157 ; RV64ZBA-NEXT:    ret
3158 entry:
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
3164 overflow:
3165   ret i1 false
3167 continue:
3168   ret i1 true
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
3180 ; RV32-NEXT:    ret
3181 ; RV32-NEXT:  .LBB58_2: # %continue
3182 ; RV32-NEXT:    addi a0, zero, 1
3183 ; RV32-NEXT:    ret
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
3194 ; RV64-NEXT:    ret
3195 ; RV64-NEXT:  .LBB58_2: # %continue
3196 ; RV64-NEXT:    addi a0, zero, 1
3197 ; RV64-NEXT:    ret
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
3207 ; RV32ZBA-NEXT:    ret
3208 ; RV32ZBA-NEXT:  .LBB58_2: # %continue
3209 ; RV32ZBA-NEXT:    addi a0, zero, 1
3210 ; RV32ZBA-NEXT:    ret
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
3221 ; RV64ZBA-NEXT:    ret
3222 ; RV64ZBA-NEXT:  .LBB58_2: # %continue
3223 ; RV64ZBA-NEXT:    addi a0, zero, 1
3224 ; RV64ZBA-NEXT:    ret
3225 entry:
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
3231 overflow:
3232   ret i1 false
3234 continue:
3235   ret i1 true
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
3258 ; RV32-NEXT:    ret
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
3268 ; RV64-NEXT:    ret
3269 ; RV64-NEXT:  .LBB59_2: # %continue
3270 ; RV64-NEXT:    addi a0, zero, 1
3271 ; RV64-NEXT:    ret
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
3292 ; RV32ZBA-NEXT:    ret
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
3302 ; RV64ZBA-NEXT:    ret
3303 ; RV64ZBA-NEXT:  .LBB59_2: # %continue
3304 ; RV64ZBA-NEXT:    addi a0, zero, 1
3305 ; RV64ZBA-NEXT:    ret
3306 entry:
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
3312 overflow:
3313   ret i1 false
3315 continue:
3316   ret i1 true
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
3341 ; RV32-NEXT:    ret
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
3352 ; RV64-NEXT:    ret
3353 ; RV64-NEXT:  .LBB60_2: # %continue
3354 ; RV64-NEXT:    addi a0, zero, 1
3355 ; RV64-NEXT:    ret
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
3378 ; RV32ZBA-NEXT:    ret
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
3389 ; RV64ZBA-NEXT:    ret
3390 ; RV64ZBA-NEXT:  .LBB60_2: # %continue
3391 ; RV64ZBA-NEXT:    addi a0, zero, 1
3392 ; RV64ZBA-NEXT:    ret
3393 entry:
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
3399 overflow:
3400   ret i1 false
3402 continue:
3403   ret i1 true
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
3413 ; RV32-NEXT:    ret
3414 ; RV32-NEXT:  .LBB61_2: # %continue
3415 ; RV32-NEXT:    addi a0, zero, 1
3416 ; RV32-NEXT:    ret
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
3427 ; RV64-NEXT:    ret
3428 ; RV64-NEXT:  .LBB61_2: # %continue
3429 ; RV64-NEXT:    addi a0, zero, 1
3430 ; RV64-NEXT:    ret
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
3438 ; RV32ZBA-NEXT:    ret
3439 ; RV32ZBA-NEXT:  .LBB61_2: # %continue
3440 ; RV32ZBA-NEXT:    addi a0, zero, 1
3441 ; RV32ZBA-NEXT:    ret
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
3452 ; RV64ZBA-NEXT:    ret
3453 ; RV64ZBA-NEXT:  .LBB61_2: # %continue
3454 ; RV64ZBA-NEXT:    addi a0, zero, 1
3455 ; RV64ZBA-NEXT:    ret
3456 entry:
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
3462 overflow:
3463   ret i1 false
3465 continue:
3466   ret i1 true
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
3491 ; RV32-NEXT:    ret
3492 ; RV32-NEXT:  .LBB62_2: # %continue
3493 ; RV32-NEXT:    addi a0, zero, 1
3494 ; RV32-NEXT:    ret
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
3502 ; RV64-NEXT:    ret
3503 ; RV64-NEXT:  .LBB62_2: # %continue
3504 ; RV64-NEXT:    addi a0, zero, 1
3505 ; RV64-NEXT:    ret
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
3528 ; RV32ZBA-NEXT:    ret
3529 ; RV32ZBA-NEXT:  .LBB62_2: # %continue
3530 ; RV32ZBA-NEXT:    addi a0, zero, 1
3531 ; RV32ZBA-NEXT:    ret
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
3539 ; RV64ZBA-NEXT:    ret
3540 ; RV64ZBA-NEXT:  .LBB62_2: # %continue
3541 ; RV64ZBA-NEXT:    addi a0, zero, 1
3542 ; RV64ZBA-NEXT:    ret
3543 entry:
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
3549 overflow:
3550   ret i1 false
3552 continue:
3553   ret i1 true
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
3570 ; RV32-NEXT:    ret
3571 ; RV32-NEXT:  .LBB63_4: # %continue
3572 ; RV32-NEXT:    addi a0, zero, 1
3573 ; RV32-NEXT:    ret
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
3581 ; RV64-NEXT:    ret
3582 ; RV64-NEXT:  .LBB63_2: # %continue
3583 ; RV64-NEXT:    addi a0, zero, 1
3584 ; RV64-NEXT:    ret
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
3599 ; RV32ZBA-NEXT:    ret
3600 ; RV32ZBA-NEXT:  .LBB63_4: # %continue
3601 ; RV32ZBA-NEXT:    addi a0, zero, 1
3602 ; RV32ZBA-NEXT:    ret
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
3610 ; RV64ZBA-NEXT:    ret
3611 ; RV64ZBA-NEXT:  .LBB63_2: # %continue
3612 ; RV64ZBA-NEXT:    addi a0, zero, 1
3613 ; RV64ZBA-NEXT:    ret
3614 entry:
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
3620 overflow:
3621   ret i1 false
3623 continue:
3624   ret i1 true
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