xref: /llvm-project/llvm/test/CodeGen/RISCV/xaluo.ll (revision e30a4fc3e20bf5d9cc2f5bfcb61b4eb0e686a193)
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,+zba -verify-machineinstrs | FileCheck %s --check-prefix=RV32ZBA
5; RUN: llc < %s -mtriple=riscv64 -mattr=+m,+zba -verify-machineinstrs | FileCheck %s --check-prefix=RV64ZBA
6; RUN: llc < %s -mtriple=riscv32 -mattr=+m,+zicond -verify-machineinstrs | FileCheck %s --check-prefix=RV32ZICOND
7; RUN: llc < %s -mtriple=riscv64 -mattr=+m,+zicond -verify-machineinstrs | FileCheck %s --check-prefix=RV64ZICOND
8
9;
10; Get the actual value of the overflow bit.
11;
12define zeroext i1 @saddo1.i32(i32 signext %v1, i32 signext %v2, ptr %res) {
13; RV32-LABEL: saddo1.i32:
14; RV32:       # %bb.0: # %entry
15; RV32-NEXT:    add a3, a0, a1
16; RV32-NEXT:    slt a0, a3, a0
17; RV32-NEXT:    slti a1, a1, 0
18; RV32-NEXT:    xor a0, a1, a0
19; RV32-NEXT:    sw a3, 0(a2)
20; RV32-NEXT:    ret
21;
22; RV64-LABEL: saddo1.i32:
23; RV64:       # %bb.0: # %entry
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
30;
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
39;
40; RV64ZBA-LABEL: saddo1.i32:
41; RV64ZBA:       # %bb.0: # %entry
42; RV64ZBA-NEXT:    add a3, a0, a1
43; RV64ZBA-NEXT:    addw a0, a0, a1
44; RV64ZBA-NEXT:    xor a0, a0, a3
45; RV64ZBA-NEXT:    snez a0, a0
46; RV64ZBA-NEXT:    sw a3, 0(a2)
47; RV64ZBA-NEXT:    ret
48;
49; RV32ZICOND-LABEL: saddo1.i32:
50; RV32ZICOND:       # %bb.0: # %entry
51; RV32ZICOND-NEXT:    add a3, a0, a1
52; RV32ZICOND-NEXT:    slt a0, a3, a0
53; RV32ZICOND-NEXT:    slti a1, a1, 0
54; RV32ZICOND-NEXT:    xor a0, a1, a0
55; RV32ZICOND-NEXT:    sw a3, 0(a2)
56; RV32ZICOND-NEXT:    ret
57;
58; RV64ZICOND-LABEL: saddo1.i32:
59; RV64ZICOND:       # %bb.0: # %entry
60; RV64ZICOND-NEXT:    add a3, a0, a1
61; RV64ZICOND-NEXT:    addw a0, a0, a1
62; RV64ZICOND-NEXT:    xor a0, a0, a3
63; RV64ZICOND-NEXT:    snez a0, a0
64; RV64ZICOND-NEXT:    sw a3, 0(a2)
65; RV64ZICOND-NEXT:    ret
66entry:
67  %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2)
68  %val = extractvalue {i32, i1} %t, 0
69  %obit = extractvalue {i32, i1} %t, 1
70  store i32 %val, ptr %res
71  ret i1 %obit
72}
73
74; Test the immediate version.
75define zeroext i1 @saddo2.i32(i32 signext %v1, ptr %res) {
76; RV32-LABEL: saddo2.i32:
77; RV32:       # %bb.0: # %entry
78; RV32-NEXT:    addi a2, a0, 4
79; RV32-NEXT:    slt a0, a2, a0
80; RV32-NEXT:    sw a2, 0(a1)
81; RV32-NEXT:    ret
82;
83; RV64-LABEL: saddo2.i32:
84; RV64:       # %bb.0: # %entry
85; RV64-NEXT:    addiw a2, a0, 4
86; RV64-NEXT:    slt a0, a2, a0
87; RV64-NEXT:    sw a2, 0(a1)
88; RV64-NEXT:    ret
89;
90; RV32ZBA-LABEL: saddo2.i32:
91; RV32ZBA:       # %bb.0: # %entry
92; RV32ZBA-NEXT:    addi a2, a0, 4
93; RV32ZBA-NEXT:    slt a0, a2, a0
94; RV32ZBA-NEXT:    sw a2, 0(a1)
95; RV32ZBA-NEXT:    ret
96;
97; RV64ZBA-LABEL: saddo2.i32:
98; RV64ZBA:       # %bb.0: # %entry
99; RV64ZBA-NEXT:    addiw a2, a0, 4
100; RV64ZBA-NEXT:    slt a0, a2, a0
101; RV64ZBA-NEXT:    sw a2, 0(a1)
102; RV64ZBA-NEXT:    ret
103;
104; RV32ZICOND-LABEL: saddo2.i32:
105; RV32ZICOND:       # %bb.0: # %entry
106; RV32ZICOND-NEXT:    addi a2, a0, 4
107; RV32ZICOND-NEXT:    slt a0, a2, a0
108; RV32ZICOND-NEXT:    sw a2, 0(a1)
109; RV32ZICOND-NEXT:    ret
110;
111; RV64ZICOND-LABEL: saddo2.i32:
112; RV64ZICOND:       # %bb.0: # %entry
113; RV64ZICOND-NEXT:    addiw a2, a0, 4
114; RV64ZICOND-NEXT:    slt a0, a2, a0
115; RV64ZICOND-NEXT:    sw a2, 0(a1)
116; RV64ZICOND-NEXT:    ret
117entry:
118  %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 4)
119  %val = extractvalue {i32, i1} %t, 0
120  %obit = extractvalue {i32, i1} %t, 1
121  store i32 %val, ptr %res
122  ret i1 %obit
123}
124
125; Test negative immediates.
126define zeroext i1 @saddo3.i32(i32 signext %v1, ptr %res) {
127; RV32-LABEL: saddo3.i32:
128; RV32:       # %bb.0: # %entry
129; RV32-NEXT:    addi a2, a0, -4
130; RV32-NEXT:    slt a0, a2, a0
131; RV32-NEXT:    xori a0, a0, 1
132; RV32-NEXT:    sw a2, 0(a1)
133; RV32-NEXT:    ret
134;
135; RV64-LABEL: saddo3.i32:
136; RV64:       # %bb.0: # %entry
137; RV64-NEXT:    addiw a2, a0, -4
138; RV64-NEXT:    slt a0, a2, a0
139; RV64-NEXT:    xori a0, a0, 1
140; RV64-NEXT:    sw a2, 0(a1)
141; RV64-NEXT:    ret
142;
143; RV32ZBA-LABEL: saddo3.i32:
144; RV32ZBA:       # %bb.0: # %entry
145; RV32ZBA-NEXT:    addi a2, a0, -4
146; RV32ZBA-NEXT:    slt a0, a2, a0
147; RV32ZBA-NEXT:    xori a0, a0, 1
148; RV32ZBA-NEXT:    sw a2, 0(a1)
149; RV32ZBA-NEXT:    ret
150;
151; RV64ZBA-LABEL: saddo3.i32:
152; RV64ZBA:       # %bb.0: # %entry
153; RV64ZBA-NEXT:    addiw a2, a0, -4
154; RV64ZBA-NEXT:    slt a0, a2, a0
155; RV64ZBA-NEXT:    xori a0, a0, 1
156; RV64ZBA-NEXT:    sw a2, 0(a1)
157; RV64ZBA-NEXT:    ret
158;
159; RV32ZICOND-LABEL: saddo3.i32:
160; RV32ZICOND:       # %bb.0: # %entry
161; RV32ZICOND-NEXT:    addi a2, a0, -4
162; RV32ZICOND-NEXT:    slt a0, a2, a0
163; RV32ZICOND-NEXT:    xori a0, a0, 1
164; RV32ZICOND-NEXT:    sw a2, 0(a1)
165; RV32ZICOND-NEXT:    ret
166;
167; RV64ZICOND-LABEL: saddo3.i32:
168; RV64ZICOND:       # %bb.0: # %entry
169; RV64ZICOND-NEXT:    addiw a2, a0, -4
170; RV64ZICOND-NEXT:    slt a0, a2, a0
171; RV64ZICOND-NEXT:    xori a0, a0, 1
172; RV64ZICOND-NEXT:    sw a2, 0(a1)
173; RV64ZICOND-NEXT:    ret
174entry:
175  %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 -4)
176  %val = extractvalue {i32, i1} %t, 0
177  %obit = extractvalue {i32, i1} %t, 1
178  store i32 %val, ptr %res
179  ret i1 %obit
180}
181
182; Test immediates that are too large to be encoded.
183define zeroext i1 @saddo4.i32(i32 signext %v1, ptr %res) {
184; RV32-LABEL: saddo4.i32:
185; RV32:       # %bb.0: # %entry
186; RV32-NEXT:    lui a2, 4096
187; RV32-NEXT:    addi a2, a2, -1
188; RV32-NEXT:    add a2, a0, a2
189; RV32-NEXT:    slt a0, a2, a0
190; RV32-NEXT:    sw a2, 0(a1)
191; RV32-NEXT:    ret
192;
193; RV64-LABEL: saddo4.i32:
194; RV64:       # %bb.0: # %entry
195; RV64-NEXT:    lui a2, 4096
196; RV64-NEXT:    addi a2, a2, -1
197; RV64-NEXT:    addw a2, a0, a2
198; RV64-NEXT:    slt a0, a2, a0
199; RV64-NEXT:    sw a2, 0(a1)
200; RV64-NEXT:    ret
201;
202; RV32ZBA-LABEL: saddo4.i32:
203; RV32ZBA:       # %bb.0: # %entry
204; RV32ZBA-NEXT:    lui a2, 4096
205; RV32ZBA-NEXT:    addi a2, a2, -1
206; RV32ZBA-NEXT:    add a2, a0, a2
207; RV32ZBA-NEXT:    slt a0, a2, a0
208; RV32ZBA-NEXT:    sw a2, 0(a1)
209; RV32ZBA-NEXT:    ret
210;
211; RV64ZBA-LABEL: saddo4.i32:
212; RV64ZBA:       # %bb.0: # %entry
213; RV64ZBA-NEXT:    lui a2, 4096
214; RV64ZBA-NEXT:    addi a2, a2, -1
215; RV64ZBA-NEXT:    addw a2, a0, a2
216; RV64ZBA-NEXT:    slt a0, a2, a0
217; RV64ZBA-NEXT:    sw a2, 0(a1)
218; RV64ZBA-NEXT:    ret
219;
220; RV32ZICOND-LABEL: saddo4.i32:
221; RV32ZICOND:       # %bb.0: # %entry
222; RV32ZICOND-NEXT:    lui a2, 4096
223; RV32ZICOND-NEXT:    addi a2, a2, -1
224; RV32ZICOND-NEXT:    add a2, a0, a2
225; RV32ZICOND-NEXT:    slt a0, a2, a0
226; RV32ZICOND-NEXT:    sw a2, 0(a1)
227; RV32ZICOND-NEXT:    ret
228;
229; RV64ZICOND-LABEL: saddo4.i32:
230; RV64ZICOND:       # %bb.0: # %entry
231; RV64ZICOND-NEXT:    lui a2, 4096
232; RV64ZICOND-NEXT:    addi a2, a2, -1
233; RV64ZICOND-NEXT:    addw a2, a0, a2
234; RV64ZICOND-NEXT:    slt a0, a2, a0
235; RV64ZICOND-NEXT:    sw a2, 0(a1)
236; RV64ZICOND-NEXT:    ret
237entry:
238  %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 16777215)
239  %val = extractvalue {i32, i1} %t, 0
240  %obit = extractvalue {i32, i1} %t, 1
241  store i32 %val, ptr %res
242  ret i1 %obit
243}
244
245define zeroext i1 @saddo1.i64(i64 %v1, i64 %v2, ptr %res) {
246; RV32-LABEL: saddo1.i64:
247; RV32:       # %bb.0: # %entry
248; RV32-NEXT:    add a5, a1, a3
249; RV32-NEXT:    add a2, a0, a2
250; RV32-NEXT:    xor a3, a1, a3
251; RV32-NEXT:    sltu a0, a2, a0
252; RV32-NEXT:    not a3, a3
253; RV32-NEXT:    add a5, a5, a0
254; RV32-NEXT:    xor a1, a1, a5
255; RV32-NEXT:    and a1, a3, a1
256; RV32-NEXT:    slti a0, a1, 0
257; RV32-NEXT:    sw a2, 0(a4)
258; RV32-NEXT:    sw a5, 4(a4)
259; RV32-NEXT:    ret
260;
261; RV64-LABEL: saddo1.i64:
262; RV64:       # %bb.0: # %entry
263; RV64-NEXT:    add a3, a0, a1
264; RV64-NEXT:    slt a0, a3, a0
265; RV64-NEXT:    slti a1, a1, 0
266; RV64-NEXT:    xor a0, a1, a0
267; RV64-NEXT:    sd a3, 0(a2)
268; RV64-NEXT:    ret
269;
270; RV32ZBA-LABEL: saddo1.i64:
271; RV32ZBA:       # %bb.0: # %entry
272; RV32ZBA-NEXT:    add a5, a1, a3
273; RV32ZBA-NEXT:    add a2, a0, a2
274; RV32ZBA-NEXT:    xor a3, a1, a3
275; RV32ZBA-NEXT:    sltu a0, a2, a0
276; RV32ZBA-NEXT:    not a3, a3
277; RV32ZBA-NEXT:    add a5, a5, a0
278; RV32ZBA-NEXT:    xor a1, a1, a5
279; RV32ZBA-NEXT:    and a1, a3, a1
280; RV32ZBA-NEXT:    slti a0, a1, 0
281; RV32ZBA-NEXT:    sw a2, 0(a4)
282; RV32ZBA-NEXT:    sw a5, 4(a4)
283; RV32ZBA-NEXT:    ret
284;
285; RV64ZBA-LABEL: saddo1.i64:
286; RV64ZBA:       # %bb.0: # %entry
287; RV64ZBA-NEXT:    add a3, a0, a1
288; RV64ZBA-NEXT:    slt a0, a3, a0
289; RV64ZBA-NEXT:    slti a1, a1, 0
290; RV64ZBA-NEXT:    xor a0, a1, a0
291; RV64ZBA-NEXT:    sd a3, 0(a2)
292; RV64ZBA-NEXT:    ret
293;
294; RV32ZICOND-LABEL: saddo1.i64:
295; RV32ZICOND:       # %bb.0: # %entry
296; RV32ZICOND-NEXT:    add a5, a1, a3
297; RV32ZICOND-NEXT:    add a2, a0, a2
298; RV32ZICOND-NEXT:    xor a3, a1, a3
299; RV32ZICOND-NEXT:    sltu a0, a2, a0
300; RV32ZICOND-NEXT:    not a3, a3
301; RV32ZICOND-NEXT:    add a5, a5, a0
302; RV32ZICOND-NEXT:    xor a1, a1, a5
303; RV32ZICOND-NEXT:    and a1, a3, a1
304; RV32ZICOND-NEXT:    slti a0, a1, 0
305; RV32ZICOND-NEXT:    sw a2, 0(a4)
306; RV32ZICOND-NEXT:    sw a5, 4(a4)
307; RV32ZICOND-NEXT:    ret
308;
309; RV64ZICOND-LABEL: saddo1.i64:
310; RV64ZICOND:       # %bb.0: # %entry
311; RV64ZICOND-NEXT:    add a3, a0, a1
312; RV64ZICOND-NEXT:    slt a0, a3, a0
313; RV64ZICOND-NEXT:    slti a1, a1, 0
314; RV64ZICOND-NEXT:    xor a0, a1, a0
315; RV64ZICOND-NEXT:    sd a3, 0(a2)
316; RV64ZICOND-NEXT:    ret
317entry:
318  %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2)
319  %val = extractvalue {i64, i1} %t, 0
320  %obit = extractvalue {i64, i1} %t, 1
321  store i64 %val, ptr %res
322  ret i1 %obit
323}
324
325define zeroext i1 @saddo2.i64(i64 %v1, ptr %res) {
326; RV32-LABEL: saddo2.i64:
327; RV32:       # %bb.0: # %entry
328; RV32-NEXT:    addi a3, a0, 4
329; RV32-NEXT:    not a4, a1
330; RV32-NEXT:    sltu a0, a3, a0
331; RV32-NEXT:    add a5, a1, a0
332; RV32-NEXT:    xor a1, a1, a5
333; RV32-NEXT:    and a1, a4, a1
334; RV32-NEXT:    slti a0, a1, 0
335; RV32-NEXT:    sw a3, 0(a2)
336; RV32-NEXT:    sw a5, 4(a2)
337; RV32-NEXT:    ret
338;
339; RV64-LABEL: saddo2.i64:
340; RV64:       # %bb.0: # %entry
341; RV64-NEXT:    addi a2, a0, 4
342; RV64-NEXT:    slt a0, a2, a0
343; RV64-NEXT:    sd a2, 0(a1)
344; RV64-NEXT:    ret
345;
346; RV32ZBA-LABEL: saddo2.i64:
347; RV32ZBA:       # %bb.0: # %entry
348; RV32ZBA-NEXT:    addi a3, a0, 4
349; RV32ZBA-NEXT:    not a4, a1
350; RV32ZBA-NEXT:    sltu a0, a3, a0
351; RV32ZBA-NEXT:    add a5, a1, a0
352; RV32ZBA-NEXT:    xor a1, a1, a5
353; RV32ZBA-NEXT:    and a1, a4, a1
354; RV32ZBA-NEXT:    slti a0, a1, 0
355; RV32ZBA-NEXT:    sw a3, 0(a2)
356; RV32ZBA-NEXT:    sw a5, 4(a2)
357; RV32ZBA-NEXT:    ret
358;
359; RV64ZBA-LABEL: saddo2.i64:
360; RV64ZBA:       # %bb.0: # %entry
361; RV64ZBA-NEXT:    addi a2, a0, 4
362; RV64ZBA-NEXT:    slt a0, a2, a0
363; RV64ZBA-NEXT:    sd a2, 0(a1)
364; RV64ZBA-NEXT:    ret
365;
366; RV32ZICOND-LABEL: saddo2.i64:
367; RV32ZICOND:       # %bb.0: # %entry
368; RV32ZICOND-NEXT:    addi a3, a0, 4
369; RV32ZICOND-NEXT:    not a4, a1
370; RV32ZICOND-NEXT:    sltu a0, a3, a0
371; RV32ZICOND-NEXT:    add a5, a1, a0
372; RV32ZICOND-NEXT:    xor a1, a1, a5
373; RV32ZICOND-NEXT:    and a1, a4, a1
374; RV32ZICOND-NEXT:    slti a0, a1, 0
375; RV32ZICOND-NEXT:    sw a3, 0(a2)
376; RV32ZICOND-NEXT:    sw a5, 4(a2)
377; RV32ZICOND-NEXT:    ret
378;
379; RV64ZICOND-LABEL: saddo2.i64:
380; RV64ZICOND:       # %bb.0: # %entry
381; RV64ZICOND-NEXT:    addi a2, a0, 4
382; RV64ZICOND-NEXT:    slt a0, a2, a0
383; RV64ZICOND-NEXT:    sd a2, 0(a1)
384; RV64ZICOND-NEXT:    ret
385entry:
386  %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 4)
387  %val = extractvalue {i64, i1} %t, 0
388  %obit = extractvalue {i64, i1} %t, 1
389  store i64 %val, ptr %res
390  ret i1 %obit
391}
392
393define zeroext i1 @saddo3.i64(i64 %v1, ptr %res) {
394; RV32-LABEL: saddo3.i64:
395; RV32:       # %bb.0: # %entry
396; RV32-NEXT:    addi a3, a0, -4
397; RV32-NEXT:    sltu a0, a3, a0
398; RV32-NEXT:    add a0, a1, a0
399; RV32-NEXT:    addi a4, a0, -1
400; RV32-NEXT:    xor a0, a1, a4
401; RV32-NEXT:    and a0, a1, a0
402; RV32-NEXT:    slti a0, a0, 0
403; RV32-NEXT:    sw a3, 0(a2)
404; RV32-NEXT:    sw a4, 4(a2)
405; RV32-NEXT:    ret
406;
407; RV64-LABEL: saddo3.i64:
408; RV64:       # %bb.0: # %entry
409; RV64-NEXT:    addi a2, a0, -4
410; RV64-NEXT:    slt a0, a2, a0
411; RV64-NEXT:    xori a0, a0, 1
412; RV64-NEXT:    sd a2, 0(a1)
413; RV64-NEXT:    ret
414;
415; RV32ZBA-LABEL: saddo3.i64:
416; RV32ZBA:       # %bb.0: # %entry
417; RV32ZBA-NEXT:    addi a3, a0, -4
418; RV32ZBA-NEXT:    sltu a0, a3, a0
419; RV32ZBA-NEXT:    add a0, a1, a0
420; RV32ZBA-NEXT:    addi a4, a0, -1
421; RV32ZBA-NEXT:    xor a0, a1, a4
422; RV32ZBA-NEXT:    and a0, a1, a0
423; RV32ZBA-NEXT:    slti a0, a0, 0
424; RV32ZBA-NEXT:    sw a3, 0(a2)
425; RV32ZBA-NEXT:    sw a4, 4(a2)
426; RV32ZBA-NEXT:    ret
427;
428; RV64ZBA-LABEL: saddo3.i64:
429; RV64ZBA:       # %bb.0: # %entry
430; RV64ZBA-NEXT:    addi a2, a0, -4
431; RV64ZBA-NEXT:    slt a0, a2, a0
432; RV64ZBA-NEXT:    xori a0, a0, 1
433; RV64ZBA-NEXT:    sd a2, 0(a1)
434; RV64ZBA-NEXT:    ret
435;
436; RV32ZICOND-LABEL: saddo3.i64:
437; RV32ZICOND:       # %bb.0: # %entry
438; RV32ZICOND-NEXT:    addi a3, a0, -4
439; RV32ZICOND-NEXT:    sltu a0, a3, a0
440; RV32ZICOND-NEXT:    add a0, a1, a0
441; RV32ZICOND-NEXT:    addi a4, a0, -1
442; RV32ZICOND-NEXT:    xor a0, a1, a4
443; RV32ZICOND-NEXT:    and a0, a1, a0
444; RV32ZICOND-NEXT:    slti a0, a0, 0
445; RV32ZICOND-NEXT:    sw a3, 0(a2)
446; RV32ZICOND-NEXT:    sw a4, 4(a2)
447; RV32ZICOND-NEXT:    ret
448;
449; RV64ZICOND-LABEL: saddo3.i64:
450; RV64ZICOND:       # %bb.0: # %entry
451; RV64ZICOND-NEXT:    addi a2, a0, -4
452; RV64ZICOND-NEXT:    slt a0, a2, a0
453; RV64ZICOND-NEXT:    xori a0, a0, 1
454; RV64ZICOND-NEXT:    sd a2, 0(a1)
455; RV64ZICOND-NEXT:    ret
456entry:
457  %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 -4)
458  %val = extractvalue {i64, i1} %t, 0
459  %obit = extractvalue {i64, i1} %t, 1
460  store i64 %val, ptr %res
461  ret i1 %obit
462}
463
464define zeroext i1 @uaddo.i32(i32 signext %v1, i32 signext %v2, ptr %res) {
465; RV32-LABEL: uaddo.i32:
466; RV32:       # %bb.0: # %entry
467; RV32-NEXT:    add a1, a0, a1
468; RV32-NEXT:    sltu a0, a1, a0
469; RV32-NEXT:    sw a1, 0(a2)
470; RV32-NEXT:    ret
471;
472; RV64-LABEL: uaddo.i32:
473; RV64:       # %bb.0: # %entry
474; RV64-NEXT:    addw a1, a0, a1
475; RV64-NEXT:    sltu a0, a1, a0
476; RV64-NEXT:    sw a1, 0(a2)
477; RV64-NEXT:    ret
478;
479; RV32ZBA-LABEL: uaddo.i32:
480; RV32ZBA:       # %bb.0: # %entry
481; RV32ZBA-NEXT:    add a1, a0, a1
482; RV32ZBA-NEXT:    sltu a0, a1, a0
483; RV32ZBA-NEXT:    sw a1, 0(a2)
484; RV32ZBA-NEXT:    ret
485;
486; RV64ZBA-LABEL: uaddo.i32:
487; RV64ZBA:       # %bb.0: # %entry
488; RV64ZBA-NEXT:    addw a1, a0, a1
489; RV64ZBA-NEXT:    sltu a0, a1, a0
490; RV64ZBA-NEXT:    sw a1, 0(a2)
491; RV64ZBA-NEXT:    ret
492;
493; RV32ZICOND-LABEL: uaddo.i32:
494; RV32ZICOND:       # %bb.0: # %entry
495; RV32ZICOND-NEXT:    add a1, a0, a1
496; RV32ZICOND-NEXT:    sltu a0, a1, a0
497; RV32ZICOND-NEXT:    sw a1, 0(a2)
498; RV32ZICOND-NEXT:    ret
499;
500; RV64ZICOND-LABEL: uaddo.i32:
501; RV64ZICOND:       # %bb.0: # %entry
502; RV64ZICOND-NEXT:    addw a1, a0, a1
503; RV64ZICOND-NEXT:    sltu a0, a1, a0
504; RV64ZICOND-NEXT:    sw a1, 0(a2)
505; RV64ZICOND-NEXT:    ret
506entry:
507  %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)
508  %val = extractvalue {i32, i1} %t, 0
509  %obit = extractvalue {i32, i1} %t, 1
510  store i32 %val, ptr %res
511  ret i1 %obit
512}
513
514define zeroext i1 @uaddo.i32.constant(i32 signext %v1, ptr %res) {
515; RV32-LABEL: uaddo.i32.constant:
516; RV32:       # %bb.0: # %entry
517; RV32-NEXT:    addi a2, a0, -2
518; RV32-NEXT:    sltu a0, a2, a0
519; RV32-NEXT:    sw a2, 0(a1)
520; RV32-NEXT:    ret
521;
522; RV64-LABEL: uaddo.i32.constant:
523; RV64:       # %bb.0: # %entry
524; RV64-NEXT:    addiw a2, a0, -2
525; RV64-NEXT:    sltu a0, a2, a0
526; RV64-NEXT:    sw a2, 0(a1)
527; RV64-NEXT:    ret
528;
529; RV32ZBA-LABEL: uaddo.i32.constant:
530; RV32ZBA:       # %bb.0: # %entry
531; RV32ZBA-NEXT:    addi a2, a0, -2
532; RV32ZBA-NEXT:    sltu a0, a2, a0
533; RV32ZBA-NEXT:    sw a2, 0(a1)
534; RV32ZBA-NEXT:    ret
535;
536; RV64ZBA-LABEL: uaddo.i32.constant:
537; RV64ZBA:       # %bb.0: # %entry
538; RV64ZBA-NEXT:    addiw a2, a0, -2
539; RV64ZBA-NEXT:    sltu a0, a2, a0
540; RV64ZBA-NEXT:    sw a2, 0(a1)
541; RV64ZBA-NEXT:    ret
542;
543; RV32ZICOND-LABEL: uaddo.i32.constant:
544; RV32ZICOND:       # %bb.0: # %entry
545; RV32ZICOND-NEXT:    addi a2, a0, -2
546; RV32ZICOND-NEXT:    sltu a0, a2, a0
547; RV32ZICOND-NEXT:    sw a2, 0(a1)
548; RV32ZICOND-NEXT:    ret
549;
550; RV64ZICOND-LABEL: uaddo.i32.constant:
551; RV64ZICOND:       # %bb.0: # %entry
552; RV64ZICOND-NEXT:    addiw a2, a0, -2
553; RV64ZICOND-NEXT:    sltu a0, a2, a0
554; RV64ZICOND-NEXT:    sw a2, 0(a1)
555; RV64ZICOND-NEXT:    ret
556entry:
557  %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 -2)
558  %val = extractvalue {i32, i1} %t, 0
559  %obit = extractvalue {i32, i1} %t, 1
560  store i32 %val, ptr %res
561  ret i1 %obit
562}
563
564define zeroext i1 @uaddo.i32.constant_one(i32 signext %v1, ptr %res) {
565; RV32-LABEL: uaddo.i32.constant_one:
566; RV32:       # %bb.0: # %entry
567; RV32-NEXT:    addi a2, a0, 1
568; RV32-NEXT:    seqz a0, a2
569; RV32-NEXT:    sw a2, 0(a1)
570; RV32-NEXT:    ret
571;
572; RV64-LABEL: uaddo.i32.constant_one:
573; RV64:       # %bb.0: # %entry
574; RV64-NEXT:    addiw a2, a0, 1
575; RV64-NEXT:    seqz a0, a2
576; RV64-NEXT:    sw a2, 0(a1)
577; RV64-NEXT:    ret
578;
579; RV32ZBA-LABEL: uaddo.i32.constant_one:
580; RV32ZBA:       # %bb.0: # %entry
581; RV32ZBA-NEXT:    addi a2, a0, 1
582; RV32ZBA-NEXT:    seqz a0, a2
583; RV32ZBA-NEXT:    sw a2, 0(a1)
584; RV32ZBA-NEXT:    ret
585;
586; RV64ZBA-LABEL: uaddo.i32.constant_one:
587; RV64ZBA:       # %bb.0: # %entry
588; RV64ZBA-NEXT:    addiw a2, a0, 1
589; RV64ZBA-NEXT:    seqz a0, a2
590; RV64ZBA-NEXT:    sw a2, 0(a1)
591; RV64ZBA-NEXT:    ret
592;
593; RV32ZICOND-LABEL: uaddo.i32.constant_one:
594; RV32ZICOND:       # %bb.0: # %entry
595; RV32ZICOND-NEXT:    addi a2, a0, 1
596; RV32ZICOND-NEXT:    seqz a0, a2
597; RV32ZICOND-NEXT:    sw a2, 0(a1)
598; RV32ZICOND-NEXT:    ret
599;
600; RV64ZICOND-LABEL: uaddo.i32.constant_one:
601; RV64ZICOND:       # %bb.0: # %entry
602; RV64ZICOND-NEXT:    addiw a2, a0, 1
603; RV64ZICOND-NEXT:    seqz a0, a2
604; RV64ZICOND-NEXT:    sw a2, 0(a1)
605; RV64ZICOND-NEXT:    ret
606entry:
607  %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 1)
608  %val = extractvalue {i32, i1} %t, 0
609  %obit = extractvalue {i32, i1} %t, 1
610  store i32 %val, ptr %res
611  ret i1 %obit
612}
613
614define zeroext i1 @uaddo.i64(i64 %v1, i64 %v2, ptr %res) {
615; RV32-LABEL: uaddo.i64:
616; RV32:       # %bb.0: # %entry
617; RV32-NEXT:    add a3, a1, a3
618; RV32-NEXT:    add a2, a0, a2
619; RV32-NEXT:    sltu a0, a2, a0
620; RV32-NEXT:    add a3, a3, a0
621; RV32-NEXT:    beq a3, a1, .LBB10_2
622; RV32-NEXT:  # %bb.1: # %entry
623; RV32-NEXT:    sltu a0, a3, a1
624; RV32-NEXT:  .LBB10_2: # %entry
625; RV32-NEXT:    sw a2, 0(a4)
626; RV32-NEXT:    sw a3, 4(a4)
627; RV32-NEXT:    ret
628;
629; RV64-LABEL: uaddo.i64:
630; RV64:       # %bb.0: # %entry
631; RV64-NEXT:    add a1, a0, a1
632; RV64-NEXT:    sltu a0, a1, a0
633; RV64-NEXT:    sd a1, 0(a2)
634; RV64-NEXT:    ret
635;
636; RV32ZBA-LABEL: uaddo.i64:
637; RV32ZBA:       # %bb.0: # %entry
638; RV32ZBA-NEXT:    add a3, a1, a3
639; RV32ZBA-NEXT:    add a2, a0, a2
640; RV32ZBA-NEXT:    sltu a0, a2, a0
641; RV32ZBA-NEXT:    add a3, a3, a0
642; RV32ZBA-NEXT:    beq a3, a1, .LBB10_2
643; RV32ZBA-NEXT:  # %bb.1: # %entry
644; RV32ZBA-NEXT:    sltu a0, a3, a1
645; RV32ZBA-NEXT:  .LBB10_2: # %entry
646; RV32ZBA-NEXT:    sw a2, 0(a4)
647; RV32ZBA-NEXT:    sw a3, 4(a4)
648; RV32ZBA-NEXT:    ret
649;
650; RV64ZBA-LABEL: uaddo.i64:
651; RV64ZBA:       # %bb.0: # %entry
652; RV64ZBA-NEXT:    add a1, a0, a1
653; RV64ZBA-NEXT:    sltu a0, a1, a0
654; RV64ZBA-NEXT:    sd a1, 0(a2)
655; RV64ZBA-NEXT:    ret
656;
657; RV32ZICOND-LABEL: uaddo.i64:
658; RV32ZICOND:       # %bb.0: # %entry
659; RV32ZICOND-NEXT:    add a3, a1, a3
660; RV32ZICOND-NEXT:    add a2, a0, a2
661; RV32ZICOND-NEXT:    sltu a0, a2, a0
662; RV32ZICOND-NEXT:    add a3, a3, a0
663; RV32ZICOND-NEXT:    xor a5, a3, a1
664; RV32ZICOND-NEXT:    sltu a1, a3, a1
665; RV32ZICOND-NEXT:    czero.eqz a1, a1, a5
666; RV32ZICOND-NEXT:    czero.nez a0, a0, a5
667; RV32ZICOND-NEXT:    or a0, a0, a1
668; RV32ZICOND-NEXT:    sw a2, 0(a4)
669; RV32ZICOND-NEXT:    sw a3, 4(a4)
670; RV32ZICOND-NEXT:    ret
671;
672; RV64ZICOND-LABEL: uaddo.i64:
673; RV64ZICOND:       # %bb.0: # %entry
674; RV64ZICOND-NEXT:    add a1, a0, a1
675; RV64ZICOND-NEXT:    sltu a0, a1, a0
676; RV64ZICOND-NEXT:    sd a1, 0(a2)
677; RV64ZICOND-NEXT:    ret
678entry:
679  %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2)
680  %val = extractvalue {i64, i1} %t, 0
681  %obit = extractvalue {i64, i1} %t, 1
682  store i64 %val, ptr %res
683  ret i1 %obit
684}
685
686define zeroext i1 @uaddo.i64.constant_one(i64 %v1, ptr %res) {
687; RV32-LABEL: uaddo.i64.constant_one:
688; RV32:       # %bb.0: # %entry
689; RV32-NEXT:    addi a3, a0, 1
690; RV32-NEXT:    seqz a0, a3
691; RV32-NEXT:    add a1, a1, a0
692; RV32-NEXT:    or a0, a3, a1
693; RV32-NEXT:    seqz a0, a0
694; RV32-NEXT:    sw a3, 0(a2)
695; RV32-NEXT:    sw a1, 4(a2)
696; RV32-NEXT:    ret
697;
698; RV64-LABEL: uaddo.i64.constant_one:
699; RV64:       # %bb.0: # %entry
700; RV64-NEXT:    addi a2, a0, 1
701; RV64-NEXT:    seqz a0, a2
702; RV64-NEXT:    sd a2, 0(a1)
703; RV64-NEXT:    ret
704;
705; RV32ZBA-LABEL: uaddo.i64.constant_one:
706; RV32ZBA:       # %bb.0: # %entry
707; RV32ZBA-NEXT:    addi a3, a0, 1
708; RV32ZBA-NEXT:    seqz a0, a3
709; RV32ZBA-NEXT:    add a1, a1, a0
710; RV32ZBA-NEXT:    or a0, a3, a1
711; RV32ZBA-NEXT:    seqz a0, a0
712; RV32ZBA-NEXT:    sw a3, 0(a2)
713; RV32ZBA-NEXT:    sw a1, 4(a2)
714; RV32ZBA-NEXT:    ret
715;
716; RV64ZBA-LABEL: uaddo.i64.constant_one:
717; RV64ZBA:       # %bb.0: # %entry
718; RV64ZBA-NEXT:    addi a2, a0, 1
719; RV64ZBA-NEXT:    seqz a0, a2
720; RV64ZBA-NEXT:    sd a2, 0(a1)
721; RV64ZBA-NEXT:    ret
722;
723; RV32ZICOND-LABEL: uaddo.i64.constant_one:
724; RV32ZICOND:       # %bb.0: # %entry
725; RV32ZICOND-NEXT:    addi a3, a0, 1
726; RV32ZICOND-NEXT:    seqz a0, a3
727; RV32ZICOND-NEXT:    add a1, a1, a0
728; RV32ZICOND-NEXT:    or a0, a3, a1
729; RV32ZICOND-NEXT:    seqz a0, a0
730; RV32ZICOND-NEXT:    sw a3, 0(a2)
731; RV32ZICOND-NEXT:    sw a1, 4(a2)
732; RV32ZICOND-NEXT:    ret
733;
734; RV64ZICOND-LABEL: uaddo.i64.constant_one:
735; RV64ZICOND:       # %bb.0: # %entry
736; RV64ZICOND-NEXT:    addi a2, a0, 1
737; RV64ZICOND-NEXT:    seqz a0, a2
738; RV64ZICOND-NEXT:    sd a2, 0(a1)
739; RV64ZICOND-NEXT:    ret
740entry:
741  %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 1)
742  %val = extractvalue {i64, i1} %t, 0
743  %obit = extractvalue {i64, i1} %t, 1
744  store i64 %val, ptr %res
745  ret i1 %obit
746}
747
748define zeroext i1 @ssubo1.i32(i32 signext %v1, i32 signext %v2, ptr %res) {
749; RV32-LABEL: ssubo1.i32:
750; RV32:       # %bb.0: # %entry
751; RV32-NEXT:    sgtz a3, a1
752; RV32-NEXT:    sub a1, a0, a1
753; RV32-NEXT:    slt a0, a1, a0
754; RV32-NEXT:    xor a0, a3, a0
755; RV32-NEXT:    sw a1, 0(a2)
756; RV32-NEXT:    ret
757;
758; RV64-LABEL: ssubo1.i32:
759; RV64:       # %bb.0: # %entry
760; RV64-NEXT:    sub a3, a0, a1
761; RV64-NEXT:    subw a0, a0, a1
762; RV64-NEXT:    xor a0, a0, a3
763; RV64-NEXT:    snez a0, a0
764; RV64-NEXT:    sw a3, 0(a2)
765; RV64-NEXT:    ret
766;
767; RV32ZBA-LABEL: ssubo1.i32:
768; RV32ZBA:       # %bb.0: # %entry
769; RV32ZBA-NEXT:    sgtz a3, a1
770; RV32ZBA-NEXT:    sub a1, a0, a1
771; RV32ZBA-NEXT:    slt a0, a1, a0
772; RV32ZBA-NEXT:    xor a0, a3, a0
773; RV32ZBA-NEXT:    sw a1, 0(a2)
774; RV32ZBA-NEXT:    ret
775;
776; RV64ZBA-LABEL: ssubo1.i32:
777; RV64ZBA:       # %bb.0: # %entry
778; RV64ZBA-NEXT:    sub a3, a0, a1
779; RV64ZBA-NEXT:    subw a0, a0, a1
780; RV64ZBA-NEXT:    xor a0, a0, a3
781; RV64ZBA-NEXT:    snez a0, a0
782; RV64ZBA-NEXT:    sw a3, 0(a2)
783; RV64ZBA-NEXT:    ret
784;
785; RV32ZICOND-LABEL: ssubo1.i32:
786; RV32ZICOND:       # %bb.0: # %entry
787; RV32ZICOND-NEXT:    sgtz a3, a1
788; RV32ZICOND-NEXT:    sub a1, a0, a1
789; RV32ZICOND-NEXT:    slt a0, a1, a0
790; RV32ZICOND-NEXT:    xor a0, a3, a0
791; RV32ZICOND-NEXT:    sw a1, 0(a2)
792; RV32ZICOND-NEXT:    ret
793;
794; RV64ZICOND-LABEL: ssubo1.i32:
795; RV64ZICOND:       # %bb.0: # %entry
796; RV64ZICOND-NEXT:    sub a3, a0, a1
797; RV64ZICOND-NEXT:    subw a0, a0, a1
798; RV64ZICOND-NEXT:    xor a0, a0, a3
799; RV64ZICOND-NEXT:    snez a0, a0
800; RV64ZICOND-NEXT:    sw a3, 0(a2)
801; RV64ZICOND-NEXT:    ret
802entry:
803  %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2)
804  %val = extractvalue {i32, i1} %t, 0
805  %obit = extractvalue {i32, i1} %t, 1
806  store i32 %val, ptr %res
807  ret i1 %obit
808}
809
810define zeroext i1 @ssubo2.i32(i32 signext %v1, ptr %res) {
811; RV32-LABEL: ssubo2.i32:
812; RV32:       # %bb.0: # %entry
813; RV32-NEXT:    addi a2, a0, 4
814; RV32-NEXT:    slt a0, a2, a0
815; RV32-NEXT:    sw a2, 0(a1)
816; RV32-NEXT:    ret
817;
818; RV64-LABEL: ssubo2.i32:
819; RV64:       # %bb.0: # %entry
820; RV64-NEXT:    addiw a2, a0, 4
821; RV64-NEXT:    slt a0, a2, a0
822; RV64-NEXT:    sw a2, 0(a1)
823; RV64-NEXT:    ret
824;
825; RV32ZBA-LABEL: ssubo2.i32:
826; RV32ZBA:       # %bb.0: # %entry
827; RV32ZBA-NEXT:    addi a2, a0, 4
828; RV32ZBA-NEXT:    slt a0, a2, a0
829; RV32ZBA-NEXT:    sw a2, 0(a1)
830; RV32ZBA-NEXT:    ret
831;
832; RV64ZBA-LABEL: ssubo2.i32:
833; RV64ZBA:       # %bb.0: # %entry
834; RV64ZBA-NEXT:    addiw a2, a0, 4
835; RV64ZBA-NEXT:    slt a0, a2, a0
836; RV64ZBA-NEXT:    sw a2, 0(a1)
837; RV64ZBA-NEXT:    ret
838;
839; RV32ZICOND-LABEL: ssubo2.i32:
840; RV32ZICOND:       # %bb.0: # %entry
841; RV32ZICOND-NEXT:    addi a2, a0, 4
842; RV32ZICOND-NEXT:    slt a0, a2, a0
843; RV32ZICOND-NEXT:    sw a2, 0(a1)
844; RV32ZICOND-NEXT:    ret
845;
846; RV64ZICOND-LABEL: ssubo2.i32:
847; RV64ZICOND:       # %bb.0: # %entry
848; RV64ZICOND-NEXT:    addiw a2, a0, 4
849; RV64ZICOND-NEXT:    slt a0, a2, a0
850; RV64ZICOND-NEXT:    sw a2, 0(a1)
851; RV64ZICOND-NEXT:    ret
852entry:
853  %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 -4)
854  %val = extractvalue {i32, i1} %t, 0
855  %obit = extractvalue {i32, i1} %t, 1
856  store i32 %val, ptr %res
857  ret i1 %obit
858}
859
860define zeroext i1 @ssubo.i64(i64 %v1, i64 %v2, ptr %res) {
861; RV32-LABEL: ssubo.i64:
862; RV32:       # %bb.0: # %entry
863; RV32-NEXT:    sltu a5, a0, a2
864; RV32-NEXT:    sub a6, a1, a3
865; RV32-NEXT:    xor a3, a1, a3
866; RV32-NEXT:    sub a2, a0, a2
867; RV32-NEXT:    sub a5, a6, a5
868; RV32-NEXT:    xor a1, a1, a5
869; RV32-NEXT:    and a1, a3, a1
870; RV32-NEXT:    slti a0, a1, 0
871; RV32-NEXT:    sw a2, 0(a4)
872; RV32-NEXT:    sw a5, 4(a4)
873; RV32-NEXT:    ret
874;
875; RV64-LABEL: ssubo.i64:
876; RV64:       # %bb.0: # %entry
877; RV64-NEXT:    sgtz a3, a1
878; RV64-NEXT:    sub a1, a0, a1
879; RV64-NEXT:    slt a0, a1, a0
880; RV64-NEXT:    xor a0, a3, a0
881; RV64-NEXT:    sd a1, 0(a2)
882; RV64-NEXT:    ret
883;
884; RV32ZBA-LABEL: ssubo.i64:
885; RV32ZBA:       # %bb.0: # %entry
886; RV32ZBA-NEXT:    sltu a5, a0, a2
887; RV32ZBA-NEXT:    sub a6, a1, a3
888; RV32ZBA-NEXT:    xor a3, a1, a3
889; RV32ZBA-NEXT:    sub a2, a0, a2
890; RV32ZBA-NEXT:    sub a5, a6, a5
891; RV32ZBA-NEXT:    xor a1, a1, a5
892; RV32ZBA-NEXT:    and a1, a3, a1
893; RV32ZBA-NEXT:    slti a0, a1, 0
894; RV32ZBA-NEXT:    sw a2, 0(a4)
895; RV32ZBA-NEXT:    sw a5, 4(a4)
896; RV32ZBA-NEXT:    ret
897;
898; RV64ZBA-LABEL: ssubo.i64:
899; RV64ZBA:       # %bb.0: # %entry
900; RV64ZBA-NEXT:    sgtz a3, a1
901; RV64ZBA-NEXT:    sub a1, a0, a1
902; RV64ZBA-NEXT:    slt a0, a1, a0
903; RV64ZBA-NEXT:    xor a0, a3, a0
904; RV64ZBA-NEXT:    sd a1, 0(a2)
905; RV64ZBA-NEXT:    ret
906;
907; RV32ZICOND-LABEL: ssubo.i64:
908; RV32ZICOND:       # %bb.0: # %entry
909; RV32ZICOND-NEXT:    sltu a5, a0, a2
910; RV32ZICOND-NEXT:    sub a6, a1, a3
911; RV32ZICOND-NEXT:    xor a3, a1, a3
912; RV32ZICOND-NEXT:    sub a2, a0, a2
913; RV32ZICOND-NEXT:    sub a5, a6, a5
914; RV32ZICOND-NEXT:    xor a1, a1, a5
915; RV32ZICOND-NEXT:    and a1, a3, a1
916; RV32ZICOND-NEXT:    slti a0, a1, 0
917; RV32ZICOND-NEXT:    sw a2, 0(a4)
918; RV32ZICOND-NEXT:    sw a5, 4(a4)
919; RV32ZICOND-NEXT:    ret
920;
921; RV64ZICOND-LABEL: ssubo.i64:
922; RV64ZICOND:       # %bb.0: # %entry
923; RV64ZICOND-NEXT:    sgtz a3, a1
924; RV64ZICOND-NEXT:    sub a1, a0, a1
925; RV64ZICOND-NEXT:    slt a0, a1, a0
926; RV64ZICOND-NEXT:    xor a0, a3, a0
927; RV64ZICOND-NEXT:    sd a1, 0(a2)
928; RV64ZICOND-NEXT:    ret
929entry:
930  %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2)
931  %val = extractvalue {i64, i1} %t, 0
932  %obit = extractvalue {i64, i1} %t, 1
933  store i64 %val, ptr %res
934  ret i1 %obit
935}
936
937define zeroext i1 @usubo.i32(i32 signext %v1, i32 signext %v2, ptr %res) {
938; RV32-LABEL: usubo.i32:
939; RV32:       # %bb.0: # %entry
940; RV32-NEXT:    sub a1, a0, a1
941; RV32-NEXT:    sltu a0, a0, a1
942; RV32-NEXT:    sw a1, 0(a2)
943; RV32-NEXT:    ret
944;
945; RV64-LABEL: usubo.i32:
946; RV64:       # %bb.0: # %entry
947; RV64-NEXT:    subw a1, a0, a1
948; RV64-NEXT:    sltu a0, a0, a1
949; RV64-NEXT:    sw a1, 0(a2)
950; RV64-NEXT:    ret
951;
952; RV32ZBA-LABEL: usubo.i32:
953; RV32ZBA:       # %bb.0: # %entry
954; RV32ZBA-NEXT:    sub a1, a0, a1
955; RV32ZBA-NEXT:    sltu a0, a0, a1
956; RV32ZBA-NEXT:    sw a1, 0(a2)
957; RV32ZBA-NEXT:    ret
958;
959; RV64ZBA-LABEL: usubo.i32:
960; RV64ZBA:       # %bb.0: # %entry
961; RV64ZBA-NEXT:    subw a1, a0, a1
962; RV64ZBA-NEXT:    sltu a0, a0, a1
963; RV64ZBA-NEXT:    sw a1, 0(a2)
964; RV64ZBA-NEXT:    ret
965;
966; RV32ZICOND-LABEL: usubo.i32:
967; RV32ZICOND:       # %bb.0: # %entry
968; RV32ZICOND-NEXT:    sub a1, a0, a1
969; RV32ZICOND-NEXT:    sltu a0, a0, a1
970; RV32ZICOND-NEXT:    sw a1, 0(a2)
971; RV32ZICOND-NEXT:    ret
972;
973; RV64ZICOND-LABEL: usubo.i32:
974; RV64ZICOND:       # %bb.0: # %entry
975; RV64ZICOND-NEXT:    subw a1, a0, a1
976; RV64ZICOND-NEXT:    sltu a0, a0, a1
977; RV64ZICOND-NEXT:    sw a1, 0(a2)
978; RV64ZICOND-NEXT:    ret
979entry:
980  %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2)
981  %val = extractvalue {i32, i1} %t, 0
982  %obit = extractvalue {i32, i1} %t, 1
983  store i32 %val, ptr %res
984  ret i1 %obit
985}
986
987define zeroext i1 @usubo.i32.constant.rhs(i32 signext %v1, ptr %res) {
988; RV32-LABEL: usubo.i32.constant.rhs:
989; RV32:       # %bb.0: # %entry
990; RV32-NEXT:    addi a2, a0, 2
991; RV32-NEXT:    sltu a0, a0, a2
992; RV32-NEXT:    sw a2, 0(a1)
993; RV32-NEXT:    ret
994;
995; RV64-LABEL: usubo.i32.constant.rhs:
996; RV64:       # %bb.0: # %entry
997; RV64-NEXT:    addiw a2, a0, 2
998; RV64-NEXT:    sltu a0, a0, a2
999; RV64-NEXT:    sw a2, 0(a1)
1000; RV64-NEXT:    ret
1001;
1002; RV32ZBA-LABEL: usubo.i32.constant.rhs:
1003; RV32ZBA:       # %bb.0: # %entry
1004; RV32ZBA-NEXT:    addi a2, a0, 2
1005; RV32ZBA-NEXT:    sltu a0, a0, a2
1006; RV32ZBA-NEXT:    sw a2, 0(a1)
1007; RV32ZBA-NEXT:    ret
1008;
1009; RV64ZBA-LABEL: usubo.i32.constant.rhs:
1010; RV64ZBA:       # %bb.0: # %entry
1011; RV64ZBA-NEXT:    addiw a2, a0, 2
1012; RV64ZBA-NEXT:    sltu a0, a0, a2
1013; RV64ZBA-NEXT:    sw a2, 0(a1)
1014; RV64ZBA-NEXT:    ret
1015;
1016; RV32ZICOND-LABEL: usubo.i32.constant.rhs:
1017; RV32ZICOND:       # %bb.0: # %entry
1018; RV32ZICOND-NEXT:    addi a2, a0, 2
1019; RV32ZICOND-NEXT:    sltu a0, a0, a2
1020; RV32ZICOND-NEXT:    sw a2, 0(a1)
1021; RV32ZICOND-NEXT:    ret
1022;
1023; RV64ZICOND-LABEL: usubo.i32.constant.rhs:
1024; RV64ZICOND:       # %bb.0: # %entry
1025; RV64ZICOND-NEXT:    addiw a2, a0, 2
1026; RV64ZICOND-NEXT:    sltu a0, a0, a2
1027; RV64ZICOND-NEXT:    sw a2, 0(a1)
1028; RV64ZICOND-NEXT:    ret
1029entry:
1030  %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 -2)
1031  %val = extractvalue {i32, i1} %t, 0
1032  %obit = extractvalue {i32, i1} %t, 1
1033  store i32 %val, ptr %res
1034  ret i1 %obit
1035}
1036
1037define zeroext i1 @usubo.i32.constant.lhs(i32 signext %v1, ptr %res) {
1038; RV32-LABEL: usubo.i32.constant.lhs:
1039; RV32:       # %bb.0: # %entry
1040; RV32-NEXT:    li a2, -2
1041; RV32-NEXT:    sub a2, a2, a0
1042; RV32-NEXT:    addi a0, a2, 1
1043; RV32-NEXT:    seqz a0, a0
1044; RV32-NEXT:    sw a2, 0(a1)
1045; RV32-NEXT:    ret
1046;
1047; RV64-LABEL: usubo.i32.constant.lhs:
1048; RV64:       # %bb.0: # %entry
1049; RV64-NEXT:    li a2, -2
1050; RV64-NEXT:    subw a2, a2, a0
1051; RV64-NEXT:    addi a0, a2, 1
1052; RV64-NEXT:    seqz a0, a0
1053; RV64-NEXT:    sw a2, 0(a1)
1054; RV64-NEXT:    ret
1055;
1056; RV32ZBA-LABEL: usubo.i32.constant.lhs:
1057; RV32ZBA:       # %bb.0: # %entry
1058; RV32ZBA-NEXT:    li a2, -2
1059; RV32ZBA-NEXT:    sub a2, a2, a0
1060; RV32ZBA-NEXT:    addi a0, a2, 1
1061; RV32ZBA-NEXT:    seqz a0, a0
1062; RV32ZBA-NEXT:    sw a2, 0(a1)
1063; RV32ZBA-NEXT:    ret
1064;
1065; RV64ZBA-LABEL: usubo.i32.constant.lhs:
1066; RV64ZBA:       # %bb.0: # %entry
1067; RV64ZBA-NEXT:    li a2, -2
1068; RV64ZBA-NEXT:    subw a2, a2, a0
1069; RV64ZBA-NEXT:    addi a0, a2, 1
1070; RV64ZBA-NEXT:    seqz a0, a0
1071; RV64ZBA-NEXT:    sw a2, 0(a1)
1072; RV64ZBA-NEXT:    ret
1073;
1074; RV32ZICOND-LABEL: usubo.i32.constant.lhs:
1075; RV32ZICOND:       # %bb.0: # %entry
1076; RV32ZICOND-NEXT:    li a2, -2
1077; RV32ZICOND-NEXT:    sub a2, a2, a0
1078; RV32ZICOND-NEXT:    addi a0, a2, 1
1079; RV32ZICOND-NEXT:    seqz a0, a0
1080; RV32ZICOND-NEXT:    sw a2, 0(a1)
1081; RV32ZICOND-NEXT:    ret
1082;
1083; RV64ZICOND-LABEL: usubo.i32.constant.lhs:
1084; RV64ZICOND:       # %bb.0: # %entry
1085; RV64ZICOND-NEXT:    li a2, -2
1086; RV64ZICOND-NEXT:    subw a2, a2, a0
1087; RV64ZICOND-NEXT:    addi a0, a2, 1
1088; RV64ZICOND-NEXT:    seqz a0, a0
1089; RV64ZICOND-NEXT:    sw a2, 0(a1)
1090; RV64ZICOND-NEXT:    ret
1091entry:
1092  %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 -2, i32 %v1)
1093  %val = extractvalue {i32, i1} %t, 0
1094  %obit = extractvalue {i32, i1} %t, 1
1095  store i32 %val, ptr %res
1096  ret i1 %obit
1097}
1098
1099define zeroext i1 @usubo.i64(i64 %v1, i64 %v2, ptr %res) {
1100; RV32-LABEL: usubo.i64:
1101; RV32:       # %bb.0: # %entry
1102; RV32-NEXT:    sltu a5, a0, a2
1103; RV32-NEXT:    sub a3, a1, a3
1104; RV32-NEXT:    sub a3, a3, a5
1105; RV32-NEXT:    sub a2, a0, a2
1106; RV32-NEXT:    beq a3, a1, .LBB18_2
1107; RV32-NEXT:  # %bb.1: # %entry
1108; RV32-NEXT:    sltu a0, a1, a3
1109; RV32-NEXT:    j .LBB18_3
1110; RV32-NEXT:  .LBB18_2:
1111; RV32-NEXT:    sltu a0, a0, a2
1112; RV32-NEXT:  .LBB18_3: # %entry
1113; RV32-NEXT:    sw a2, 0(a4)
1114; RV32-NEXT:    sw a3, 4(a4)
1115; RV32-NEXT:    ret
1116;
1117; RV64-LABEL: usubo.i64:
1118; RV64:       # %bb.0: # %entry
1119; RV64-NEXT:    sub a1, a0, a1
1120; RV64-NEXT:    sltu a0, a0, a1
1121; RV64-NEXT:    sd a1, 0(a2)
1122; RV64-NEXT:    ret
1123;
1124; RV32ZBA-LABEL: usubo.i64:
1125; RV32ZBA:       # %bb.0: # %entry
1126; RV32ZBA-NEXT:    sltu a5, a0, a2
1127; RV32ZBA-NEXT:    sub a3, a1, a3
1128; RV32ZBA-NEXT:    sub a3, a3, a5
1129; RV32ZBA-NEXT:    sub a2, a0, a2
1130; RV32ZBA-NEXT:    beq a3, a1, .LBB18_2
1131; RV32ZBA-NEXT:  # %bb.1: # %entry
1132; RV32ZBA-NEXT:    sltu a0, a1, a3
1133; RV32ZBA-NEXT:    j .LBB18_3
1134; RV32ZBA-NEXT:  .LBB18_2:
1135; RV32ZBA-NEXT:    sltu a0, a0, a2
1136; RV32ZBA-NEXT:  .LBB18_3: # %entry
1137; RV32ZBA-NEXT:    sw a2, 0(a4)
1138; RV32ZBA-NEXT:    sw a3, 4(a4)
1139; RV32ZBA-NEXT:    ret
1140;
1141; RV64ZBA-LABEL: usubo.i64:
1142; RV64ZBA:       # %bb.0: # %entry
1143; RV64ZBA-NEXT:    sub a1, a0, a1
1144; RV64ZBA-NEXT:    sltu a0, a0, a1
1145; RV64ZBA-NEXT:    sd a1, 0(a2)
1146; RV64ZBA-NEXT:    ret
1147;
1148; RV32ZICOND-LABEL: usubo.i64:
1149; RV32ZICOND:       # %bb.0: # %entry
1150; RV32ZICOND-NEXT:    sltu a5, a0, a2
1151; RV32ZICOND-NEXT:    sub a3, a1, a3
1152; RV32ZICOND-NEXT:    sub a2, a0, a2
1153; RV32ZICOND-NEXT:    sub a3, a3, a5
1154; RV32ZICOND-NEXT:    sltu a0, a0, a2
1155; RV32ZICOND-NEXT:    xor a5, a3, a1
1156; RV32ZICOND-NEXT:    sltu a1, a1, a3
1157; RV32ZICOND-NEXT:    czero.eqz a1, a1, a5
1158; RV32ZICOND-NEXT:    czero.nez a0, a0, a5
1159; RV32ZICOND-NEXT:    or a0, a0, a1
1160; RV32ZICOND-NEXT:    sw a2, 0(a4)
1161; RV32ZICOND-NEXT:    sw a3, 4(a4)
1162; RV32ZICOND-NEXT:    ret
1163;
1164; RV64ZICOND-LABEL: usubo.i64:
1165; RV64ZICOND:       # %bb.0: # %entry
1166; RV64ZICOND-NEXT:    sub a1, a0, a1
1167; RV64ZICOND-NEXT:    sltu a0, a0, a1
1168; RV64ZICOND-NEXT:    sd a1, 0(a2)
1169; RV64ZICOND-NEXT:    ret
1170entry:
1171  %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2)
1172  %val = extractvalue {i64, i1} %t, 0
1173  %obit = extractvalue {i64, i1} %t, 1
1174  store i64 %val, ptr %res
1175  ret i1 %obit
1176}
1177
1178define zeroext i1 @smulo.i32(i32 signext %v1, i32 signext %v2, ptr %res) {
1179; RV32-LABEL: smulo.i32:
1180; RV32:       # %bb.0: # %entry
1181; RV32-NEXT:    mulh a3, a0, a1
1182; RV32-NEXT:    mul a1, a0, a1
1183; RV32-NEXT:    srai a0, a1, 31
1184; RV32-NEXT:    xor a0, a3, a0
1185; RV32-NEXT:    snez a0, a0
1186; RV32-NEXT:    sw a1, 0(a2)
1187; RV32-NEXT:    ret
1188;
1189; RV64-LABEL: smulo.i32:
1190; RV64:       # %bb.0: # %entry
1191; RV64-NEXT:    mul a3, a0, a1
1192; RV64-NEXT:    mulw a0, a0, a1
1193; RV64-NEXT:    xor a0, a0, a3
1194; RV64-NEXT:    snez a0, a0
1195; RV64-NEXT:    sw a3, 0(a2)
1196; RV64-NEXT:    ret
1197;
1198; RV32ZBA-LABEL: smulo.i32:
1199; RV32ZBA:       # %bb.0: # %entry
1200; RV32ZBA-NEXT:    mulh a3, a0, a1
1201; RV32ZBA-NEXT:    mul a1, a0, a1
1202; RV32ZBA-NEXT:    srai a0, a1, 31
1203; RV32ZBA-NEXT:    xor a0, a3, a0
1204; RV32ZBA-NEXT:    snez a0, a0
1205; RV32ZBA-NEXT:    sw a1, 0(a2)
1206; RV32ZBA-NEXT:    ret
1207;
1208; RV64ZBA-LABEL: smulo.i32:
1209; RV64ZBA:       # %bb.0: # %entry
1210; RV64ZBA-NEXT:    mul a3, a0, a1
1211; RV64ZBA-NEXT:    mulw a0, a0, a1
1212; RV64ZBA-NEXT:    xor a0, a0, a3
1213; RV64ZBA-NEXT:    snez a0, a0
1214; RV64ZBA-NEXT:    sw a3, 0(a2)
1215; RV64ZBA-NEXT:    ret
1216;
1217; RV32ZICOND-LABEL: smulo.i32:
1218; RV32ZICOND:       # %bb.0: # %entry
1219; RV32ZICOND-NEXT:    mulh a3, a0, a1
1220; RV32ZICOND-NEXT:    mul a1, a0, a1
1221; RV32ZICOND-NEXT:    srai a0, a1, 31
1222; RV32ZICOND-NEXT:    xor a0, a3, a0
1223; RV32ZICOND-NEXT:    snez a0, a0
1224; RV32ZICOND-NEXT:    sw a1, 0(a2)
1225; RV32ZICOND-NEXT:    ret
1226;
1227; RV64ZICOND-LABEL: smulo.i32:
1228; RV64ZICOND:       # %bb.0: # %entry
1229; RV64ZICOND-NEXT:    mul a3, a0, a1
1230; RV64ZICOND-NEXT:    mulw a0, a0, a1
1231; RV64ZICOND-NEXT:    xor a0, a0, a3
1232; RV64ZICOND-NEXT:    snez a0, a0
1233; RV64ZICOND-NEXT:    sw a3, 0(a2)
1234; RV64ZICOND-NEXT:    ret
1235entry:
1236  %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
1237  %val = extractvalue {i32, i1} %t, 0
1238  %obit = extractvalue {i32, i1} %t, 1
1239  store i32 %val, ptr %res
1240  ret i1 %obit
1241}
1242
1243define zeroext i1 @smulo2.i32(i32 signext %v1, ptr %res) {
1244; RV32-LABEL: smulo2.i32:
1245; RV32:       # %bb.0: # %entry
1246; RV32-NEXT:    li a2, 13
1247; RV32-NEXT:    mulh a3, a0, a2
1248; RV32-NEXT:    mul a2, a0, a2
1249; RV32-NEXT:    srai a0, a2, 31
1250; RV32-NEXT:    xor a0, a3, a0
1251; RV32-NEXT:    snez a0, a0
1252; RV32-NEXT:    sw a2, 0(a1)
1253; RV32-NEXT:    ret
1254;
1255; RV64-LABEL: smulo2.i32:
1256; RV64:       # %bb.0: # %entry
1257; RV64-NEXT:    li a2, 13
1258; RV64-NEXT:    mul a3, a0, a2
1259; RV64-NEXT:    mulw a0, a0, a2
1260; RV64-NEXT:    xor a0, a0, a3
1261; RV64-NEXT:    snez a0, a0
1262; RV64-NEXT:    sw a3, 0(a1)
1263; RV64-NEXT:    ret
1264;
1265; RV32ZBA-LABEL: smulo2.i32:
1266; RV32ZBA:       # %bb.0: # %entry
1267; RV32ZBA-NEXT:    li a2, 13
1268; RV32ZBA-NEXT:    sh1add a3, a0, a0
1269; RV32ZBA-NEXT:    mulh a2, a0, a2
1270; RV32ZBA-NEXT:    sh2add a3, a3, a0
1271; RV32ZBA-NEXT:    srai a0, a3, 31
1272; RV32ZBA-NEXT:    xor a0, a2, a0
1273; RV32ZBA-NEXT:    snez a0, a0
1274; RV32ZBA-NEXT:    sw a3, 0(a1)
1275; RV32ZBA-NEXT:    ret
1276;
1277; RV64ZBA-LABEL: smulo2.i32:
1278; RV64ZBA:       # %bb.0: # %entry
1279; RV64ZBA-NEXT:    sh1add a2, a0, a0
1280; RV64ZBA-NEXT:    sh2add a2, a2, a0
1281; RV64ZBA-NEXT:    sext.w a0, a2
1282; RV64ZBA-NEXT:    xor a0, a0, a2
1283; RV64ZBA-NEXT:    snez a0, a0
1284; RV64ZBA-NEXT:    sw a2, 0(a1)
1285; RV64ZBA-NEXT:    ret
1286;
1287; RV32ZICOND-LABEL: smulo2.i32:
1288; RV32ZICOND:       # %bb.0: # %entry
1289; RV32ZICOND-NEXT:    li a2, 13
1290; RV32ZICOND-NEXT:    mulh a3, a0, a2
1291; RV32ZICOND-NEXT:    mul a2, a0, a2
1292; RV32ZICOND-NEXT:    srai a0, a2, 31
1293; RV32ZICOND-NEXT:    xor a0, a3, a0
1294; RV32ZICOND-NEXT:    snez a0, a0
1295; RV32ZICOND-NEXT:    sw a2, 0(a1)
1296; RV32ZICOND-NEXT:    ret
1297;
1298; RV64ZICOND-LABEL: smulo2.i32:
1299; RV64ZICOND:       # %bb.0: # %entry
1300; RV64ZICOND-NEXT:    li a2, 13
1301; RV64ZICOND-NEXT:    mul a3, a0, a2
1302; RV64ZICOND-NEXT:    mulw a0, a0, a2
1303; RV64ZICOND-NEXT:    xor a0, a0, a3
1304; RV64ZICOND-NEXT:    snez a0, a0
1305; RV64ZICOND-NEXT:    sw a3, 0(a1)
1306; RV64ZICOND-NEXT:    ret
1307entry:
1308  %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 13)
1309  %val = extractvalue {i32, i1} %t, 0
1310  %obit = extractvalue {i32, i1} %t, 1
1311  store i32 %val, ptr %res
1312  ret i1 %obit
1313}
1314
1315define zeroext i1 @smulo.i64(i64 %v1, i64 %v2, ptr %res) {
1316; RV32-LABEL: smulo.i64:
1317; RV32:       # %bb.0: # %entry
1318; RV32-NEXT:    mulhu a5, a0, a2
1319; RV32-NEXT:    mul a6, a1, a2
1320; RV32-NEXT:    mulhsu a7, a1, a2
1321; RV32-NEXT:    mul t0, a3, a0
1322; RV32-NEXT:    mulh t1, a1, a3
1323; RV32-NEXT:    mul a1, a1, a3
1324; RV32-NEXT:    mulhsu a3, a3, a0
1325; RV32-NEXT:    mul a2, a0, a2
1326; RV32-NEXT:    add a5, a6, a5
1327; RV32-NEXT:    sltu a0, a5, a6
1328; RV32-NEXT:    add a5, t0, a5
1329; RV32-NEXT:    add a0, a7, a0
1330; RV32-NEXT:    sltu a6, a5, t0
1331; RV32-NEXT:    srai a7, a5, 31
1332; RV32-NEXT:    add a3, a3, a6
1333; RV32-NEXT:    srai a6, a0, 31
1334; RV32-NEXT:    add t0, a0, a3
1335; RV32-NEXT:    srai a3, a3, 31
1336; RV32-NEXT:    sltu a0, t0, a0
1337; RV32-NEXT:    add a3, a6, a3
1338; RV32-NEXT:    add t0, a1, t0
1339; RV32-NEXT:    add a0, a3, a0
1340; RV32-NEXT:    sltu a1, t0, a1
1341; RV32-NEXT:    xor a3, t0, a7
1342; RV32-NEXT:    add a0, t1, a0
1343; RV32-NEXT:    add a0, a0, a1
1344; RV32-NEXT:    xor a0, a0, a7
1345; RV32-NEXT:    or a0, a3, a0
1346; RV32-NEXT:    snez a0, a0
1347; RV32-NEXT:    sw a2, 0(a4)
1348; RV32-NEXT:    sw a5, 4(a4)
1349; RV32-NEXT:    ret
1350;
1351; RV64-LABEL: smulo.i64:
1352; RV64:       # %bb.0: # %entry
1353; RV64-NEXT:    mulh a3, a0, a1
1354; RV64-NEXT:    mul a1, a0, a1
1355; RV64-NEXT:    srai a0, a1, 63
1356; RV64-NEXT:    xor a0, a3, a0
1357; RV64-NEXT:    snez a0, a0
1358; RV64-NEXT:    sd a1, 0(a2)
1359; RV64-NEXT:    ret
1360;
1361; RV32ZBA-LABEL: smulo.i64:
1362; RV32ZBA:       # %bb.0: # %entry
1363; RV32ZBA-NEXT:    mulhu a5, a0, a2
1364; RV32ZBA-NEXT:    mul a6, a1, a2
1365; RV32ZBA-NEXT:    mulhsu a7, a1, a2
1366; RV32ZBA-NEXT:    mul t0, a3, a0
1367; RV32ZBA-NEXT:    mulh t1, a1, a3
1368; RV32ZBA-NEXT:    mul a1, a1, a3
1369; RV32ZBA-NEXT:    mulhsu a3, a3, a0
1370; RV32ZBA-NEXT:    mul a2, a0, a2
1371; RV32ZBA-NEXT:    add a5, a6, a5
1372; RV32ZBA-NEXT:    sltu a0, a5, a6
1373; RV32ZBA-NEXT:    add a5, t0, a5
1374; RV32ZBA-NEXT:    add a0, a7, a0
1375; RV32ZBA-NEXT:    sltu a6, a5, t0
1376; RV32ZBA-NEXT:    srai a7, a5, 31
1377; RV32ZBA-NEXT:    add a3, a3, a6
1378; RV32ZBA-NEXT:    srai a6, a0, 31
1379; RV32ZBA-NEXT:    add t0, a0, a3
1380; RV32ZBA-NEXT:    srai a3, a3, 31
1381; RV32ZBA-NEXT:    sltu a0, t0, a0
1382; RV32ZBA-NEXT:    add a3, a6, a3
1383; RV32ZBA-NEXT:    add t0, a1, t0
1384; RV32ZBA-NEXT:    add a0, a3, a0
1385; RV32ZBA-NEXT:    sltu a1, t0, a1
1386; RV32ZBA-NEXT:    xor a3, t0, a7
1387; RV32ZBA-NEXT:    add a0, t1, a0
1388; RV32ZBA-NEXT:    add a0, a0, a1
1389; RV32ZBA-NEXT:    xor a0, a0, a7
1390; RV32ZBA-NEXT:    or a0, a3, a0
1391; RV32ZBA-NEXT:    snez a0, a0
1392; RV32ZBA-NEXT:    sw a2, 0(a4)
1393; RV32ZBA-NEXT:    sw a5, 4(a4)
1394; RV32ZBA-NEXT:    ret
1395;
1396; RV64ZBA-LABEL: smulo.i64:
1397; RV64ZBA:       # %bb.0: # %entry
1398; RV64ZBA-NEXT:    mulh a3, a0, a1
1399; RV64ZBA-NEXT:    mul a1, a0, a1
1400; RV64ZBA-NEXT:    srai a0, a1, 63
1401; RV64ZBA-NEXT:    xor a0, a3, a0
1402; RV64ZBA-NEXT:    snez a0, a0
1403; RV64ZBA-NEXT:    sd a1, 0(a2)
1404; RV64ZBA-NEXT:    ret
1405;
1406; RV32ZICOND-LABEL: smulo.i64:
1407; RV32ZICOND:       # %bb.0: # %entry
1408; RV32ZICOND-NEXT:    mulhu a5, a0, a2
1409; RV32ZICOND-NEXT:    mul a6, a1, a2
1410; RV32ZICOND-NEXT:    mulhsu a7, a1, a2
1411; RV32ZICOND-NEXT:    mul t0, a3, a0
1412; RV32ZICOND-NEXT:    mulh t1, a1, a3
1413; RV32ZICOND-NEXT:    mul a1, a1, a3
1414; RV32ZICOND-NEXT:    mulhsu a3, a3, a0
1415; RV32ZICOND-NEXT:    mul a2, a0, a2
1416; RV32ZICOND-NEXT:    add a5, a6, a5
1417; RV32ZICOND-NEXT:    sltu a0, a5, a6
1418; RV32ZICOND-NEXT:    add a5, t0, a5
1419; RV32ZICOND-NEXT:    add a0, a7, a0
1420; RV32ZICOND-NEXT:    sltu a6, a5, t0
1421; RV32ZICOND-NEXT:    srai a7, a5, 31
1422; RV32ZICOND-NEXT:    add a3, a3, a6
1423; RV32ZICOND-NEXT:    srai a6, a0, 31
1424; RV32ZICOND-NEXT:    add t0, a0, a3
1425; RV32ZICOND-NEXT:    srai a3, a3, 31
1426; RV32ZICOND-NEXT:    sltu a0, t0, a0
1427; RV32ZICOND-NEXT:    add a3, a6, a3
1428; RV32ZICOND-NEXT:    add t0, a1, t0
1429; RV32ZICOND-NEXT:    add a0, a3, a0
1430; RV32ZICOND-NEXT:    sltu a1, t0, a1
1431; RV32ZICOND-NEXT:    xor a3, t0, a7
1432; RV32ZICOND-NEXT:    add a0, t1, a0
1433; RV32ZICOND-NEXT:    add a0, a0, a1
1434; RV32ZICOND-NEXT:    xor a0, a0, a7
1435; RV32ZICOND-NEXT:    or a0, a3, a0
1436; RV32ZICOND-NEXT:    snez a0, a0
1437; RV32ZICOND-NEXT:    sw a2, 0(a4)
1438; RV32ZICOND-NEXT:    sw a5, 4(a4)
1439; RV32ZICOND-NEXT:    ret
1440;
1441; RV64ZICOND-LABEL: smulo.i64:
1442; RV64ZICOND:       # %bb.0: # %entry
1443; RV64ZICOND-NEXT:    mulh a3, a0, a1
1444; RV64ZICOND-NEXT:    mul a1, a0, a1
1445; RV64ZICOND-NEXT:    srai a0, a1, 63
1446; RV64ZICOND-NEXT:    xor a0, a3, a0
1447; RV64ZICOND-NEXT:    snez a0, a0
1448; RV64ZICOND-NEXT:    sd a1, 0(a2)
1449; RV64ZICOND-NEXT:    ret
1450entry:
1451  %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
1452  %val = extractvalue {i64, i1} %t, 0
1453  %obit = extractvalue {i64, i1} %t, 1
1454  store i64 %val, ptr %res
1455  ret i1 %obit
1456}
1457
1458define zeroext i1 @smulo2.i64(i64 %v1, ptr %res) {
1459; RV32-LABEL: smulo2.i64:
1460; RV32:       # %bb.0: # %entry
1461; RV32-NEXT:    li a3, 13
1462; RV32-NEXT:    mulhu a4, a0, a3
1463; RV32-NEXT:    mul a5, a1, a3
1464; RV32-NEXT:    mulh a1, a1, a3
1465; RV32-NEXT:    mul a3, a0, a3
1466; RV32-NEXT:    add a4, a5, a4
1467; RV32-NEXT:    sltu a0, a4, a5
1468; RV32-NEXT:    srai a5, a4, 31
1469; RV32-NEXT:    add a0, a1, a0
1470; RV32-NEXT:    xor a1, a0, a5
1471; RV32-NEXT:    srai a0, a0, 31
1472; RV32-NEXT:    xor a0, a0, a5
1473; RV32-NEXT:    or a0, a1, a0
1474; RV32-NEXT:    snez a0, a0
1475; RV32-NEXT:    sw a3, 0(a2)
1476; RV32-NEXT:    sw a4, 4(a2)
1477; RV32-NEXT:    ret
1478;
1479; RV64-LABEL: smulo2.i64:
1480; RV64:       # %bb.0: # %entry
1481; RV64-NEXT:    li a2, 13
1482; RV64-NEXT:    mulh a3, a0, a2
1483; RV64-NEXT:    mul a2, a0, a2
1484; RV64-NEXT:    srai a0, a2, 63
1485; RV64-NEXT:    xor a0, a3, a0
1486; RV64-NEXT:    snez a0, a0
1487; RV64-NEXT:    sd a2, 0(a1)
1488; RV64-NEXT:    ret
1489;
1490; RV32ZBA-LABEL: smulo2.i64:
1491; RV32ZBA:       # %bb.0: # %entry
1492; RV32ZBA-NEXT:    li a3, 13
1493; RV32ZBA-NEXT:    sh1add a4, a1, a1
1494; RV32ZBA-NEXT:    sh1add a5, a0, a0
1495; RV32ZBA-NEXT:    sh2add a4, a4, a1
1496; RV32ZBA-NEXT:    mulh a1, a1, a3
1497; RV32ZBA-NEXT:    mulhu a3, a0, a3
1498; RV32ZBA-NEXT:    sh2add a5, a5, a0
1499; RV32ZBA-NEXT:    add a3, a4, a3
1500; RV32ZBA-NEXT:    sltu a0, a3, a4
1501; RV32ZBA-NEXT:    srai a4, a3, 31
1502; RV32ZBA-NEXT:    add a0, a1, a0
1503; RV32ZBA-NEXT:    xor a1, a0, a4
1504; RV32ZBA-NEXT:    srai a0, a0, 31
1505; RV32ZBA-NEXT:    xor a0, a0, a4
1506; RV32ZBA-NEXT:    or a0, a1, a0
1507; RV32ZBA-NEXT:    snez a0, a0
1508; RV32ZBA-NEXT:    sw a5, 0(a2)
1509; RV32ZBA-NEXT:    sw a3, 4(a2)
1510; RV32ZBA-NEXT:    ret
1511;
1512; RV64ZBA-LABEL: smulo2.i64:
1513; RV64ZBA:       # %bb.0: # %entry
1514; RV64ZBA-NEXT:    li a2, 13
1515; RV64ZBA-NEXT:    sh1add a3, a0, a0
1516; RV64ZBA-NEXT:    mulh a2, a0, a2
1517; RV64ZBA-NEXT:    sh2add a3, a3, a0
1518; RV64ZBA-NEXT:    srai a0, a3, 63
1519; RV64ZBA-NEXT:    xor a0, a2, a0
1520; RV64ZBA-NEXT:    snez a0, a0
1521; RV64ZBA-NEXT:    sd a3, 0(a1)
1522; RV64ZBA-NEXT:    ret
1523;
1524; RV32ZICOND-LABEL: smulo2.i64:
1525; RV32ZICOND:       # %bb.0: # %entry
1526; RV32ZICOND-NEXT:    li a3, 13
1527; RV32ZICOND-NEXT:    mulhu a4, a0, a3
1528; RV32ZICOND-NEXT:    mul a5, a1, a3
1529; RV32ZICOND-NEXT:    mulh a1, a1, a3
1530; RV32ZICOND-NEXT:    mul a3, a0, a3
1531; RV32ZICOND-NEXT:    add a4, a5, a4
1532; RV32ZICOND-NEXT:    sltu a0, a4, a5
1533; RV32ZICOND-NEXT:    srai a5, a4, 31
1534; RV32ZICOND-NEXT:    add a0, a1, a0
1535; RV32ZICOND-NEXT:    xor a1, a0, a5
1536; RV32ZICOND-NEXT:    srai a0, a0, 31
1537; RV32ZICOND-NEXT:    xor a0, a0, a5
1538; RV32ZICOND-NEXT:    or a0, a1, a0
1539; RV32ZICOND-NEXT:    snez a0, a0
1540; RV32ZICOND-NEXT:    sw a3, 0(a2)
1541; RV32ZICOND-NEXT:    sw a4, 4(a2)
1542; RV32ZICOND-NEXT:    ret
1543;
1544; RV64ZICOND-LABEL: smulo2.i64:
1545; RV64ZICOND:       # %bb.0: # %entry
1546; RV64ZICOND-NEXT:    li a2, 13
1547; RV64ZICOND-NEXT:    mulh a3, a0, a2
1548; RV64ZICOND-NEXT:    mul a2, a0, a2
1549; RV64ZICOND-NEXT:    srai a0, a2, 63
1550; RV64ZICOND-NEXT:    xor a0, a3, a0
1551; RV64ZICOND-NEXT:    snez a0, a0
1552; RV64ZICOND-NEXT:    sd a2, 0(a1)
1553; RV64ZICOND-NEXT:    ret
1554entry:
1555  %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 13)
1556  %val = extractvalue {i64, i1} %t, 0
1557  %obit = extractvalue {i64, i1} %t, 1
1558  store i64 %val, ptr %res
1559  ret i1 %obit
1560}
1561
1562define zeroext i1 @umulo.i32(i32 signext %v1, i32 signext %v2, ptr %res) {
1563; RV32-LABEL: umulo.i32:
1564; RV32:       # %bb.0: # %entry
1565; RV32-NEXT:    mulhu a3, a0, a1
1566; RV32-NEXT:    snez a3, a3
1567; RV32-NEXT:    mul a0, a0, a1
1568; RV32-NEXT:    sw a0, 0(a2)
1569; RV32-NEXT:    mv a0, a3
1570; RV32-NEXT:    ret
1571;
1572; RV64-LABEL: umulo.i32:
1573; RV64:       # %bb.0: # %entry
1574; RV64-NEXT:    slli a1, a1, 32
1575; RV64-NEXT:    slli a0, a0, 32
1576; RV64-NEXT:    mulhu a1, a0, a1
1577; RV64-NEXT:    srli a0, a1, 32
1578; RV64-NEXT:    snez a0, a0
1579; RV64-NEXT:    sw a1, 0(a2)
1580; RV64-NEXT:    ret
1581;
1582; RV32ZBA-LABEL: umulo.i32:
1583; RV32ZBA:       # %bb.0: # %entry
1584; RV32ZBA-NEXT:    mulhu a3, a0, a1
1585; RV32ZBA-NEXT:    snez a3, a3
1586; RV32ZBA-NEXT:    mul a0, a0, a1
1587; RV32ZBA-NEXT:    sw a0, 0(a2)
1588; RV32ZBA-NEXT:    mv a0, a3
1589; RV32ZBA-NEXT:    ret
1590;
1591; RV64ZBA-LABEL: umulo.i32:
1592; RV64ZBA:       # %bb.0: # %entry
1593; RV64ZBA-NEXT:    zext.w a1, a1
1594; RV64ZBA-NEXT:    zext.w a0, a0
1595; RV64ZBA-NEXT:    mul a1, a0, a1
1596; RV64ZBA-NEXT:    srli a0, a1, 32
1597; RV64ZBA-NEXT:    snez a0, a0
1598; RV64ZBA-NEXT:    sw a1, 0(a2)
1599; RV64ZBA-NEXT:    ret
1600;
1601; RV32ZICOND-LABEL: umulo.i32:
1602; RV32ZICOND:       # %bb.0: # %entry
1603; RV32ZICOND-NEXT:    mulhu a3, a0, a1
1604; RV32ZICOND-NEXT:    snez a3, a3
1605; RV32ZICOND-NEXT:    mul a0, a0, a1
1606; RV32ZICOND-NEXT:    sw a0, 0(a2)
1607; RV32ZICOND-NEXT:    mv a0, a3
1608; RV32ZICOND-NEXT:    ret
1609;
1610; RV64ZICOND-LABEL: umulo.i32:
1611; RV64ZICOND:       # %bb.0: # %entry
1612; RV64ZICOND-NEXT:    slli a1, a1, 32
1613; RV64ZICOND-NEXT:    slli a0, a0, 32
1614; RV64ZICOND-NEXT:    mulhu a1, a0, a1
1615; RV64ZICOND-NEXT:    srli a0, a1, 32
1616; RV64ZICOND-NEXT:    snez a0, a0
1617; RV64ZICOND-NEXT:    sw a1, 0(a2)
1618; RV64ZICOND-NEXT:    ret
1619entry:
1620  %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
1621  %val = extractvalue {i32, i1} %t, 0
1622  %obit = extractvalue {i32, i1} %t, 1
1623  store i32 %val, ptr %res
1624  ret i1 %obit
1625}
1626
1627define zeroext i1 @umulo2.i32(i32 signext %v1, ptr %res) {
1628; RV32-LABEL: umulo2.i32:
1629; RV32:       # %bb.0: # %entry
1630; RV32-NEXT:    li a3, 13
1631; RV32-NEXT:    mulhu a2, a0, a3
1632; RV32-NEXT:    snez a2, a2
1633; RV32-NEXT:    mul a0, a0, a3
1634; RV32-NEXT:    sw a0, 0(a1)
1635; RV32-NEXT:    mv a0, a2
1636; RV32-NEXT:    ret
1637;
1638; RV64-LABEL: umulo2.i32:
1639; RV64:       # %bb.0: # %entry
1640; RV64-NEXT:    li a2, 13
1641; RV64-NEXT:    slli a2, a2, 32
1642; RV64-NEXT:    slli a0, a0, 32
1643; RV64-NEXT:    mulhu a2, a0, a2
1644; RV64-NEXT:    srli a0, a2, 32
1645; RV64-NEXT:    snez a0, a0
1646; RV64-NEXT:    sw a2, 0(a1)
1647; RV64-NEXT:    ret
1648;
1649; RV32ZBA-LABEL: umulo2.i32:
1650; RV32ZBA:       # %bb.0: # %entry
1651; RV32ZBA-NEXT:    li a2, 13
1652; RV32ZBA-NEXT:    sh1add a3, a0, a0
1653; RV32ZBA-NEXT:    mulhu a2, a0, a2
1654; RV32ZBA-NEXT:    snez a2, a2
1655; RV32ZBA-NEXT:    sh2add a0, a3, a0
1656; RV32ZBA-NEXT:    sw a0, 0(a1)
1657; RV32ZBA-NEXT:    mv a0, a2
1658; RV32ZBA-NEXT:    ret
1659;
1660; RV64ZBA-LABEL: umulo2.i32:
1661; RV64ZBA:       # %bb.0: # %entry
1662; RV64ZBA-NEXT:    zext.w a2, a0
1663; RV64ZBA-NEXT:    sh1add.uw a0, a0, a2
1664; RV64ZBA-NEXT:    sh2add a2, a0, a2
1665; RV64ZBA-NEXT:    srli a0, a2, 32
1666; RV64ZBA-NEXT:    snez a0, a0
1667; RV64ZBA-NEXT:    sw a2, 0(a1)
1668; RV64ZBA-NEXT:    ret
1669;
1670; RV32ZICOND-LABEL: umulo2.i32:
1671; RV32ZICOND:       # %bb.0: # %entry
1672; RV32ZICOND-NEXT:    li a3, 13
1673; RV32ZICOND-NEXT:    mulhu a2, a0, a3
1674; RV32ZICOND-NEXT:    snez a2, a2
1675; RV32ZICOND-NEXT:    mul a0, a0, a3
1676; RV32ZICOND-NEXT:    sw a0, 0(a1)
1677; RV32ZICOND-NEXT:    mv a0, a2
1678; RV32ZICOND-NEXT:    ret
1679;
1680; RV64ZICOND-LABEL: umulo2.i32:
1681; RV64ZICOND:       # %bb.0: # %entry
1682; RV64ZICOND-NEXT:    li a2, 13
1683; RV64ZICOND-NEXT:    slli a2, a2, 32
1684; RV64ZICOND-NEXT:    slli a0, a0, 32
1685; RV64ZICOND-NEXT:    mulhu a2, a0, a2
1686; RV64ZICOND-NEXT:    srli a0, a2, 32
1687; RV64ZICOND-NEXT:    snez a0, a0
1688; RV64ZICOND-NEXT:    sw a2, 0(a1)
1689; RV64ZICOND-NEXT:    ret
1690entry:
1691  %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 13)
1692  %val = extractvalue {i32, i1} %t, 0
1693  %obit = extractvalue {i32, i1} %t, 1
1694  store i32 %val, ptr %res
1695  ret i1 %obit
1696}
1697
1698; Similar to umulo.i32, but storing the overflow and returning the result.
1699define signext i32 @umulo3.i32(i32 signext %0, i32 signext %1, ptr %2) {
1700; RV32-LABEL: umulo3.i32:
1701; RV32:       # %bb.0:
1702; RV32-NEXT:    mul a3, a0, a1
1703; RV32-NEXT:    mulhu a0, a0, a1
1704; RV32-NEXT:    snez a0, a0
1705; RV32-NEXT:    sw a0, 0(a2)
1706; RV32-NEXT:    mv a0, a3
1707; RV32-NEXT:    ret
1708;
1709; RV64-LABEL: umulo3.i32:
1710; RV64:       # %bb.0:
1711; RV64-NEXT:    slli a1, a1, 32
1712; RV64-NEXT:    slli a0, a0, 32
1713; RV64-NEXT:    mulhu a0, a0, a1
1714; RV64-NEXT:    srli a1, a0, 32
1715; RV64-NEXT:    snez a1, a1
1716; RV64-NEXT:    sext.w a0, a0
1717; RV64-NEXT:    sw a1, 0(a2)
1718; RV64-NEXT:    ret
1719;
1720; RV32ZBA-LABEL: umulo3.i32:
1721; RV32ZBA:       # %bb.0:
1722; RV32ZBA-NEXT:    mul a3, a0, a1
1723; RV32ZBA-NEXT:    mulhu a0, a0, a1
1724; RV32ZBA-NEXT:    snez a0, a0
1725; RV32ZBA-NEXT:    sw a0, 0(a2)
1726; RV32ZBA-NEXT:    mv a0, a3
1727; RV32ZBA-NEXT:    ret
1728;
1729; RV64ZBA-LABEL: umulo3.i32:
1730; RV64ZBA:       # %bb.0:
1731; RV64ZBA-NEXT:    zext.w a1, a1
1732; RV64ZBA-NEXT:    zext.w a0, a0
1733; RV64ZBA-NEXT:    mul a3, a0, a1
1734; RV64ZBA-NEXT:    srli a3, a3, 32
1735; RV64ZBA-NEXT:    snez a3, a3
1736; RV64ZBA-NEXT:    mulw a0, a0, a1
1737; RV64ZBA-NEXT:    sw a3, 0(a2)
1738; RV64ZBA-NEXT:    ret
1739;
1740; RV32ZICOND-LABEL: umulo3.i32:
1741; RV32ZICOND:       # %bb.0:
1742; RV32ZICOND-NEXT:    mul a3, a0, a1
1743; RV32ZICOND-NEXT:    mulhu a0, a0, a1
1744; RV32ZICOND-NEXT:    snez a0, a0
1745; RV32ZICOND-NEXT:    sw a0, 0(a2)
1746; RV32ZICOND-NEXT:    mv a0, a3
1747; RV32ZICOND-NEXT:    ret
1748;
1749; RV64ZICOND-LABEL: umulo3.i32:
1750; RV64ZICOND:       # %bb.0:
1751; RV64ZICOND-NEXT:    slli a1, a1, 32
1752; RV64ZICOND-NEXT:    slli a0, a0, 32
1753; RV64ZICOND-NEXT:    mulhu a0, a0, a1
1754; RV64ZICOND-NEXT:    srli a1, a0, 32
1755; RV64ZICOND-NEXT:    snez a1, a1
1756; RV64ZICOND-NEXT:    sext.w a0, a0
1757; RV64ZICOND-NEXT:    sw a1, 0(a2)
1758; RV64ZICOND-NEXT:    ret
1759  %4 = tail call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %0, i32 %1)
1760  %5 = extractvalue { i32, i1 } %4, 1
1761  %6 = extractvalue { i32, i1 } %4, 0
1762  %7 = zext i1 %5 to i32
1763  store i32 %7, ptr %2, align 4
1764  ret i32 %6
1765}
1766
1767define zeroext i1 @umulo.i64(i64 %v1, i64 %v2, ptr %res) {
1768; RV32-LABEL: umulo.i64:
1769; RV32:       # %bb.0: # %entry
1770; RV32-NEXT:    mul a5, a3, a0
1771; RV32-NEXT:    mul a6, a1, a2
1772; RV32-NEXT:    mulhu a7, a0, a2
1773; RV32-NEXT:    snez t0, a3
1774; RV32-NEXT:    mulhu a3, a3, a0
1775; RV32-NEXT:    mul t1, a0, a2
1776; RV32-NEXT:    mulhu a0, a1, a2
1777; RV32-NEXT:    snez a1, a1
1778; RV32-NEXT:    add a5, a6, a5
1779; RV32-NEXT:    and a1, a1, t0
1780; RV32-NEXT:    snez a0, a0
1781; RV32-NEXT:    snez a2, a3
1782; RV32-NEXT:    add a5, a7, a5
1783; RV32-NEXT:    or a0, a1, a0
1784; RV32-NEXT:    sltu a1, a5, a7
1785; RV32-NEXT:    or a0, a0, a2
1786; RV32-NEXT:    or a0, a0, a1
1787; RV32-NEXT:    sw t1, 0(a4)
1788; RV32-NEXT:    sw a5, 4(a4)
1789; RV32-NEXT:    ret
1790;
1791; RV64-LABEL: umulo.i64:
1792; RV64:       # %bb.0: # %entry
1793; RV64-NEXT:    mulhu a3, a0, a1
1794; RV64-NEXT:    snez a3, a3
1795; RV64-NEXT:    mul a0, a0, a1
1796; RV64-NEXT:    sd a0, 0(a2)
1797; RV64-NEXT:    mv a0, a3
1798; RV64-NEXT:    ret
1799;
1800; RV32ZBA-LABEL: umulo.i64:
1801; RV32ZBA:       # %bb.0: # %entry
1802; RV32ZBA-NEXT:    mul a5, a3, a0
1803; RV32ZBA-NEXT:    mul a6, a1, a2
1804; RV32ZBA-NEXT:    mulhu a7, a0, a2
1805; RV32ZBA-NEXT:    snez t0, a3
1806; RV32ZBA-NEXT:    mulhu a3, a3, a0
1807; RV32ZBA-NEXT:    mul t1, a0, a2
1808; RV32ZBA-NEXT:    mulhu a0, a1, a2
1809; RV32ZBA-NEXT:    snez a1, a1
1810; RV32ZBA-NEXT:    add a5, a6, a5
1811; RV32ZBA-NEXT:    and a1, a1, t0
1812; RV32ZBA-NEXT:    snez a0, a0
1813; RV32ZBA-NEXT:    snez a2, a3
1814; RV32ZBA-NEXT:    add a5, a7, a5
1815; RV32ZBA-NEXT:    or a0, a1, a0
1816; RV32ZBA-NEXT:    sltu a1, a5, a7
1817; RV32ZBA-NEXT:    or a0, a0, a2
1818; RV32ZBA-NEXT:    or a0, a0, a1
1819; RV32ZBA-NEXT:    sw t1, 0(a4)
1820; RV32ZBA-NEXT:    sw a5, 4(a4)
1821; RV32ZBA-NEXT:    ret
1822;
1823; RV64ZBA-LABEL: umulo.i64:
1824; RV64ZBA:       # %bb.0: # %entry
1825; RV64ZBA-NEXT:    mulhu a3, a0, a1
1826; RV64ZBA-NEXT:    snez a3, a3
1827; RV64ZBA-NEXT:    mul a0, a0, a1
1828; RV64ZBA-NEXT:    sd a0, 0(a2)
1829; RV64ZBA-NEXT:    mv a0, a3
1830; RV64ZBA-NEXT:    ret
1831;
1832; RV32ZICOND-LABEL: umulo.i64:
1833; RV32ZICOND:       # %bb.0: # %entry
1834; RV32ZICOND-NEXT:    mul a5, a3, a0
1835; RV32ZICOND-NEXT:    mul a6, a1, a2
1836; RV32ZICOND-NEXT:    mulhu a7, a0, a2
1837; RV32ZICOND-NEXT:    snez t0, a3
1838; RV32ZICOND-NEXT:    mulhu a3, a3, a0
1839; RV32ZICOND-NEXT:    mul t1, a0, a2
1840; RV32ZICOND-NEXT:    mulhu a0, a1, a2
1841; RV32ZICOND-NEXT:    snez a1, a1
1842; RV32ZICOND-NEXT:    add a5, a6, a5
1843; RV32ZICOND-NEXT:    and a1, a1, t0
1844; RV32ZICOND-NEXT:    snez a0, a0
1845; RV32ZICOND-NEXT:    snez a2, a3
1846; RV32ZICOND-NEXT:    add a5, a7, a5
1847; RV32ZICOND-NEXT:    or a0, a1, a0
1848; RV32ZICOND-NEXT:    sltu a1, a5, a7
1849; RV32ZICOND-NEXT:    or a0, a0, a2
1850; RV32ZICOND-NEXT:    or a0, a0, a1
1851; RV32ZICOND-NEXT:    sw t1, 0(a4)
1852; RV32ZICOND-NEXT:    sw a5, 4(a4)
1853; RV32ZICOND-NEXT:    ret
1854;
1855; RV64ZICOND-LABEL: umulo.i64:
1856; RV64ZICOND:       # %bb.0: # %entry
1857; RV64ZICOND-NEXT:    mulhu a3, a0, a1
1858; RV64ZICOND-NEXT:    snez a3, a3
1859; RV64ZICOND-NEXT:    mul a0, a0, a1
1860; RV64ZICOND-NEXT:    sd a0, 0(a2)
1861; RV64ZICOND-NEXT:    mv a0, a3
1862; RV64ZICOND-NEXT:    ret
1863entry:
1864  %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
1865  %val = extractvalue {i64, i1} %t, 0
1866  %obit = extractvalue {i64, i1} %t, 1
1867  store i64 %val, ptr %res
1868  ret i1 %obit
1869}
1870
1871define zeroext i1 @umulo2.i64(i64 %v1, ptr %res) {
1872; RV32-LABEL: umulo2.i64:
1873; RV32:       # %bb.0: # %entry
1874; RV32-NEXT:    li a3, 13
1875; RV32-NEXT:    mul a4, a1, a3
1876; RV32-NEXT:    mulhu a5, a0, a3
1877; RV32-NEXT:    mulhu a1, a1, a3
1878; RV32-NEXT:    mul a3, a0, a3
1879; RV32-NEXT:    add a4, a5, a4
1880; RV32-NEXT:    snez a0, a1
1881; RV32-NEXT:    sltu a1, a4, a5
1882; RV32-NEXT:    or a0, a0, a1
1883; RV32-NEXT:    sw a3, 0(a2)
1884; RV32-NEXT:    sw a4, 4(a2)
1885; RV32-NEXT:    ret
1886;
1887; RV64-LABEL: umulo2.i64:
1888; RV64:       # %bb.0: # %entry
1889; RV64-NEXT:    li a3, 13
1890; RV64-NEXT:    mulhu a2, a0, a3
1891; RV64-NEXT:    snez a2, a2
1892; RV64-NEXT:    mul a0, a0, a3
1893; RV64-NEXT:    sd a0, 0(a1)
1894; RV64-NEXT:    mv a0, a2
1895; RV64-NEXT:    ret
1896;
1897; RV32ZBA-LABEL: umulo2.i64:
1898; RV32ZBA:       # %bb.0: # %entry
1899; RV32ZBA-NEXT:    li a3, 13
1900; RV32ZBA-NEXT:    sh1add a4, a1, a1
1901; RV32ZBA-NEXT:    sh1add a5, a0, a0
1902; RV32ZBA-NEXT:    sh2add a4, a4, a1
1903; RV32ZBA-NEXT:    mulhu a1, a1, a3
1904; RV32ZBA-NEXT:    mulhu a3, a0, a3
1905; RV32ZBA-NEXT:    sh2add a5, a5, a0
1906; RV32ZBA-NEXT:    add a4, a3, a4
1907; RV32ZBA-NEXT:    snez a0, a1
1908; RV32ZBA-NEXT:    sltu a1, a4, a3
1909; RV32ZBA-NEXT:    or a0, a0, a1
1910; RV32ZBA-NEXT:    sw a5, 0(a2)
1911; RV32ZBA-NEXT:    sw a4, 4(a2)
1912; RV32ZBA-NEXT:    ret
1913;
1914; RV64ZBA-LABEL: umulo2.i64:
1915; RV64ZBA:       # %bb.0: # %entry
1916; RV64ZBA-NEXT:    li a2, 13
1917; RV64ZBA-NEXT:    sh1add a3, a0, a0
1918; RV64ZBA-NEXT:    mulhu a2, a0, a2
1919; RV64ZBA-NEXT:    snez a2, a2
1920; RV64ZBA-NEXT:    sh2add a0, a3, a0
1921; RV64ZBA-NEXT:    sd a0, 0(a1)
1922; RV64ZBA-NEXT:    mv a0, a2
1923; RV64ZBA-NEXT:    ret
1924;
1925; RV32ZICOND-LABEL: umulo2.i64:
1926; RV32ZICOND:       # %bb.0: # %entry
1927; RV32ZICOND-NEXT:    li a3, 13
1928; RV32ZICOND-NEXT:    mul a4, a1, a3
1929; RV32ZICOND-NEXT:    mulhu a5, a0, a3
1930; RV32ZICOND-NEXT:    mulhu a1, a1, a3
1931; RV32ZICOND-NEXT:    mul a3, a0, a3
1932; RV32ZICOND-NEXT:    add a4, a5, a4
1933; RV32ZICOND-NEXT:    snez a0, a1
1934; RV32ZICOND-NEXT:    sltu a1, a4, a5
1935; RV32ZICOND-NEXT:    or a0, a0, a1
1936; RV32ZICOND-NEXT:    sw a3, 0(a2)
1937; RV32ZICOND-NEXT:    sw a4, 4(a2)
1938; RV32ZICOND-NEXT:    ret
1939;
1940; RV64ZICOND-LABEL: umulo2.i64:
1941; RV64ZICOND:       # %bb.0: # %entry
1942; RV64ZICOND-NEXT:    li a3, 13
1943; RV64ZICOND-NEXT:    mulhu a2, a0, a3
1944; RV64ZICOND-NEXT:    snez a2, a2
1945; RV64ZICOND-NEXT:    mul a0, a0, a3
1946; RV64ZICOND-NEXT:    sd a0, 0(a1)
1947; RV64ZICOND-NEXT:    mv a0, a2
1948; RV64ZICOND-NEXT:    ret
1949entry:
1950  %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 13)
1951  %val = extractvalue {i64, i1} %t, 0
1952  %obit = extractvalue {i64, i1} %t, 1
1953  store i64 %val, ptr %res
1954  ret i1 %obit
1955}
1956
1957
1958;
1959; Check the use of the overflow bit in combination with a select instruction.
1960;
1961define i32 @saddo.select.i32(i32 signext %v1, i32 signext %v2) {
1962; RV32-LABEL: saddo.select.i32:
1963; RV32:       # %bb.0: # %entry
1964; RV32-NEXT:    add a2, a0, a1
1965; RV32-NEXT:    slt a2, a2, a0
1966; RV32-NEXT:    slti a3, a1, 0
1967; RV32-NEXT:    bne a3, a2, .LBB28_2
1968; RV32-NEXT:  # %bb.1: # %entry
1969; RV32-NEXT:    mv a0, a1
1970; RV32-NEXT:  .LBB28_2: # %entry
1971; RV32-NEXT:    ret
1972;
1973; RV64-LABEL: saddo.select.i32:
1974; RV64:       # %bb.0: # %entry
1975; RV64-NEXT:    add a2, a0, a1
1976; RV64-NEXT:    addw a3, a0, a1
1977; RV64-NEXT:    bne a3, a2, .LBB28_2
1978; RV64-NEXT:  # %bb.1: # %entry
1979; RV64-NEXT:    mv a0, a1
1980; RV64-NEXT:  .LBB28_2: # %entry
1981; RV64-NEXT:    ret
1982;
1983; RV32ZBA-LABEL: saddo.select.i32:
1984; RV32ZBA:       # %bb.0: # %entry
1985; RV32ZBA-NEXT:    add a2, a0, a1
1986; RV32ZBA-NEXT:    slt a2, a2, a0
1987; RV32ZBA-NEXT:    slti a3, a1, 0
1988; RV32ZBA-NEXT:    bne a3, a2, .LBB28_2
1989; RV32ZBA-NEXT:  # %bb.1: # %entry
1990; RV32ZBA-NEXT:    mv a0, a1
1991; RV32ZBA-NEXT:  .LBB28_2: # %entry
1992; RV32ZBA-NEXT:    ret
1993;
1994; RV64ZBA-LABEL: saddo.select.i32:
1995; RV64ZBA:       # %bb.0: # %entry
1996; RV64ZBA-NEXT:    add a2, a0, a1
1997; RV64ZBA-NEXT:    addw a3, a0, a1
1998; RV64ZBA-NEXT:    bne a3, a2, .LBB28_2
1999; RV64ZBA-NEXT:  # %bb.1: # %entry
2000; RV64ZBA-NEXT:    mv a0, a1
2001; RV64ZBA-NEXT:  .LBB28_2: # %entry
2002; RV64ZBA-NEXT:    ret
2003;
2004; RV32ZICOND-LABEL: saddo.select.i32:
2005; RV32ZICOND:       # %bb.0: # %entry
2006; RV32ZICOND-NEXT:    add a2, a0, a1
2007; RV32ZICOND-NEXT:    slti a3, a1, 0
2008; RV32ZICOND-NEXT:    slt a2, a2, a0
2009; RV32ZICOND-NEXT:    xor a2, a3, a2
2010; RV32ZICOND-NEXT:    czero.nez a1, a1, a2
2011; RV32ZICOND-NEXT:    czero.eqz a0, a0, a2
2012; RV32ZICOND-NEXT:    or a0, a0, a1
2013; RV32ZICOND-NEXT:    ret
2014;
2015; RV64ZICOND-LABEL: saddo.select.i32:
2016; RV64ZICOND:       # %bb.0: # %entry
2017; RV64ZICOND-NEXT:    add a2, a0, a1
2018; RV64ZICOND-NEXT:    addw a3, a0, a1
2019; RV64ZICOND-NEXT:    xor a2, a3, a2
2020; RV64ZICOND-NEXT:    czero.nez a1, a1, a2
2021; RV64ZICOND-NEXT:    czero.eqz a0, a0, a2
2022; RV64ZICOND-NEXT:    or a0, a0, a1
2023; RV64ZICOND-NEXT:    ret
2024entry:
2025  %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2)
2026  %obit = extractvalue {i32, i1} %t, 1
2027  %ret = select i1 %obit, i32 %v1, i32 %v2
2028  ret i32 %ret
2029}
2030
2031define i1 @saddo.not.i32(i32 signext %v1, i32 signext %v2) {
2032; RV32-LABEL: saddo.not.i32:
2033; RV32:       # %bb.0: # %entry
2034; RV32-NEXT:    add a2, a0, a1
2035; RV32-NEXT:    slt a0, a2, a0
2036; RV32-NEXT:    slti a1, a1, 0
2037; RV32-NEXT:    xor a0, a1, a0
2038; RV32-NEXT:    xori a0, a0, 1
2039; RV32-NEXT:    ret
2040;
2041; RV64-LABEL: saddo.not.i32:
2042; RV64:       # %bb.0: # %entry
2043; RV64-NEXT:    add a2, a0, a1
2044; RV64-NEXT:    addw a0, a0, a1
2045; RV64-NEXT:    xor a0, a0, a2
2046; RV64-NEXT:    seqz a0, a0
2047; RV64-NEXT:    ret
2048;
2049; RV32ZBA-LABEL: saddo.not.i32:
2050; RV32ZBA:       # %bb.0: # %entry
2051; RV32ZBA-NEXT:    add a2, a0, a1
2052; RV32ZBA-NEXT:    slt a0, a2, a0
2053; RV32ZBA-NEXT:    slti a1, a1, 0
2054; RV32ZBA-NEXT:    xor a0, a1, a0
2055; RV32ZBA-NEXT:    xori a0, a0, 1
2056; RV32ZBA-NEXT:    ret
2057;
2058; RV64ZBA-LABEL: saddo.not.i32:
2059; RV64ZBA:       # %bb.0: # %entry
2060; RV64ZBA-NEXT:    add a2, a0, a1
2061; RV64ZBA-NEXT:    addw a0, a0, a1
2062; RV64ZBA-NEXT:    xor a0, a0, a2
2063; RV64ZBA-NEXT:    seqz a0, a0
2064; RV64ZBA-NEXT:    ret
2065;
2066; RV32ZICOND-LABEL: saddo.not.i32:
2067; RV32ZICOND:       # %bb.0: # %entry
2068; RV32ZICOND-NEXT:    add a2, a0, a1
2069; RV32ZICOND-NEXT:    slt a0, a2, a0
2070; RV32ZICOND-NEXT:    slti a1, a1, 0
2071; RV32ZICOND-NEXT:    xor a0, a1, a0
2072; RV32ZICOND-NEXT:    xori a0, a0, 1
2073; RV32ZICOND-NEXT:    ret
2074;
2075; RV64ZICOND-LABEL: saddo.not.i32:
2076; RV64ZICOND:       # %bb.0: # %entry
2077; RV64ZICOND-NEXT:    add a2, a0, a1
2078; RV64ZICOND-NEXT:    addw a0, a0, a1
2079; RV64ZICOND-NEXT:    xor a0, a0, a2
2080; RV64ZICOND-NEXT:    seqz a0, a0
2081; RV64ZICOND-NEXT:    ret
2082entry:
2083  %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2)
2084  %obit = extractvalue {i32, i1} %t, 1
2085  %ret = xor i1 %obit, true
2086  ret i1 %ret
2087}
2088
2089define i64 @saddo.select.i64(i64 %v1, i64 %v2) {
2090; RV32-LABEL: saddo.select.i64:
2091; RV32:       # %bb.0: # %entry
2092; RV32-NEXT:    add a4, a1, a3
2093; RV32-NEXT:    add a5, a0, a2
2094; RV32-NEXT:    sltu a5, a5, a0
2095; RV32-NEXT:    add a4, a4, a5
2096; RV32-NEXT:    xor a5, a1, a3
2097; RV32-NEXT:    xor a4, a1, a4
2098; RV32-NEXT:    not a5, a5
2099; RV32-NEXT:    and a4, a5, a4
2100; RV32-NEXT:    bltz a4, .LBB30_2
2101; RV32-NEXT:  # %bb.1: # %entry
2102; RV32-NEXT:    mv a0, a2
2103; RV32-NEXT:    mv a1, a3
2104; RV32-NEXT:  .LBB30_2: # %entry
2105; RV32-NEXT:    ret
2106;
2107; RV64-LABEL: saddo.select.i64:
2108; RV64:       # %bb.0: # %entry
2109; RV64-NEXT:    add a2, a0, a1
2110; RV64-NEXT:    slt a2, a2, a0
2111; RV64-NEXT:    slti a3, a1, 0
2112; RV64-NEXT:    bne a3, a2, .LBB30_2
2113; RV64-NEXT:  # %bb.1: # %entry
2114; RV64-NEXT:    mv a0, a1
2115; RV64-NEXT:  .LBB30_2: # %entry
2116; RV64-NEXT:    ret
2117;
2118; RV32ZBA-LABEL: saddo.select.i64:
2119; RV32ZBA:       # %bb.0: # %entry
2120; RV32ZBA-NEXT:    add a4, a1, a3
2121; RV32ZBA-NEXT:    add a5, a0, a2
2122; RV32ZBA-NEXT:    sltu a5, a5, a0
2123; RV32ZBA-NEXT:    add a4, a4, a5
2124; RV32ZBA-NEXT:    xor a5, a1, a3
2125; RV32ZBA-NEXT:    xor a4, a1, a4
2126; RV32ZBA-NEXT:    not a5, a5
2127; RV32ZBA-NEXT:    and a4, a5, a4
2128; RV32ZBA-NEXT:    bltz a4, .LBB30_2
2129; RV32ZBA-NEXT:  # %bb.1: # %entry
2130; RV32ZBA-NEXT:    mv a0, a2
2131; RV32ZBA-NEXT:    mv a1, a3
2132; RV32ZBA-NEXT:  .LBB30_2: # %entry
2133; RV32ZBA-NEXT:    ret
2134;
2135; RV64ZBA-LABEL: saddo.select.i64:
2136; RV64ZBA:       # %bb.0: # %entry
2137; RV64ZBA-NEXT:    add a2, a0, a1
2138; RV64ZBA-NEXT:    slt a2, a2, a0
2139; RV64ZBA-NEXT:    slti a3, a1, 0
2140; RV64ZBA-NEXT:    bne a3, a2, .LBB30_2
2141; RV64ZBA-NEXT:  # %bb.1: # %entry
2142; RV64ZBA-NEXT:    mv a0, a1
2143; RV64ZBA-NEXT:  .LBB30_2: # %entry
2144; RV64ZBA-NEXT:    ret
2145;
2146; RV32ZICOND-LABEL: saddo.select.i64:
2147; RV32ZICOND:       # %bb.0: # %entry
2148; RV32ZICOND-NEXT:    add a4, a1, a3
2149; RV32ZICOND-NEXT:    add a5, a0, a2
2150; RV32ZICOND-NEXT:    sltu a5, a5, a0
2151; RV32ZICOND-NEXT:    add a4, a4, a5
2152; RV32ZICOND-NEXT:    xor a5, a1, a3
2153; RV32ZICOND-NEXT:    not a5, a5
2154; RV32ZICOND-NEXT:    xor a4, a1, a4
2155; RV32ZICOND-NEXT:    and a4, a5, a4
2156; RV32ZICOND-NEXT:    slti a4, a4, 0
2157; RV32ZICOND-NEXT:    czero.nez a2, a2, a4
2158; RV32ZICOND-NEXT:    czero.eqz a0, a0, a4
2159; RV32ZICOND-NEXT:    czero.nez a3, a3, a4
2160; RV32ZICOND-NEXT:    czero.eqz a1, a1, a4
2161; RV32ZICOND-NEXT:    or a0, a0, a2
2162; RV32ZICOND-NEXT:    or a1, a1, a3
2163; RV32ZICOND-NEXT:    ret
2164;
2165; RV64ZICOND-LABEL: saddo.select.i64:
2166; RV64ZICOND:       # %bb.0: # %entry
2167; RV64ZICOND-NEXT:    add a2, a0, a1
2168; RV64ZICOND-NEXT:    slti a3, a1, 0
2169; RV64ZICOND-NEXT:    slt a2, a2, a0
2170; RV64ZICOND-NEXT:    xor a2, a3, a2
2171; RV64ZICOND-NEXT:    czero.nez a1, a1, a2
2172; RV64ZICOND-NEXT:    czero.eqz a0, a0, a2
2173; RV64ZICOND-NEXT:    or a0, a0, a1
2174; RV64ZICOND-NEXT:    ret
2175entry:
2176  %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2)
2177  %obit = extractvalue {i64, i1} %t, 1
2178  %ret = select i1 %obit, i64 %v1, i64 %v2
2179  ret i64 %ret
2180}
2181
2182define i1 @saddo.not.i64(i64 %v1, i64 %v2) {
2183; RV32-LABEL: saddo.not.i64:
2184; RV32:       # %bb.0: # %entry
2185; RV32-NEXT:    add a4, a1, a3
2186; RV32-NEXT:    add a2, a0, a2
2187; RV32-NEXT:    xor a3, a1, a3
2188; RV32-NEXT:    sltu a0, a2, a0
2189; RV32-NEXT:    add a0, a4, a0
2190; RV32-NEXT:    xor a0, a1, a0
2191; RV32-NEXT:    not a1, a3
2192; RV32-NEXT:    and a0, a1, a0
2193; RV32-NEXT:    slti a0, a0, 0
2194; RV32-NEXT:    xori a0, a0, 1
2195; RV32-NEXT:    ret
2196;
2197; RV64-LABEL: saddo.not.i64:
2198; RV64:       # %bb.0: # %entry
2199; RV64-NEXT:    add a2, a0, a1
2200; RV64-NEXT:    slt a0, a2, a0
2201; RV64-NEXT:    slti a1, a1, 0
2202; RV64-NEXT:    xor a0, a1, a0
2203; RV64-NEXT:    xori a0, a0, 1
2204; RV64-NEXT:    ret
2205;
2206; RV32ZBA-LABEL: saddo.not.i64:
2207; RV32ZBA:       # %bb.0: # %entry
2208; RV32ZBA-NEXT:    add a4, a1, a3
2209; RV32ZBA-NEXT:    add a2, a0, a2
2210; RV32ZBA-NEXT:    xor a3, a1, a3
2211; RV32ZBA-NEXT:    sltu a0, a2, a0
2212; RV32ZBA-NEXT:    add a0, a4, a0
2213; RV32ZBA-NEXT:    xor a0, a1, a0
2214; RV32ZBA-NEXT:    not a1, a3
2215; RV32ZBA-NEXT:    and a0, a1, a0
2216; RV32ZBA-NEXT:    slti a0, a0, 0
2217; RV32ZBA-NEXT:    xori a0, a0, 1
2218; RV32ZBA-NEXT:    ret
2219;
2220; RV64ZBA-LABEL: saddo.not.i64:
2221; RV64ZBA:       # %bb.0: # %entry
2222; RV64ZBA-NEXT:    add a2, a0, a1
2223; RV64ZBA-NEXT:    slt a0, a2, a0
2224; RV64ZBA-NEXT:    slti a1, a1, 0
2225; RV64ZBA-NEXT:    xor a0, a1, a0
2226; RV64ZBA-NEXT:    xori a0, a0, 1
2227; RV64ZBA-NEXT:    ret
2228;
2229; RV32ZICOND-LABEL: saddo.not.i64:
2230; RV32ZICOND:       # %bb.0: # %entry
2231; RV32ZICOND-NEXT:    add a4, a1, a3
2232; RV32ZICOND-NEXT:    add a2, a0, a2
2233; RV32ZICOND-NEXT:    xor a3, a1, a3
2234; RV32ZICOND-NEXT:    sltu a0, a2, a0
2235; RV32ZICOND-NEXT:    add a0, a4, a0
2236; RV32ZICOND-NEXT:    xor a0, a1, a0
2237; RV32ZICOND-NEXT:    not a1, a3
2238; RV32ZICOND-NEXT:    and a0, a1, a0
2239; RV32ZICOND-NEXT:    slti a0, a0, 0
2240; RV32ZICOND-NEXT:    xori a0, a0, 1
2241; RV32ZICOND-NEXT:    ret
2242;
2243; RV64ZICOND-LABEL: saddo.not.i64:
2244; RV64ZICOND:       # %bb.0: # %entry
2245; RV64ZICOND-NEXT:    add a2, a0, a1
2246; RV64ZICOND-NEXT:    slt a0, a2, a0
2247; RV64ZICOND-NEXT:    slti a1, a1, 0
2248; RV64ZICOND-NEXT:    xor a0, a1, a0
2249; RV64ZICOND-NEXT:    xori a0, a0, 1
2250; RV64ZICOND-NEXT:    ret
2251entry:
2252  %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2)
2253  %obit = extractvalue {i64, i1} %t, 1
2254  %ret = xor i1 %obit, true
2255  ret i1 %ret
2256}
2257
2258define i32 @uaddo.select.i32(i32 signext %v1, i32 signext %v2) {
2259; RV32-LABEL: uaddo.select.i32:
2260; RV32:       # %bb.0: # %entry
2261; RV32-NEXT:    add a2, a0, a1
2262; RV32-NEXT:    bltu a2, a0, .LBB32_2
2263; RV32-NEXT:  # %bb.1: # %entry
2264; RV32-NEXT:    mv a0, a1
2265; RV32-NEXT:  .LBB32_2: # %entry
2266; RV32-NEXT:    ret
2267;
2268; RV64-LABEL: uaddo.select.i32:
2269; RV64:       # %bb.0: # %entry
2270; RV64-NEXT:    addw a2, a0, a1
2271; RV64-NEXT:    bltu a2, a0, .LBB32_2
2272; RV64-NEXT:  # %bb.1: # %entry
2273; RV64-NEXT:    mv a0, a1
2274; RV64-NEXT:  .LBB32_2: # %entry
2275; RV64-NEXT:    ret
2276;
2277; RV32ZBA-LABEL: uaddo.select.i32:
2278; RV32ZBA:       # %bb.0: # %entry
2279; RV32ZBA-NEXT:    add a2, a0, a1
2280; RV32ZBA-NEXT:    bltu a2, a0, .LBB32_2
2281; RV32ZBA-NEXT:  # %bb.1: # %entry
2282; RV32ZBA-NEXT:    mv a0, a1
2283; RV32ZBA-NEXT:  .LBB32_2: # %entry
2284; RV32ZBA-NEXT:    ret
2285;
2286; RV64ZBA-LABEL: uaddo.select.i32:
2287; RV64ZBA:       # %bb.0: # %entry
2288; RV64ZBA-NEXT:    addw a2, a0, a1
2289; RV64ZBA-NEXT:    bltu a2, a0, .LBB32_2
2290; RV64ZBA-NEXT:  # %bb.1: # %entry
2291; RV64ZBA-NEXT:    mv a0, a1
2292; RV64ZBA-NEXT:  .LBB32_2: # %entry
2293; RV64ZBA-NEXT:    ret
2294;
2295; RV32ZICOND-LABEL: uaddo.select.i32:
2296; RV32ZICOND:       # %bb.0: # %entry
2297; RV32ZICOND-NEXT:    add a2, a0, a1
2298; RV32ZICOND-NEXT:    sltu a2, a2, a0
2299; RV32ZICOND-NEXT:    czero.nez a1, a1, a2
2300; RV32ZICOND-NEXT:    czero.eqz a0, a0, a2
2301; RV32ZICOND-NEXT:    or a0, a0, a1
2302; RV32ZICOND-NEXT:    ret
2303;
2304; RV64ZICOND-LABEL: uaddo.select.i32:
2305; RV64ZICOND:       # %bb.0: # %entry
2306; RV64ZICOND-NEXT:    addw a2, a0, a1
2307; RV64ZICOND-NEXT:    sltu a2, a2, a0
2308; RV64ZICOND-NEXT:    czero.nez a1, a1, a2
2309; RV64ZICOND-NEXT:    czero.eqz a0, a0, a2
2310; RV64ZICOND-NEXT:    or a0, a0, a1
2311; RV64ZICOND-NEXT:    ret
2312entry:
2313  %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)
2314  %obit = extractvalue {i32, i1} %t, 1
2315  %ret = select i1 %obit, i32 %v1, i32 %v2
2316  ret i32 %ret
2317}
2318
2319define i1 @uaddo.not.i32(i32 signext %v1, i32 signext %v2) {
2320; RV32-LABEL: uaddo.not.i32:
2321; RV32:       # %bb.0: # %entry
2322; RV32-NEXT:    add a1, a0, a1
2323; RV32-NEXT:    sltu a0, a1, a0
2324; RV32-NEXT:    xori a0, a0, 1
2325; RV32-NEXT:    ret
2326;
2327; RV64-LABEL: uaddo.not.i32:
2328; RV64:       # %bb.0: # %entry
2329; RV64-NEXT:    addw a1, a0, a1
2330; RV64-NEXT:    sltu a0, a1, a0
2331; RV64-NEXT:    xori a0, a0, 1
2332; RV64-NEXT:    ret
2333;
2334; RV32ZBA-LABEL: uaddo.not.i32:
2335; RV32ZBA:       # %bb.0: # %entry
2336; RV32ZBA-NEXT:    add a1, a0, a1
2337; RV32ZBA-NEXT:    sltu a0, a1, a0
2338; RV32ZBA-NEXT:    xori a0, a0, 1
2339; RV32ZBA-NEXT:    ret
2340;
2341; RV64ZBA-LABEL: uaddo.not.i32:
2342; RV64ZBA:       # %bb.0: # %entry
2343; RV64ZBA-NEXT:    addw a1, a0, a1
2344; RV64ZBA-NEXT:    sltu a0, a1, a0
2345; RV64ZBA-NEXT:    xori a0, a0, 1
2346; RV64ZBA-NEXT:    ret
2347;
2348; RV32ZICOND-LABEL: uaddo.not.i32:
2349; RV32ZICOND:       # %bb.0: # %entry
2350; RV32ZICOND-NEXT:    add a1, a0, a1
2351; RV32ZICOND-NEXT:    sltu a0, a1, a0
2352; RV32ZICOND-NEXT:    xori a0, a0, 1
2353; RV32ZICOND-NEXT:    ret
2354;
2355; RV64ZICOND-LABEL: uaddo.not.i32:
2356; RV64ZICOND:       # %bb.0: # %entry
2357; RV64ZICOND-NEXT:    addw a1, a0, a1
2358; RV64ZICOND-NEXT:    sltu a0, a1, a0
2359; RV64ZICOND-NEXT:    xori a0, a0, 1
2360; RV64ZICOND-NEXT:    ret
2361entry:
2362  %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)
2363  %obit = extractvalue {i32, i1} %t, 1
2364  %ret = xor i1 %obit, true
2365  ret i1 %ret
2366}
2367
2368define i64 @uaddo.select.i64(i64 %v1, i64 %v2) {
2369; RV32-LABEL: uaddo.select.i64:
2370; RV32:       # %bb.0: # %entry
2371; RV32-NEXT:    add a5, a1, a3
2372; RV32-NEXT:    add a4, a0, a2
2373; RV32-NEXT:    sltu a4, a4, a0
2374; RV32-NEXT:    add a5, a5, a4
2375; RV32-NEXT:    bne a5, a1, .LBB34_3
2376; RV32-NEXT:  # %bb.1: # %entry
2377; RV32-NEXT:    beqz a4, .LBB34_4
2378; RV32-NEXT:  .LBB34_2: # %entry
2379; RV32-NEXT:    ret
2380; RV32-NEXT:  .LBB34_3: # %entry
2381; RV32-NEXT:    sltu a4, a5, a1
2382; RV32-NEXT:    bnez a4, .LBB34_2
2383; RV32-NEXT:  .LBB34_4: # %entry
2384; RV32-NEXT:    mv a0, a2
2385; RV32-NEXT:    mv a1, a3
2386; RV32-NEXT:    ret
2387;
2388; RV64-LABEL: uaddo.select.i64:
2389; RV64:       # %bb.0: # %entry
2390; RV64-NEXT:    add a2, a0, a1
2391; RV64-NEXT:    bltu a2, a0, .LBB34_2
2392; RV64-NEXT:  # %bb.1: # %entry
2393; RV64-NEXT:    mv a0, a1
2394; RV64-NEXT:  .LBB34_2: # %entry
2395; RV64-NEXT:    ret
2396;
2397; RV32ZBA-LABEL: uaddo.select.i64:
2398; RV32ZBA:       # %bb.0: # %entry
2399; RV32ZBA-NEXT:    add a5, a1, a3
2400; RV32ZBA-NEXT:    add a4, a0, a2
2401; RV32ZBA-NEXT:    sltu a4, a4, a0
2402; RV32ZBA-NEXT:    add a5, a5, a4
2403; RV32ZBA-NEXT:    bne a5, a1, .LBB34_3
2404; RV32ZBA-NEXT:  # %bb.1: # %entry
2405; RV32ZBA-NEXT:    beqz a4, .LBB34_4
2406; RV32ZBA-NEXT:  .LBB34_2: # %entry
2407; RV32ZBA-NEXT:    ret
2408; RV32ZBA-NEXT:  .LBB34_3: # %entry
2409; RV32ZBA-NEXT:    sltu a4, a5, a1
2410; RV32ZBA-NEXT:    bnez a4, .LBB34_2
2411; RV32ZBA-NEXT:  .LBB34_4: # %entry
2412; RV32ZBA-NEXT:    mv a0, a2
2413; RV32ZBA-NEXT:    mv a1, a3
2414; RV32ZBA-NEXT:    ret
2415;
2416; RV64ZBA-LABEL: uaddo.select.i64:
2417; RV64ZBA:       # %bb.0: # %entry
2418; RV64ZBA-NEXT:    add a2, a0, a1
2419; RV64ZBA-NEXT:    bltu a2, a0, .LBB34_2
2420; RV64ZBA-NEXT:  # %bb.1: # %entry
2421; RV64ZBA-NEXT:    mv a0, a1
2422; RV64ZBA-NEXT:  .LBB34_2: # %entry
2423; RV64ZBA-NEXT:    ret
2424;
2425; RV32ZICOND-LABEL: uaddo.select.i64:
2426; RV32ZICOND:       # %bb.0: # %entry
2427; RV32ZICOND-NEXT:    add a4, a1, a3
2428; RV32ZICOND-NEXT:    add a5, a0, a2
2429; RV32ZICOND-NEXT:    sltu a5, a5, a0
2430; RV32ZICOND-NEXT:    add a4, a4, a5
2431; RV32ZICOND-NEXT:    xor a6, a4, a1
2432; RV32ZICOND-NEXT:    sltu a4, a4, a1
2433; RV32ZICOND-NEXT:    czero.eqz a4, a4, a6
2434; RV32ZICOND-NEXT:    czero.nez a5, a5, a6
2435; RV32ZICOND-NEXT:    or a4, a5, a4
2436; RV32ZICOND-NEXT:    czero.nez a2, a2, a4
2437; RV32ZICOND-NEXT:    czero.eqz a0, a0, a4
2438; RV32ZICOND-NEXT:    czero.nez a3, a3, a4
2439; RV32ZICOND-NEXT:    czero.eqz a1, a1, a4
2440; RV32ZICOND-NEXT:    or a0, a0, a2
2441; RV32ZICOND-NEXT:    or a1, a1, a3
2442; RV32ZICOND-NEXT:    ret
2443;
2444; RV64ZICOND-LABEL: uaddo.select.i64:
2445; RV64ZICOND:       # %bb.0: # %entry
2446; RV64ZICOND-NEXT:    add a2, a0, a1
2447; RV64ZICOND-NEXT:    sltu a2, a2, a0
2448; RV64ZICOND-NEXT:    czero.nez a1, a1, a2
2449; RV64ZICOND-NEXT:    czero.eqz a0, a0, a2
2450; RV64ZICOND-NEXT:    or a0, a0, a1
2451; RV64ZICOND-NEXT:    ret
2452entry:
2453  %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2)
2454  %obit = extractvalue {i64, i1} %t, 1
2455  %ret = select i1 %obit, i64 %v1, i64 %v2
2456  ret i64 %ret
2457}
2458
2459define i1 @uaddo.not.i64(i64 %v1, i64 %v2) {
2460; RV32-LABEL: uaddo.not.i64:
2461; RV32:       # %bb.0: # %entry
2462; RV32-NEXT:    add a3, a1, a3
2463; RV32-NEXT:    add a2, a0, a2
2464; RV32-NEXT:    sltu a0, a2, a0
2465; RV32-NEXT:    add a2, a3, a0
2466; RV32-NEXT:    beq a2, a1, .LBB35_2
2467; RV32-NEXT:  # %bb.1: # %entry
2468; RV32-NEXT:    sltu a0, a2, a1
2469; RV32-NEXT:  .LBB35_2: # %entry
2470; RV32-NEXT:    xori a0, a0, 1
2471; RV32-NEXT:    ret
2472;
2473; RV64-LABEL: uaddo.not.i64:
2474; RV64:       # %bb.0: # %entry
2475; RV64-NEXT:    add a1, a0, a1
2476; RV64-NEXT:    sltu a0, a1, a0
2477; RV64-NEXT:    xori a0, a0, 1
2478; RV64-NEXT:    ret
2479;
2480; RV32ZBA-LABEL: uaddo.not.i64:
2481; RV32ZBA:       # %bb.0: # %entry
2482; RV32ZBA-NEXT:    add a3, a1, a3
2483; RV32ZBA-NEXT:    add a2, a0, a2
2484; RV32ZBA-NEXT:    sltu a0, a2, a0
2485; RV32ZBA-NEXT:    add a2, a3, a0
2486; RV32ZBA-NEXT:    beq a2, a1, .LBB35_2
2487; RV32ZBA-NEXT:  # %bb.1: # %entry
2488; RV32ZBA-NEXT:    sltu a0, a2, a1
2489; RV32ZBA-NEXT:  .LBB35_2: # %entry
2490; RV32ZBA-NEXT:    xori a0, a0, 1
2491; RV32ZBA-NEXT:    ret
2492;
2493; RV64ZBA-LABEL: uaddo.not.i64:
2494; RV64ZBA:       # %bb.0: # %entry
2495; RV64ZBA-NEXT:    add a1, a0, a1
2496; RV64ZBA-NEXT:    sltu a0, a1, a0
2497; RV64ZBA-NEXT:    xori a0, a0, 1
2498; RV64ZBA-NEXT:    ret
2499;
2500; RV32ZICOND-LABEL: uaddo.not.i64:
2501; RV32ZICOND:       # %bb.0: # %entry
2502; RV32ZICOND-NEXT:    add a3, a1, a3
2503; RV32ZICOND-NEXT:    add a2, a0, a2
2504; RV32ZICOND-NEXT:    sltu a0, a2, a0
2505; RV32ZICOND-NEXT:    add a3, a3, a0
2506; RV32ZICOND-NEXT:    xor a2, a3, a1
2507; RV32ZICOND-NEXT:    sltu a1, a3, a1
2508; RV32ZICOND-NEXT:    czero.eqz a1, a1, a2
2509; RV32ZICOND-NEXT:    czero.nez a0, a0, a2
2510; RV32ZICOND-NEXT:    or a0, a0, a1
2511; RV32ZICOND-NEXT:    xori a0, a0, 1
2512; RV32ZICOND-NEXT:    ret
2513;
2514; RV64ZICOND-LABEL: uaddo.not.i64:
2515; RV64ZICOND:       # %bb.0: # %entry
2516; RV64ZICOND-NEXT:    add a1, a0, a1
2517; RV64ZICOND-NEXT:    sltu a0, a1, a0
2518; RV64ZICOND-NEXT:    xori a0, a0, 1
2519; RV64ZICOND-NEXT:    ret
2520entry:
2521  %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2)
2522  %obit = extractvalue {i64, i1} %t, 1
2523  %ret = xor i1 %obit, true
2524  ret i1 %ret
2525}
2526
2527define i32 @ssubo.select.i32(i32 signext %v1, i32 signext %v2) {
2528; RV32-LABEL: ssubo.select.i32:
2529; RV32:       # %bb.0: # %entry
2530; RV32-NEXT:    sgtz a2, a1
2531; RV32-NEXT:    sub a3, a0, a1
2532; RV32-NEXT:    slt a3, a3, a0
2533; RV32-NEXT:    bne a2, a3, .LBB36_2
2534; RV32-NEXT:  # %bb.1: # %entry
2535; RV32-NEXT:    mv a0, a1
2536; RV32-NEXT:  .LBB36_2: # %entry
2537; RV32-NEXT:    ret
2538;
2539; RV64-LABEL: ssubo.select.i32:
2540; RV64:       # %bb.0: # %entry
2541; RV64-NEXT:    sub a2, a0, a1
2542; RV64-NEXT:    subw a3, a0, a1
2543; RV64-NEXT:    bne a3, a2, .LBB36_2
2544; RV64-NEXT:  # %bb.1: # %entry
2545; RV64-NEXT:    mv a0, a1
2546; RV64-NEXT:  .LBB36_2: # %entry
2547; RV64-NEXT:    ret
2548;
2549; RV32ZBA-LABEL: ssubo.select.i32:
2550; RV32ZBA:       # %bb.0: # %entry
2551; RV32ZBA-NEXT:    sgtz a2, a1
2552; RV32ZBA-NEXT:    sub a3, a0, a1
2553; RV32ZBA-NEXT:    slt a3, a3, a0
2554; RV32ZBA-NEXT:    bne a2, a3, .LBB36_2
2555; RV32ZBA-NEXT:  # %bb.1: # %entry
2556; RV32ZBA-NEXT:    mv a0, a1
2557; RV32ZBA-NEXT:  .LBB36_2: # %entry
2558; RV32ZBA-NEXT:    ret
2559;
2560; RV64ZBA-LABEL: ssubo.select.i32:
2561; RV64ZBA:       # %bb.0: # %entry
2562; RV64ZBA-NEXT:    sub a2, a0, a1
2563; RV64ZBA-NEXT:    subw a3, a0, a1
2564; RV64ZBA-NEXT:    bne a3, a2, .LBB36_2
2565; RV64ZBA-NEXT:  # %bb.1: # %entry
2566; RV64ZBA-NEXT:    mv a0, a1
2567; RV64ZBA-NEXT:  .LBB36_2: # %entry
2568; RV64ZBA-NEXT:    ret
2569;
2570; RV32ZICOND-LABEL: ssubo.select.i32:
2571; RV32ZICOND:       # %bb.0: # %entry
2572; RV32ZICOND-NEXT:    sgtz a2, a1
2573; RV32ZICOND-NEXT:    sub a3, a0, a1
2574; RV32ZICOND-NEXT:    slt a3, a3, a0
2575; RV32ZICOND-NEXT:    xor a2, a2, a3
2576; RV32ZICOND-NEXT:    czero.nez a1, a1, a2
2577; RV32ZICOND-NEXT:    czero.eqz a0, a0, a2
2578; RV32ZICOND-NEXT:    or a0, a0, a1
2579; RV32ZICOND-NEXT:    ret
2580;
2581; RV64ZICOND-LABEL: ssubo.select.i32:
2582; RV64ZICOND:       # %bb.0: # %entry
2583; RV64ZICOND-NEXT:    sub a2, a0, a1
2584; RV64ZICOND-NEXT:    subw a3, a0, a1
2585; RV64ZICOND-NEXT:    xor a2, a3, a2
2586; RV64ZICOND-NEXT:    czero.nez a1, a1, a2
2587; RV64ZICOND-NEXT:    czero.eqz a0, a0, a2
2588; RV64ZICOND-NEXT:    or a0, a0, a1
2589; RV64ZICOND-NEXT:    ret
2590entry:
2591  %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2)
2592  %obit = extractvalue {i32, i1} %t, 1
2593  %ret = select i1 %obit, i32 %v1, i32 %v2
2594  ret i32 %ret
2595}
2596
2597define i1 @ssubo.not.i32(i32 signext %v1, i32 signext %v2) {
2598; RV32-LABEL: ssubo.not.i32:
2599; RV32:       # %bb.0: # %entry
2600; RV32-NEXT:    sgtz a2, a1
2601; RV32-NEXT:    sub a1, a0, a1
2602; RV32-NEXT:    slt a0, a1, a0
2603; RV32-NEXT:    xor a0, a2, a0
2604; RV32-NEXT:    xori a0, a0, 1
2605; RV32-NEXT:    ret
2606;
2607; RV64-LABEL: ssubo.not.i32:
2608; RV64:       # %bb.0: # %entry
2609; RV64-NEXT:    sub a2, a0, a1
2610; RV64-NEXT:    subw a0, a0, a1
2611; RV64-NEXT:    xor a0, a0, a2
2612; RV64-NEXT:    seqz a0, a0
2613; RV64-NEXT:    ret
2614;
2615; RV32ZBA-LABEL: ssubo.not.i32:
2616; RV32ZBA:       # %bb.0: # %entry
2617; RV32ZBA-NEXT:    sgtz a2, a1
2618; RV32ZBA-NEXT:    sub a1, a0, a1
2619; RV32ZBA-NEXT:    slt a0, a1, a0
2620; RV32ZBA-NEXT:    xor a0, a2, a0
2621; RV32ZBA-NEXT:    xori a0, a0, 1
2622; RV32ZBA-NEXT:    ret
2623;
2624; RV64ZBA-LABEL: ssubo.not.i32:
2625; RV64ZBA:       # %bb.0: # %entry
2626; RV64ZBA-NEXT:    sub a2, a0, a1
2627; RV64ZBA-NEXT:    subw a0, a0, a1
2628; RV64ZBA-NEXT:    xor a0, a0, a2
2629; RV64ZBA-NEXT:    seqz a0, a0
2630; RV64ZBA-NEXT:    ret
2631;
2632; RV32ZICOND-LABEL: ssubo.not.i32:
2633; RV32ZICOND:       # %bb.0: # %entry
2634; RV32ZICOND-NEXT:    sgtz a2, a1
2635; RV32ZICOND-NEXT:    sub a1, a0, a1
2636; RV32ZICOND-NEXT:    slt a0, a1, a0
2637; RV32ZICOND-NEXT:    xor a0, a2, a0
2638; RV32ZICOND-NEXT:    xori a0, a0, 1
2639; RV32ZICOND-NEXT:    ret
2640;
2641; RV64ZICOND-LABEL: ssubo.not.i32:
2642; RV64ZICOND:       # %bb.0: # %entry
2643; RV64ZICOND-NEXT:    sub a2, a0, a1
2644; RV64ZICOND-NEXT:    subw a0, a0, a1
2645; RV64ZICOND-NEXT:    xor a0, a0, a2
2646; RV64ZICOND-NEXT:    seqz a0, a0
2647; RV64ZICOND-NEXT:    ret
2648entry:
2649  %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2)
2650  %obit = extractvalue {i32, i1} %t, 1
2651  %ret = xor i1 %obit, true
2652  ret i1 %ret
2653}
2654
2655define i64 @ssubo.select.i64(i64 %v1, i64 %v2) {
2656; RV32-LABEL: ssubo.select.i64:
2657; RV32:       # %bb.0: # %entry
2658; RV32-NEXT:    sltu a4, a0, a2
2659; RV32-NEXT:    sub a5, a1, a3
2660; RV32-NEXT:    sub a5, a5, a4
2661; RV32-NEXT:    xor a5, a1, a5
2662; RV32-NEXT:    xor a4, a1, a3
2663; RV32-NEXT:    and a4, a4, a5
2664; RV32-NEXT:    bltz a4, .LBB38_2
2665; RV32-NEXT:  # %bb.1: # %entry
2666; RV32-NEXT:    mv a0, a2
2667; RV32-NEXT:    mv a1, a3
2668; RV32-NEXT:  .LBB38_2: # %entry
2669; RV32-NEXT:    ret
2670;
2671; RV64-LABEL: ssubo.select.i64:
2672; RV64:       # %bb.0: # %entry
2673; RV64-NEXT:    sgtz a2, a1
2674; RV64-NEXT:    sub a3, a0, a1
2675; RV64-NEXT:    slt a3, a3, a0
2676; RV64-NEXT:    bne a2, a3, .LBB38_2
2677; RV64-NEXT:  # %bb.1: # %entry
2678; RV64-NEXT:    mv a0, a1
2679; RV64-NEXT:  .LBB38_2: # %entry
2680; RV64-NEXT:    ret
2681;
2682; RV32ZBA-LABEL: ssubo.select.i64:
2683; RV32ZBA:       # %bb.0: # %entry
2684; RV32ZBA-NEXT:    sltu a4, a0, a2
2685; RV32ZBA-NEXT:    sub a5, a1, a3
2686; RV32ZBA-NEXT:    sub a5, a5, a4
2687; RV32ZBA-NEXT:    xor a5, a1, a5
2688; RV32ZBA-NEXT:    xor a4, a1, a3
2689; RV32ZBA-NEXT:    and a4, a4, a5
2690; RV32ZBA-NEXT:    bltz a4, .LBB38_2
2691; RV32ZBA-NEXT:  # %bb.1: # %entry
2692; RV32ZBA-NEXT:    mv a0, a2
2693; RV32ZBA-NEXT:    mv a1, a3
2694; RV32ZBA-NEXT:  .LBB38_2: # %entry
2695; RV32ZBA-NEXT:    ret
2696;
2697; RV64ZBA-LABEL: ssubo.select.i64:
2698; RV64ZBA:       # %bb.0: # %entry
2699; RV64ZBA-NEXT:    sgtz a2, a1
2700; RV64ZBA-NEXT:    sub a3, a0, a1
2701; RV64ZBA-NEXT:    slt a3, a3, a0
2702; RV64ZBA-NEXT:    bne a2, a3, .LBB38_2
2703; RV64ZBA-NEXT:  # %bb.1: # %entry
2704; RV64ZBA-NEXT:    mv a0, a1
2705; RV64ZBA-NEXT:  .LBB38_2: # %entry
2706; RV64ZBA-NEXT:    ret
2707;
2708; RV32ZICOND-LABEL: ssubo.select.i64:
2709; RV32ZICOND:       # %bb.0: # %entry
2710; RV32ZICOND-NEXT:    sltu a4, a0, a2
2711; RV32ZICOND-NEXT:    sub a5, a1, a3
2712; RV32ZICOND-NEXT:    sub a5, a5, a4
2713; RV32ZICOND-NEXT:    xor a4, a1, a3
2714; RV32ZICOND-NEXT:    xor a5, a1, a5
2715; RV32ZICOND-NEXT:    and a4, a4, a5
2716; RV32ZICOND-NEXT:    slti a4, a4, 0
2717; RV32ZICOND-NEXT:    czero.nez a2, a2, a4
2718; RV32ZICOND-NEXT:    czero.eqz a0, a0, a4
2719; RV32ZICOND-NEXT:    czero.nez a3, a3, a4
2720; RV32ZICOND-NEXT:    czero.eqz a1, a1, a4
2721; RV32ZICOND-NEXT:    or a0, a0, a2
2722; RV32ZICOND-NEXT:    or a1, a1, a3
2723; RV32ZICOND-NEXT:    ret
2724;
2725; RV64ZICOND-LABEL: ssubo.select.i64:
2726; RV64ZICOND:       # %bb.0: # %entry
2727; RV64ZICOND-NEXT:    sgtz a2, a1
2728; RV64ZICOND-NEXT:    sub a3, a0, a1
2729; RV64ZICOND-NEXT:    slt a3, a3, a0
2730; RV64ZICOND-NEXT:    xor a2, a2, a3
2731; RV64ZICOND-NEXT:    czero.nez a1, a1, a2
2732; RV64ZICOND-NEXT:    czero.eqz a0, a0, a2
2733; RV64ZICOND-NEXT:    or a0, a0, a1
2734; RV64ZICOND-NEXT:    ret
2735entry:
2736  %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2)
2737  %obit = extractvalue {i64, i1} %t, 1
2738  %ret = select i1 %obit, i64 %v1, i64 %v2
2739  ret i64 %ret
2740}
2741
2742define i1 @ssub.not.i64(i64 %v1, i64 %v2) {
2743; RV32-LABEL: ssub.not.i64:
2744; RV32:       # %bb.0: # %entry
2745; RV32-NEXT:    sltu a0, a0, a2
2746; RV32-NEXT:    sub a2, a1, a3
2747; RV32-NEXT:    sub a2, a2, a0
2748; RV32-NEXT:    xor a2, a1, a2
2749; RV32-NEXT:    xor a1, a1, a3
2750; RV32-NEXT:    and a1, a1, a2
2751; RV32-NEXT:    slti a0, a1, 0
2752; RV32-NEXT:    xori a0, a0, 1
2753; RV32-NEXT:    ret
2754;
2755; RV64-LABEL: ssub.not.i64:
2756; RV64:       # %bb.0: # %entry
2757; RV64-NEXT:    sgtz a2, a1
2758; RV64-NEXT:    sub a1, a0, a1
2759; RV64-NEXT:    slt a0, a1, a0
2760; RV64-NEXT:    xor a0, a2, a0
2761; RV64-NEXT:    xori a0, a0, 1
2762; RV64-NEXT:    ret
2763;
2764; RV32ZBA-LABEL: ssub.not.i64:
2765; RV32ZBA:       # %bb.0: # %entry
2766; RV32ZBA-NEXT:    sltu a0, a0, a2
2767; RV32ZBA-NEXT:    sub a2, a1, a3
2768; RV32ZBA-NEXT:    sub a2, a2, a0
2769; RV32ZBA-NEXT:    xor a2, a1, a2
2770; RV32ZBA-NEXT:    xor a1, a1, a3
2771; RV32ZBA-NEXT:    and a1, a1, a2
2772; RV32ZBA-NEXT:    slti a0, a1, 0
2773; RV32ZBA-NEXT:    xori a0, a0, 1
2774; RV32ZBA-NEXT:    ret
2775;
2776; RV64ZBA-LABEL: ssub.not.i64:
2777; RV64ZBA:       # %bb.0: # %entry
2778; RV64ZBA-NEXT:    sgtz a2, a1
2779; RV64ZBA-NEXT:    sub a1, a0, a1
2780; RV64ZBA-NEXT:    slt a0, a1, a0
2781; RV64ZBA-NEXT:    xor a0, a2, a0
2782; RV64ZBA-NEXT:    xori a0, a0, 1
2783; RV64ZBA-NEXT:    ret
2784;
2785; RV32ZICOND-LABEL: ssub.not.i64:
2786; RV32ZICOND:       # %bb.0: # %entry
2787; RV32ZICOND-NEXT:    sltu a0, a0, a2
2788; RV32ZICOND-NEXT:    sub a2, a1, a3
2789; RV32ZICOND-NEXT:    sub a2, a2, a0
2790; RV32ZICOND-NEXT:    xor a2, a1, a2
2791; RV32ZICOND-NEXT:    xor a1, a1, a3
2792; RV32ZICOND-NEXT:    and a1, a1, a2
2793; RV32ZICOND-NEXT:    slti a0, a1, 0
2794; RV32ZICOND-NEXT:    xori a0, a0, 1
2795; RV32ZICOND-NEXT:    ret
2796;
2797; RV64ZICOND-LABEL: ssub.not.i64:
2798; RV64ZICOND:       # %bb.0: # %entry
2799; RV64ZICOND-NEXT:    sgtz a2, a1
2800; RV64ZICOND-NEXT:    sub a1, a0, a1
2801; RV64ZICOND-NEXT:    slt a0, a1, a0
2802; RV64ZICOND-NEXT:    xor a0, a2, a0
2803; RV64ZICOND-NEXT:    xori a0, a0, 1
2804; RV64ZICOND-NEXT:    ret
2805entry:
2806  %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2)
2807  %obit = extractvalue {i64, i1} %t, 1
2808  %ret = xor i1 %obit, true
2809  ret i1 %ret
2810}
2811
2812define i32 @usubo.select.i32(i32 signext %v1, i32 signext %v2) {
2813; RV32-LABEL: usubo.select.i32:
2814; RV32:       # %bb.0: # %entry
2815; RV32-NEXT:    sub a2, a0, a1
2816; RV32-NEXT:    bltu a0, a2, .LBB40_2
2817; RV32-NEXT:  # %bb.1: # %entry
2818; RV32-NEXT:    mv a0, a1
2819; RV32-NEXT:  .LBB40_2: # %entry
2820; RV32-NEXT:    ret
2821;
2822; RV64-LABEL: usubo.select.i32:
2823; RV64:       # %bb.0: # %entry
2824; RV64-NEXT:    subw a2, a0, a1
2825; RV64-NEXT:    bltu a0, a2, .LBB40_2
2826; RV64-NEXT:  # %bb.1: # %entry
2827; RV64-NEXT:    mv a0, a1
2828; RV64-NEXT:  .LBB40_2: # %entry
2829; RV64-NEXT:    ret
2830;
2831; RV32ZBA-LABEL: usubo.select.i32:
2832; RV32ZBA:       # %bb.0: # %entry
2833; RV32ZBA-NEXT:    sub a2, a0, a1
2834; RV32ZBA-NEXT:    bltu a0, a2, .LBB40_2
2835; RV32ZBA-NEXT:  # %bb.1: # %entry
2836; RV32ZBA-NEXT:    mv a0, a1
2837; RV32ZBA-NEXT:  .LBB40_2: # %entry
2838; RV32ZBA-NEXT:    ret
2839;
2840; RV64ZBA-LABEL: usubo.select.i32:
2841; RV64ZBA:       # %bb.0: # %entry
2842; RV64ZBA-NEXT:    subw a2, a0, a1
2843; RV64ZBA-NEXT:    bltu a0, a2, .LBB40_2
2844; RV64ZBA-NEXT:  # %bb.1: # %entry
2845; RV64ZBA-NEXT:    mv a0, a1
2846; RV64ZBA-NEXT:  .LBB40_2: # %entry
2847; RV64ZBA-NEXT:    ret
2848;
2849; RV32ZICOND-LABEL: usubo.select.i32:
2850; RV32ZICOND:       # %bb.0: # %entry
2851; RV32ZICOND-NEXT:    sub a2, a0, a1
2852; RV32ZICOND-NEXT:    sltu a2, a0, a2
2853; RV32ZICOND-NEXT:    czero.nez a1, a1, a2
2854; RV32ZICOND-NEXT:    czero.eqz a0, a0, a2
2855; RV32ZICOND-NEXT:    or a0, a0, a1
2856; RV32ZICOND-NEXT:    ret
2857;
2858; RV64ZICOND-LABEL: usubo.select.i32:
2859; RV64ZICOND:       # %bb.0: # %entry
2860; RV64ZICOND-NEXT:    subw a2, a0, a1
2861; RV64ZICOND-NEXT:    sltu a2, a0, a2
2862; RV64ZICOND-NEXT:    czero.nez a1, a1, a2
2863; RV64ZICOND-NEXT:    czero.eqz a0, a0, a2
2864; RV64ZICOND-NEXT:    or a0, a0, a1
2865; RV64ZICOND-NEXT:    ret
2866entry:
2867  %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2)
2868  %obit = extractvalue {i32, i1} %t, 1
2869  %ret = select i1 %obit, i32 %v1, i32 %v2
2870  ret i32 %ret
2871}
2872
2873define i1 @usubo.not.i32(i32 signext %v1, i32 signext %v2) {
2874; RV32-LABEL: usubo.not.i32:
2875; RV32:       # %bb.0: # %entry
2876; RV32-NEXT:    sub a1, a0, a1
2877; RV32-NEXT:    sltu a0, a0, a1
2878; RV32-NEXT:    xori a0, a0, 1
2879; RV32-NEXT:    ret
2880;
2881; RV64-LABEL: usubo.not.i32:
2882; RV64:       # %bb.0: # %entry
2883; RV64-NEXT:    subw a1, a0, a1
2884; RV64-NEXT:    sltu a0, a0, a1
2885; RV64-NEXT:    xori a0, a0, 1
2886; RV64-NEXT:    ret
2887;
2888; RV32ZBA-LABEL: usubo.not.i32:
2889; RV32ZBA:       # %bb.0: # %entry
2890; RV32ZBA-NEXT:    sub a1, a0, a1
2891; RV32ZBA-NEXT:    sltu a0, a0, a1
2892; RV32ZBA-NEXT:    xori a0, a0, 1
2893; RV32ZBA-NEXT:    ret
2894;
2895; RV64ZBA-LABEL: usubo.not.i32:
2896; RV64ZBA:       # %bb.0: # %entry
2897; RV64ZBA-NEXT:    subw a1, a0, a1
2898; RV64ZBA-NEXT:    sltu a0, a0, a1
2899; RV64ZBA-NEXT:    xori a0, a0, 1
2900; RV64ZBA-NEXT:    ret
2901;
2902; RV32ZICOND-LABEL: usubo.not.i32:
2903; RV32ZICOND:       # %bb.0: # %entry
2904; RV32ZICOND-NEXT:    sub a1, a0, a1
2905; RV32ZICOND-NEXT:    sltu a0, a0, a1
2906; RV32ZICOND-NEXT:    xori a0, a0, 1
2907; RV32ZICOND-NEXT:    ret
2908;
2909; RV64ZICOND-LABEL: usubo.not.i32:
2910; RV64ZICOND:       # %bb.0: # %entry
2911; RV64ZICOND-NEXT:    subw a1, a0, a1
2912; RV64ZICOND-NEXT:    sltu a0, a0, a1
2913; RV64ZICOND-NEXT:    xori a0, a0, 1
2914; RV64ZICOND-NEXT:    ret
2915entry:
2916  %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2)
2917  %obit = extractvalue {i32, i1} %t, 1
2918  %ret = xor i1 %obit, true
2919  ret i1 %ret
2920}
2921
2922define i64 @usubo.select.i64(i64 %v1, i64 %v2) {
2923; RV32-LABEL: usubo.select.i64:
2924; RV32:       # %bb.0: # %entry
2925; RV32-NEXT:    sltu a4, a0, a2
2926; RV32-NEXT:    sub a5, a1, a3
2927; RV32-NEXT:    sub a4, a5, a4
2928; RV32-NEXT:    beq a4, a1, .LBB42_2
2929; RV32-NEXT:  # %bb.1: # %entry
2930; RV32-NEXT:    sltu a4, a1, a4
2931; RV32-NEXT:    beqz a4, .LBB42_3
2932; RV32-NEXT:    j .LBB42_4
2933; RV32-NEXT:  .LBB42_2:
2934; RV32-NEXT:    sub a4, a0, a2
2935; RV32-NEXT:    sltu a4, a0, a4
2936; RV32-NEXT:    bnez a4, .LBB42_4
2937; RV32-NEXT:  .LBB42_3: # %entry
2938; RV32-NEXT:    mv a0, a2
2939; RV32-NEXT:    mv a1, a3
2940; RV32-NEXT:  .LBB42_4: # %entry
2941; RV32-NEXT:    ret
2942;
2943; RV64-LABEL: usubo.select.i64:
2944; RV64:       # %bb.0: # %entry
2945; RV64-NEXT:    sub a2, a0, a1
2946; RV64-NEXT:    bltu a0, a2, .LBB42_2
2947; RV64-NEXT:  # %bb.1: # %entry
2948; RV64-NEXT:    mv a0, a1
2949; RV64-NEXT:  .LBB42_2: # %entry
2950; RV64-NEXT:    ret
2951;
2952; RV32ZBA-LABEL: usubo.select.i64:
2953; RV32ZBA:       # %bb.0: # %entry
2954; RV32ZBA-NEXT:    sltu a4, a0, a2
2955; RV32ZBA-NEXT:    sub a5, a1, a3
2956; RV32ZBA-NEXT:    sub a4, a5, a4
2957; RV32ZBA-NEXT:    beq a4, a1, .LBB42_2
2958; RV32ZBA-NEXT:  # %bb.1: # %entry
2959; RV32ZBA-NEXT:    sltu a4, a1, a4
2960; RV32ZBA-NEXT:    beqz a4, .LBB42_3
2961; RV32ZBA-NEXT:    j .LBB42_4
2962; RV32ZBA-NEXT:  .LBB42_2:
2963; RV32ZBA-NEXT:    sub a4, a0, a2
2964; RV32ZBA-NEXT:    sltu a4, a0, a4
2965; RV32ZBA-NEXT:    bnez a4, .LBB42_4
2966; RV32ZBA-NEXT:  .LBB42_3: # %entry
2967; RV32ZBA-NEXT:    mv a0, a2
2968; RV32ZBA-NEXT:    mv a1, a3
2969; RV32ZBA-NEXT:  .LBB42_4: # %entry
2970; RV32ZBA-NEXT:    ret
2971;
2972; RV64ZBA-LABEL: usubo.select.i64:
2973; RV64ZBA:       # %bb.0: # %entry
2974; RV64ZBA-NEXT:    sub a2, a0, a1
2975; RV64ZBA-NEXT:    bltu a0, a2, .LBB42_2
2976; RV64ZBA-NEXT:  # %bb.1: # %entry
2977; RV64ZBA-NEXT:    mv a0, a1
2978; RV64ZBA-NEXT:  .LBB42_2: # %entry
2979; RV64ZBA-NEXT:    ret
2980;
2981; RV32ZICOND-LABEL: usubo.select.i64:
2982; RV32ZICOND:       # %bb.0: # %entry
2983; RV32ZICOND-NEXT:    sltu a4, a0, a2
2984; RV32ZICOND-NEXT:    sub a5, a1, a3
2985; RV32ZICOND-NEXT:    sub a6, a0, a2
2986; RV32ZICOND-NEXT:    sub a5, a5, a4
2987; RV32ZICOND-NEXT:    sltu a4, a0, a6
2988; RV32ZICOND-NEXT:    xor a6, a5, a1
2989; RV32ZICOND-NEXT:    sltu a5, a1, a5
2990; RV32ZICOND-NEXT:    czero.eqz a5, a5, a6
2991; RV32ZICOND-NEXT:    czero.nez a4, a4, a6
2992; RV32ZICOND-NEXT:    or a4, a4, a5
2993; RV32ZICOND-NEXT:    czero.nez a2, a2, a4
2994; RV32ZICOND-NEXT:    czero.eqz a0, a0, a4
2995; RV32ZICOND-NEXT:    czero.nez a3, a3, a4
2996; RV32ZICOND-NEXT:    czero.eqz a1, a1, a4
2997; RV32ZICOND-NEXT:    or a0, a0, a2
2998; RV32ZICOND-NEXT:    or a1, a1, a3
2999; RV32ZICOND-NEXT:    ret
3000;
3001; RV64ZICOND-LABEL: usubo.select.i64:
3002; RV64ZICOND:       # %bb.0: # %entry
3003; RV64ZICOND-NEXT:    sub a2, a0, a1
3004; RV64ZICOND-NEXT:    sltu a2, a0, a2
3005; RV64ZICOND-NEXT:    czero.nez a1, a1, a2
3006; RV64ZICOND-NEXT:    czero.eqz a0, a0, a2
3007; RV64ZICOND-NEXT:    or a0, a0, a1
3008; RV64ZICOND-NEXT:    ret
3009entry:
3010  %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2)
3011  %obit = extractvalue {i64, i1} %t, 1
3012  %ret = select i1 %obit, i64 %v1, i64 %v2
3013  ret i64 %ret
3014}
3015
3016define i1 @usubo.not.i64(i64 %v1, i64 %v2) {
3017; RV32-LABEL: usubo.not.i64:
3018; RV32:       # %bb.0: # %entry
3019; RV32-NEXT:    sltu a4, a0, a2
3020; RV32-NEXT:    sub a3, a1, a3
3021; RV32-NEXT:    sub a3, a3, a4
3022; RV32-NEXT:    beq a3, a1, .LBB43_2
3023; RV32-NEXT:  # %bb.1: # %entry
3024; RV32-NEXT:    sltu a0, a1, a3
3025; RV32-NEXT:    xori a0, a0, 1
3026; RV32-NEXT:    ret
3027; RV32-NEXT:  .LBB43_2:
3028; RV32-NEXT:    sub a1, a0, a2
3029; RV32-NEXT:    sltu a0, a0, a1
3030; RV32-NEXT:    xori a0, a0, 1
3031; RV32-NEXT:    ret
3032;
3033; RV64-LABEL: usubo.not.i64:
3034; RV64:       # %bb.0: # %entry
3035; RV64-NEXT:    sub a1, a0, a1
3036; RV64-NEXT:    sltu a0, a0, a1
3037; RV64-NEXT:    xori a0, a0, 1
3038; RV64-NEXT:    ret
3039;
3040; RV32ZBA-LABEL: usubo.not.i64:
3041; RV32ZBA:       # %bb.0: # %entry
3042; RV32ZBA-NEXT:    sltu a4, a0, a2
3043; RV32ZBA-NEXT:    sub a3, a1, a3
3044; RV32ZBA-NEXT:    sub a3, a3, a4
3045; RV32ZBA-NEXT:    beq a3, a1, .LBB43_2
3046; RV32ZBA-NEXT:  # %bb.1: # %entry
3047; RV32ZBA-NEXT:    sltu a0, a1, a3
3048; RV32ZBA-NEXT:    xori a0, a0, 1
3049; RV32ZBA-NEXT:    ret
3050; RV32ZBA-NEXT:  .LBB43_2:
3051; RV32ZBA-NEXT:    sub a1, a0, a2
3052; RV32ZBA-NEXT:    sltu a0, a0, a1
3053; RV32ZBA-NEXT:    xori a0, a0, 1
3054; RV32ZBA-NEXT:    ret
3055;
3056; RV64ZBA-LABEL: usubo.not.i64:
3057; RV64ZBA:       # %bb.0: # %entry
3058; RV64ZBA-NEXT:    sub a1, a0, a1
3059; RV64ZBA-NEXT:    sltu a0, a0, a1
3060; RV64ZBA-NEXT:    xori a0, a0, 1
3061; RV64ZBA-NEXT:    ret
3062;
3063; RV32ZICOND-LABEL: usubo.not.i64:
3064; RV32ZICOND:       # %bb.0: # %entry
3065; RV32ZICOND-NEXT:    sltu a4, a0, a2
3066; RV32ZICOND-NEXT:    sub a3, a1, a3
3067; RV32ZICOND-NEXT:    sub a2, a0, a2
3068; RV32ZICOND-NEXT:    sub a3, a3, a4
3069; RV32ZICOND-NEXT:    sltu a0, a0, a2
3070; RV32ZICOND-NEXT:    xor a2, a3, a1
3071; RV32ZICOND-NEXT:    sltu a1, a1, a3
3072; RV32ZICOND-NEXT:    czero.eqz a1, a1, a2
3073; RV32ZICOND-NEXT:    czero.nez a0, a0, a2
3074; RV32ZICOND-NEXT:    or a0, a0, a1
3075; RV32ZICOND-NEXT:    xori a0, a0, 1
3076; RV32ZICOND-NEXT:    ret
3077;
3078; RV64ZICOND-LABEL: usubo.not.i64:
3079; RV64ZICOND:       # %bb.0: # %entry
3080; RV64ZICOND-NEXT:    sub a1, a0, a1
3081; RV64ZICOND-NEXT:    sltu a0, a0, a1
3082; RV64ZICOND-NEXT:    xori a0, a0, 1
3083; RV64ZICOND-NEXT:    ret
3084entry:
3085  %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2)
3086  %obit = extractvalue {i64, i1} %t, 1
3087  %ret = xor i1 %obit, true
3088  ret i1 %ret
3089}
3090
3091define i32 @smulo.select.i32(i32 signext %v1, i32 signext %v2) {
3092; RV32-LABEL: smulo.select.i32:
3093; RV32:       # %bb.0: # %entry
3094; RV32-NEXT:    mulh a2, a0, a1
3095; RV32-NEXT:    mul a3, a0, a1
3096; RV32-NEXT:    srai a3, a3, 31
3097; RV32-NEXT:    bne a2, a3, .LBB44_2
3098; RV32-NEXT:  # %bb.1: # %entry
3099; RV32-NEXT:    mv a0, a1
3100; RV32-NEXT:  .LBB44_2: # %entry
3101; RV32-NEXT:    ret
3102;
3103; RV64-LABEL: smulo.select.i32:
3104; RV64:       # %bb.0: # %entry
3105; RV64-NEXT:    mul a2, a0, a1
3106; RV64-NEXT:    mulw a3, a0, a1
3107; RV64-NEXT:    bne a3, a2, .LBB44_2
3108; RV64-NEXT:  # %bb.1: # %entry
3109; RV64-NEXT:    mv a0, a1
3110; RV64-NEXT:  .LBB44_2: # %entry
3111; RV64-NEXT:    ret
3112;
3113; RV32ZBA-LABEL: smulo.select.i32:
3114; RV32ZBA:       # %bb.0: # %entry
3115; RV32ZBA-NEXT:    mulh a2, a0, a1
3116; RV32ZBA-NEXT:    mul a3, a0, a1
3117; RV32ZBA-NEXT:    srai a3, a3, 31
3118; RV32ZBA-NEXT:    bne a2, a3, .LBB44_2
3119; RV32ZBA-NEXT:  # %bb.1: # %entry
3120; RV32ZBA-NEXT:    mv a0, a1
3121; RV32ZBA-NEXT:  .LBB44_2: # %entry
3122; RV32ZBA-NEXT:    ret
3123;
3124; RV64ZBA-LABEL: smulo.select.i32:
3125; RV64ZBA:       # %bb.0: # %entry
3126; RV64ZBA-NEXT:    mul a2, a0, a1
3127; RV64ZBA-NEXT:    mulw a3, a0, a1
3128; RV64ZBA-NEXT:    bne a3, a2, .LBB44_2
3129; RV64ZBA-NEXT:  # %bb.1: # %entry
3130; RV64ZBA-NEXT:    mv a0, a1
3131; RV64ZBA-NEXT:  .LBB44_2: # %entry
3132; RV64ZBA-NEXT:    ret
3133;
3134; RV32ZICOND-LABEL: smulo.select.i32:
3135; RV32ZICOND:       # %bb.0: # %entry
3136; RV32ZICOND-NEXT:    mulh a2, a0, a1
3137; RV32ZICOND-NEXT:    mul a3, a0, a1
3138; RV32ZICOND-NEXT:    srai a3, a3, 31
3139; RV32ZICOND-NEXT:    xor a2, a2, a3
3140; RV32ZICOND-NEXT:    czero.nez a1, a1, a2
3141; RV32ZICOND-NEXT:    czero.eqz a0, a0, a2
3142; RV32ZICOND-NEXT:    or a0, a0, a1
3143; RV32ZICOND-NEXT:    ret
3144;
3145; RV64ZICOND-LABEL: smulo.select.i32:
3146; RV64ZICOND:       # %bb.0: # %entry
3147; RV64ZICOND-NEXT:    mul a2, a0, a1
3148; RV64ZICOND-NEXT:    mulw a3, a0, a1
3149; RV64ZICOND-NEXT:    xor a2, a3, a2
3150; RV64ZICOND-NEXT:    czero.nez a1, a1, a2
3151; RV64ZICOND-NEXT:    czero.eqz a0, a0, a2
3152; RV64ZICOND-NEXT:    or a0, a0, a1
3153; RV64ZICOND-NEXT:    ret
3154entry:
3155  %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
3156  %obit = extractvalue {i32, i1} %t, 1
3157  %ret = select i1 %obit, i32 %v1, i32 %v2
3158  ret i32 %ret
3159}
3160
3161define i1 @smulo.not.i32(i32 signext %v1, i32 signext %v2) {
3162; RV32-LABEL: smulo.not.i32:
3163; RV32:       # %bb.0: # %entry
3164; RV32-NEXT:    mulh a2, a0, a1
3165; RV32-NEXT:    mul a0, a0, a1
3166; RV32-NEXT:    srai a0, a0, 31
3167; RV32-NEXT:    xor a0, a2, a0
3168; RV32-NEXT:    seqz a0, a0
3169; RV32-NEXT:    ret
3170;
3171; RV64-LABEL: smulo.not.i32:
3172; RV64:       # %bb.0: # %entry
3173; RV64-NEXT:    mul a2, a0, a1
3174; RV64-NEXT:    mulw a0, a0, a1
3175; RV64-NEXT:    xor a0, a0, a2
3176; RV64-NEXT:    seqz a0, a0
3177; RV64-NEXT:    ret
3178;
3179; RV32ZBA-LABEL: smulo.not.i32:
3180; RV32ZBA:       # %bb.0: # %entry
3181; RV32ZBA-NEXT:    mulh a2, a0, a1
3182; RV32ZBA-NEXT:    mul a0, a0, a1
3183; RV32ZBA-NEXT:    srai a0, a0, 31
3184; RV32ZBA-NEXT:    xor a0, a2, a0
3185; RV32ZBA-NEXT:    seqz a0, a0
3186; RV32ZBA-NEXT:    ret
3187;
3188; RV64ZBA-LABEL: smulo.not.i32:
3189; RV64ZBA:       # %bb.0: # %entry
3190; RV64ZBA-NEXT:    mul a2, a0, a1
3191; RV64ZBA-NEXT:    mulw a0, a0, a1
3192; RV64ZBA-NEXT:    xor a0, a0, a2
3193; RV64ZBA-NEXT:    seqz a0, a0
3194; RV64ZBA-NEXT:    ret
3195;
3196; RV32ZICOND-LABEL: smulo.not.i32:
3197; RV32ZICOND:       # %bb.0: # %entry
3198; RV32ZICOND-NEXT:    mulh a2, a0, a1
3199; RV32ZICOND-NEXT:    mul a0, a0, a1
3200; RV32ZICOND-NEXT:    srai a0, a0, 31
3201; RV32ZICOND-NEXT:    xor a0, a2, a0
3202; RV32ZICOND-NEXT:    seqz a0, a0
3203; RV32ZICOND-NEXT:    ret
3204;
3205; RV64ZICOND-LABEL: smulo.not.i32:
3206; RV64ZICOND:       # %bb.0: # %entry
3207; RV64ZICOND-NEXT:    mul a2, a0, a1
3208; RV64ZICOND-NEXT:    mulw a0, a0, a1
3209; RV64ZICOND-NEXT:    xor a0, a0, a2
3210; RV64ZICOND-NEXT:    seqz a0, a0
3211; RV64ZICOND-NEXT:    ret
3212entry:
3213  %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
3214  %obit = extractvalue {i32, i1} %t, 1
3215  %ret = xor i1 %obit, true
3216  ret i1 %ret
3217}
3218
3219define i64 @smulo.select.i64(i64 %v1, i64 %v2) {
3220; RV32-LABEL: smulo.select.i64:
3221; RV32:       # %bb.0: # %entry
3222; RV32-NEXT:    mulhu a4, a0, a2
3223; RV32-NEXT:    mul a5, a1, a2
3224; RV32-NEXT:    mulhsu a6, a1, a2
3225; RV32-NEXT:    mul a7, a3, a0
3226; RV32-NEXT:    mulhsu t0, a3, a0
3227; RV32-NEXT:    add a4, a5, a4
3228; RV32-NEXT:    sltu a5, a4, a5
3229; RV32-NEXT:    add a4, a7, a4
3230; RV32-NEXT:    add a5, a6, a5
3231; RV32-NEXT:    sltu a6, a4, a7
3232; RV32-NEXT:    add a6, t0, a6
3233; RV32-NEXT:    srai a7, a5, 31
3234; RV32-NEXT:    srai t0, a6, 31
3235; RV32-NEXT:    add a7, a7, t0
3236; RV32-NEXT:    mulh t0, a1, a3
3237; RV32-NEXT:    add a6, a5, a6
3238; RV32-NEXT:    sltu a5, a6, a5
3239; RV32-NEXT:    add a5, a7, a5
3240; RV32-NEXT:    mul a7, a1, a3
3241; RV32-NEXT:    srai a4, a4, 31
3242; RV32-NEXT:    add a6, a7, a6
3243; RV32-NEXT:    sltu a7, a6, a7
3244; RV32-NEXT:    add a5, t0, a5
3245; RV32-NEXT:    add a5, a5, a7
3246; RV32-NEXT:    xor a5, a5, a4
3247; RV32-NEXT:    xor a4, a6, a4
3248; RV32-NEXT:    or a4, a4, a5
3249; RV32-NEXT:    bnez a4, .LBB46_2
3250; RV32-NEXT:  # %bb.1: # %entry
3251; RV32-NEXT:    mv a0, a2
3252; RV32-NEXT:    mv a1, a3
3253; RV32-NEXT:  .LBB46_2: # %entry
3254; RV32-NEXT:    ret
3255;
3256; RV64-LABEL: smulo.select.i64:
3257; RV64:       # %bb.0: # %entry
3258; RV64-NEXT:    mulh a2, a0, a1
3259; RV64-NEXT:    mul a3, a0, a1
3260; RV64-NEXT:    srai a3, a3, 63
3261; RV64-NEXT:    bne a2, a3, .LBB46_2
3262; RV64-NEXT:  # %bb.1: # %entry
3263; RV64-NEXT:    mv a0, a1
3264; RV64-NEXT:  .LBB46_2: # %entry
3265; RV64-NEXT:    ret
3266;
3267; RV32ZBA-LABEL: smulo.select.i64:
3268; RV32ZBA:       # %bb.0: # %entry
3269; RV32ZBA-NEXT:    mulhu a4, a0, a2
3270; RV32ZBA-NEXT:    mul a5, a1, a2
3271; RV32ZBA-NEXT:    mulhsu a6, a1, a2
3272; RV32ZBA-NEXT:    mul a7, a3, a0
3273; RV32ZBA-NEXT:    mulhsu t0, a3, a0
3274; RV32ZBA-NEXT:    add a4, a5, a4
3275; RV32ZBA-NEXT:    sltu a5, a4, a5
3276; RV32ZBA-NEXT:    add a4, a7, a4
3277; RV32ZBA-NEXT:    add a5, a6, a5
3278; RV32ZBA-NEXT:    sltu a6, a4, a7
3279; RV32ZBA-NEXT:    add a6, t0, a6
3280; RV32ZBA-NEXT:    srai a7, a5, 31
3281; RV32ZBA-NEXT:    srai t0, a6, 31
3282; RV32ZBA-NEXT:    add a7, a7, t0
3283; RV32ZBA-NEXT:    mulh t0, a1, a3
3284; RV32ZBA-NEXT:    add a6, a5, a6
3285; RV32ZBA-NEXT:    sltu a5, a6, a5
3286; RV32ZBA-NEXT:    add a5, a7, a5
3287; RV32ZBA-NEXT:    mul a7, a1, a3
3288; RV32ZBA-NEXT:    srai a4, a4, 31
3289; RV32ZBA-NEXT:    add a6, a7, a6
3290; RV32ZBA-NEXT:    sltu a7, a6, a7
3291; RV32ZBA-NEXT:    add a5, t0, a5
3292; RV32ZBA-NEXT:    add a5, a5, a7
3293; RV32ZBA-NEXT:    xor a5, a5, a4
3294; RV32ZBA-NEXT:    xor a4, a6, a4
3295; RV32ZBA-NEXT:    or a4, a4, a5
3296; RV32ZBA-NEXT:    bnez a4, .LBB46_2
3297; RV32ZBA-NEXT:  # %bb.1: # %entry
3298; RV32ZBA-NEXT:    mv a0, a2
3299; RV32ZBA-NEXT:    mv a1, a3
3300; RV32ZBA-NEXT:  .LBB46_2: # %entry
3301; RV32ZBA-NEXT:    ret
3302;
3303; RV64ZBA-LABEL: smulo.select.i64:
3304; RV64ZBA:       # %bb.0: # %entry
3305; RV64ZBA-NEXT:    mulh a2, a0, a1
3306; RV64ZBA-NEXT:    mul a3, a0, a1
3307; RV64ZBA-NEXT:    srai a3, a3, 63
3308; RV64ZBA-NEXT:    bne a2, a3, .LBB46_2
3309; RV64ZBA-NEXT:  # %bb.1: # %entry
3310; RV64ZBA-NEXT:    mv a0, a1
3311; RV64ZBA-NEXT:  .LBB46_2: # %entry
3312; RV64ZBA-NEXT:    ret
3313;
3314; RV32ZICOND-LABEL: smulo.select.i64:
3315; RV32ZICOND:       # %bb.0: # %entry
3316; RV32ZICOND-NEXT:    mulhu a4, a0, a2
3317; RV32ZICOND-NEXT:    mul a5, a1, a2
3318; RV32ZICOND-NEXT:    mulhsu a6, a1, a2
3319; RV32ZICOND-NEXT:    mul a7, a3, a0
3320; RV32ZICOND-NEXT:    mulhsu t0, a3, a0
3321; RV32ZICOND-NEXT:    add a4, a5, a4
3322; RV32ZICOND-NEXT:    sltu a5, a4, a5
3323; RV32ZICOND-NEXT:    add a4, a7, a4
3324; RV32ZICOND-NEXT:    add a5, a6, a5
3325; RV32ZICOND-NEXT:    sltu a6, a4, a7
3326; RV32ZICOND-NEXT:    add a6, t0, a6
3327; RV32ZICOND-NEXT:    srai a7, a5, 31
3328; RV32ZICOND-NEXT:    srai t0, a6, 31
3329; RV32ZICOND-NEXT:    add a7, a7, t0
3330; RV32ZICOND-NEXT:    mulh t0, a1, a3
3331; RV32ZICOND-NEXT:    add a6, a5, a6
3332; RV32ZICOND-NEXT:    sltu a5, a6, a5
3333; RV32ZICOND-NEXT:    add a5, a7, a5
3334; RV32ZICOND-NEXT:    mul a7, a1, a3
3335; RV32ZICOND-NEXT:    srai a4, a4, 31
3336; RV32ZICOND-NEXT:    add a6, a7, a6
3337; RV32ZICOND-NEXT:    sltu a7, a6, a7
3338; RV32ZICOND-NEXT:    xor a6, a6, a4
3339; RV32ZICOND-NEXT:    add a5, t0, a5
3340; RV32ZICOND-NEXT:    add a5, a5, a7
3341; RV32ZICOND-NEXT:    xor a4, a5, a4
3342; RV32ZICOND-NEXT:    or a4, a6, a4
3343; RV32ZICOND-NEXT:    czero.nez a2, a2, a4
3344; RV32ZICOND-NEXT:    czero.eqz a0, a0, a4
3345; RV32ZICOND-NEXT:    czero.nez a3, a3, a4
3346; RV32ZICOND-NEXT:    czero.eqz a1, a1, a4
3347; RV32ZICOND-NEXT:    or a0, a0, a2
3348; RV32ZICOND-NEXT:    or a1, a1, a3
3349; RV32ZICOND-NEXT:    ret
3350;
3351; RV64ZICOND-LABEL: smulo.select.i64:
3352; RV64ZICOND:       # %bb.0: # %entry
3353; RV64ZICOND-NEXT:    mulh a2, a0, a1
3354; RV64ZICOND-NEXT:    mul a3, a0, a1
3355; RV64ZICOND-NEXT:    srai a3, a3, 63
3356; RV64ZICOND-NEXT:    xor a2, a2, a3
3357; RV64ZICOND-NEXT:    czero.nez a1, a1, a2
3358; RV64ZICOND-NEXT:    czero.eqz a0, a0, a2
3359; RV64ZICOND-NEXT:    or a0, a0, a1
3360; RV64ZICOND-NEXT:    ret
3361entry:
3362  %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
3363  %obit = extractvalue {i64, i1} %t, 1
3364  %ret = select i1 %obit, i64 %v1, i64 %v2
3365  ret i64 %ret
3366}
3367
3368define i1 @smulo.not.i64(i64 %v1, i64 %v2) {
3369; RV32-LABEL: smulo.not.i64:
3370; RV32:       # %bb.0: # %entry
3371; RV32-NEXT:    mulhu a4, a0, a2
3372; RV32-NEXT:    mul a5, a1, a2
3373; RV32-NEXT:    mulhsu a2, a1, a2
3374; RV32-NEXT:    mul a6, a3, a0
3375; RV32-NEXT:    mulhsu a0, a3, a0
3376; RV32-NEXT:    mulh a7, a1, a3
3377; RV32-NEXT:    mul a1, a1, a3
3378; RV32-NEXT:    add a4, a5, a4
3379; RV32-NEXT:    sltu a3, a4, a5
3380; RV32-NEXT:    add a4, a6, a4
3381; RV32-NEXT:    add a2, a2, a3
3382; RV32-NEXT:    sltu a3, a4, a6
3383; RV32-NEXT:    srai a4, a4, 31
3384; RV32-NEXT:    add a0, a0, a3
3385; RV32-NEXT:    srai a3, a2, 31
3386; RV32-NEXT:    add a5, a2, a0
3387; RV32-NEXT:    srai a0, a0, 31
3388; RV32-NEXT:    sltu a2, a5, a2
3389; RV32-NEXT:    add a0, a3, a0
3390; RV32-NEXT:    add a5, a1, a5
3391; RV32-NEXT:    add a0, a0, a2
3392; RV32-NEXT:    sltu a1, a5, a1
3393; RV32-NEXT:    add a0, a7, a0
3394; RV32-NEXT:    add a0, a0, a1
3395; RV32-NEXT:    xor a0, a0, a4
3396; RV32-NEXT:    xor a4, a5, a4
3397; RV32-NEXT:    or a0, a4, a0
3398; RV32-NEXT:    seqz a0, a0
3399; RV32-NEXT:    ret
3400;
3401; RV64-LABEL: smulo.not.i64:
3402; RV64:       # %bb.0: # %entry
3403; RV64-NEXT:    mulh a2, a0, a1
3404; RV64-NEXT:    mul a0, a0, a1
3405; RV64-NEXT:    srai a0, a0, 63
3406; RV64-NEXT:    xor a0, a2, a0
3407; RV64-NEXT:    seqz a0, a0
3408; RV64-NEXT:    ret
3409;
3410; RV32ZBA-LABEL: smulo.not.i64:
3411; RV32ZBA:       # %bb.0: # %entry
3412; RV32ZBA-NEXT:    mulhu a4, a0, a2
3413; RV32ZBA-NEXT:    mul a5, a1, a2
3414; RV32ZBA-NEXT:    mulhsu a2, a1, a2
3415; RV32ZBA-NEXT:    mul a6, a3, a0
3416; RV32ZBA-NEXT:    mulhsu a0, a3, a0
3417; RV32ZBA-NEXT:    mulh a7, a1, a3
3418; RV32ZBA-NEXT:    mul a1, a1, a3
3419; RV32ZBA-NEXT:    add a4, a5, a4
3420; RV32ZBA-NEXT:    sltu a3, a4, a5
3421; RV32ZBA-NEXT:    add a4, a6, a4
3422; RV32ZBA-NEXT:    add a2, a2, a3
3423; RV32ZBA-NEXT:    sltu a3, a4, a6
3424; RV32ZBA-NEXT:    srai a4, a4, 31
3425; RV32ZBA-NEXT:    add a0, a0, a3
3426; RV32ZBA-NEXT:    srai a3, a2, 31
3427; RV32ZBA-NEXT:    add a5, a2, a0
3428; RV32ZBA-NEXT:    srai a0, a0, 31
3429; RV32ZBA-NEXT:    sltu a2, a5, a2
3430; RV32ZBA-NEXT:    add a0, a3, a0
3431; RV32ZBA-NEXT:    add a5, a1, a5
3432; RV32ZBA-NEXT:    add a0, a0, a2
3433; RV32ZBA-NEXT:    sltu a1, a5, a1
3434; RV32ZBA-NEXT:    add a0, a7, a0
3435; RV32ZBA-NEXT:    add a0, a0, a1
3436; RV32ZBA-NEXT:    xor a0, a0, a4
3437; RV32ZBA-NEXT:    xor a4, a5, a4
3438; RV32ZBA-NEXT:    or a0, a4, a0
3439; RV32ZBA-NEXT:    seqz a0, a0
3440; RV32ZBA-NEXT:    ret
3441;
3442; RV64ZBA-LABEL: smulo.not.i64:
3443; RV64ZBA:       # %bb.0: # %entry
3444; RV64ZBA-NEXT:    mulh a2, a0, a1
3445; RV64ZBA-NEXT:    mul a0, a0, a1
3446; RV64ZBA-NEXT:    srai a0, a0, 63
3447; RV64ZBA-NEXT:    xor a0, a2, a0
3448; RV64ZBA-NEXT:    seqz a0, a0
3449; RV64ZBA-NEXT:    ret
3450;
3451; RV32ZICOND-LABEL: smulo.not.i64:
3452; RV32ZICOND:       # %bb.0: # %entry
3453; RV32ZICOND-NEXT:    mulhu a4, a0, a2
3454; RV32ZICOND-NEXT:    mul a5, a1, a2
3455; RV32ZICOND-NEXT:    mulhsu a2, a1, a2
3456; RV32ZICOND-NEXT:    mul a6, a3, a0
3457; RV32ZICOND-NEXT:    mulhsu a0, a3, a0
3458; RV32ZICOND-NEXT:    mulh a7, a1, a3
3459; RV32ZICOND-NEXT:    mul a1, a1, a3
3460; RV32ZICOND-NEXT:    add a4, a5, a4
3461; RV32ZICOND-NEXT:    sltu a3, a4, a5
3462; RV32ZICOND-NEXT:    add a4, a6, a4
3463; RV32ZICOND-NEXT:    add a2, a2, a3
3464; RV32ZICOND-NEXT:    sltu a3, a4, a6
3465; RV32ZICOND-NEXT:    srai a4, a4, 31
3466; RV32ZICOND-NEXT:    add a0, a0, a3
3467; RV32ZICOND-NEXT:    srai a3, a2, 31
3468; RV32ZICOND-NEXT:    add a5, a2, a0
3469; RV32ZICOND-NEXT:    srai a0, a0, 31
3470; RV32ZICOND-NEXT:    sltu a2, a5, a2
3471; RV32ZICOND-NEXT:    add a0, a3, a0
3472; RV32ZICOND-NEXT:    add a5, a1, a5
3473; RV32ZICOND-NEXT:    add a0, a0, a2
3474; RV32ZICOND-NEXT:    sltu a1, a5, a1
3475; RV32ZICOND-NEXT:    add a0, a7, a0
3476; RV32ZICOND-NEXT:    add a0, a0, a1
3477; RV32ZICOND-NEXT:    xor a0, a0, a4
3478; RV32ZICOND-NEXT:    xor a4, a5, a4
3479; RV32ZICOND-NEXT:    or a0, a4, a0
3480; RV32ZICOND-NEXT:    seqz a0, a0
3481; RV32ZICOND-NEXT:    ret
3482;
3483; RV64ZICOND-LABEL: smulo.not.i64:
3484; RV64ZICOND:       # %bb.0: # %entry
3485; RV64ZICOND-NEXT:    mulh a2, a0, a1
3486; RV64ZICOND-NEXT:    mul a0, a0, a1
3487; RV64ZICOND-NEXT:    srai a0, a0, 63
3488; RV64ZICOND-NEXT:    xor a0, a2, a0
3489; RV64ZICOND-NEXT:    seqz a0, a0
3490; RV64ZICOND-NEXT:    ret
3491entry:
3492  %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
3493  %obit = extractvalue {i64, i1} %t, 1
3494  %ret = xor i1 %obit, true
3495  ret i1 %ret
3496}
3497
3498define i32 @umulo.select.i32(i32 signext %v1, i32 signext %v2) {
3499; RV32-LABEL: umulo.select.i32:
3500; RV32:       # %bb.0: # %entry
3501; RV32-NEXT:    mulhu a2, a0, a1
3502; RV32-NEXT:    bnez a2, .LBB48_2
3503; RV32-NEXT:  # %bb.1: # %entry
3504; RV32-NEXT:    mv a0, a1
3505; RV32-NEXT:  .LBB48_2: # %entry
3506; RV32-NEXT:    ret
3507;
3508; RV64-LABEL: umulo.select.i32:
3509; RV64:       # %bb.0: # %entry
3510; RV64-NEXT:    slli a2, a1, 32
3511; RV64-NEXT:    slli a3, a0, 32
3512; RV64-NEXT:    mulhu a2, a3, a2
3513; RV64-NEXT:    srli a2, a2, 32
3514; RV64-NEXT:    bnez a2, .LBB48_2
3515; RV64-NEXT:  # %bb.1: # %entry
3516; RV64-NEXT:    mv a0, a1
3517; RV64-NEXT:  .LBB48_2: # %entry
3518; RV64-NEXT:    ret
3519;
3520; RV32ZBA-LABEL: umulo.select.i32:
3521; RV32ZBA:       # %bb.0: # %entry
3522; RV32ZBA-NEXT:    mulhu a2, a0, a1
3523; RV32ZBA-NEXT:    bnez a2, .LBB48_2
3524; RV32ZBA-NEXT:  # %bb.1: # %entry
3525; RV32ZBA-NEXT:    mv a0, a1
3526; RV32ZBA-NEXT:  .LBB48_2: # %entry
3527; RV32ZBA-NEXT:    ret
3528;
3529; RV64ZBA-LABEL: umulo.select.i32:
3530; RV64ZBA:       # %bb.0: # %entry
3531; RV64ZBA-NEXT:    zext.w a2, a1
3532; RV64ZBA-NEXT:    zext.w a3, a0
3533; RV64ZBA-NEXT:    mul a2, a3, a2
3534; RV64ZBA-NEXT:    srli a2, a2, 32
3535; RV64ZBA-NEXT:    bnez a2, .LBB48_2
3536; RV64ZBA-NEXT:  # %bb.1: # %entry
3537; RV64ZBA-NEXT:    mv a0, a1
3538; RV64ZBA-NEXT:  .LBB48_2: # %entry
3539; RV64ZBA-NEXT:    ret
3540;
3541; RV32ZICOND-LABEL: umulo.select.i32:
3542; RV32ZICOND:       # %bb.0: # %entry
3543; RV32ZICOND-NEXT:    mulhu a2, a0, a1
3544; RV32ZICOND-NEXT:    czero.nez a1, a1, a2
3545; RV32ZICOND-NEXT:    czero.eqz a0, a0, a2
3546; RV32ZICOND-NEXT:    or a0, a0, a1
3547; RV32ZICOND-NEXT:    ret
3548;
3549; RV64ZICOND-LABEL: umulo.select.i32:
3550; RV64ZICOND:       # %bb.0: # %entry
3551; RV64ZICOND-NEXT:    slli a2, a1, 32
3552; RV64ZICOND-NEXT:    slli a3, a0, 32
3553; RV64ZICOND-NEXT:    mulhu a2, a3, a2
3554; RV64ZICOND-NEXT:    srli a2, a2, 32
3555; RV64ZICOND-NEXT:    czero.nez a1, a1, a2
3556; RV64ZICOND-NEXT:    czero.eqz a0, a0, a2
3557; RV64ZICOND-NEXT:    or a0, a0, a1
3558; RV64ZICOND-NEXT:    ret
3559entry:
3560  %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
3561  %obit = extractvalue {i32, i1} %t, 1
3562  %ret = select i1 %obit, i32 %v1, i32 %v2
3563  ret i32 %ret
3564}
3565
3566define i1 @umulo.not.i32(i32 signext %v1, i32 signext %v2) {
3567; RV32-LABEL: umulo.not.i32:
3568; RV32:       # %bb.0: # %entry
3569; RV32-NEXT:    mulhu a0, a0, a1
3570; RV32-NEXT:    seqz a0, a0
3571; RV32-NEXT:    ret
3572;
3573; RV64-LABEL: umulo.not.i32:
3574; RV64:       # %bb.0: # %entry
3575; RV64-NEXT:    slli a1, a1, 32
3576; RV64-NEXT:    slli a0, a0, 32
3577; RV64-NEXT:    mulhu a0, a0, a1
3578; RV64-NEXT:    srli a0, a0, 32
3579; RV64-NEXT:    seqz a0, a0
3580; RV64-NEXT:    ret
3581;
3582; RV32ZBA-LABEL: umulo.not.i32:
3583; RV32ZBA:       # %bb.0: # %entry
3584; RV32ZBA-NEXT:    mulhu a0, a0, a1
3585; RV32ZBA-NEXT:    seqz a0, a0
3586; RV32ZBA-NEXT:    ret
3587;
3588; RV64ZBA-LABEL: umulo.not.i32:
3589; RV64ZBA:       # %bb.0: # %entry
3590; RV64ZBA-NEXT:    zext.w a1, a1
3591; RV64ZBA-NEXT:    zext.w a0, a0
3592; RV64ZBA-NEXT:    mul a0, a0, a1
3593; RV64ZBA-NEXT:    srli a0, a0, 32
3594; RV64ZBA-NEXT:    seqz a0, a0
3595; RV64ZBA-NEXT:    ret
3596;
3597; RV32ZICOND-LABEL: umulo.not.i32:
3598; RV32ZICOND:       # %bb.0: # %entry
3599; RV32ZICOND-NEXT:    mulhu a0, a0, a1
3600; RV32ZICOND-NEXT:    seqz a0, a0
3601; RV32ZICOND-NEXT:    ret
3602;
3603; RV64ZICOND-LABEL: umulo.not.i32:
3604; RV64ZICOND:       # %bb.0: # %entry
3605; RV64ZICOND-NEXT:    slli a1, a1, 32
3606; RV64ZICOND-NEXT:    slli a0, a0, 32
3607; RV64ZICOND-NEXT:    mulhu a0, a0, a1
3608; RV64ZICOND-NEXT:    srli a0, a0, 32
3609; RV64ZICOND-NEXT:    seqz a0, a0
3610; RV64ZICOND-NEXT:    ret
3611entry:
3612  %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
3613  %obit = extractvalue {i32, i1} %t, 1
3614  %ret = xor i1 %obit, true
3615  ret i1 %ret
3616}
3617
3618define i64 @umulo.select.i64(i64 %v1, i64 %v2) {
3619; RV32-LABEL: umulo.select.i64:
3620; RV32:       # %bb.0: # %entry
3621; RV32-NEXT:    mul a4, a3, a0
3622; RV32-NEXT:    mul a5, a1, a2
3623; RV32-NEXT:    snez a6, a3
3624; RV32-NEXT:    add a4, a5, a4
3625; RV32-NEXT:    snez a5, a1
3626; RV32-NEXT:    and a5, a5, a6
3627; RV32-NEXT:    mulhu a6, a1, a2
3628; RV32-NEXT:    snez a6, a6
3629; RV32-NEXT:    or a5, a5, a6
3630; RV32-NEXT:    mulhu a6, a0, a2
3631; RV32-NEXT:    add a4, a6, a4
3632; RV32-NEXT:    sltu a4, a4, a6
3633; RV32-NEXT:    mulhu a6, a3, a0
3634; RV32-NEXT:    snez a6, a6
3635; RV32-NEXT:    or a5, a5, a6
3636; RV32-NEXT:    or a4, a5, a4
3637; RV32-NEXT:    bnez a4, .LBB50_2
3638; RV32-NEXT:  # %bb.1: # %entry
3639; RV32-NEXT:    mv a0, a2
3640; RV32-NEXT:    mv a1, a3
3641; RV32-NEXT:  .LBB50_2: # %entry
3642; RV32-NEXT:    ret
3643;
3644; RV64-LABEL: umulo.select.i64:
3645; RV64:       # %bb.0: # %entry
3646; RV64-NEXT:    mulhu a2, a0, a1
3647; RV64-NEXT:    bnez a2, .LBB50_2
3648; RV64-NEXT:  # %bb.1: # %entry
3649; RV64-NEXT:    mv a0, a1
3650; RV64-NEXT:  .LBB50_2: # %entry
3651; RV64-NEXT:    ret
3652;
3653; RV32ZBA-LABEL: umulo.select.i64:
3654; RV32ZBA:       # %bb.0: # %entry
3655; RV32ZBA-NEXT:    mul a4, a3, a0
3656; RV32ZBA-NEXT:    mul a5, a1, a2
3657; RV32ZBA-NEXT:    snez a6, a3
3658; RV32ZBA-NEXT:    add a4, a5, a4
3659; RV32ZBA-NEXT:    snez a5, a1
3660; RV32ZBA-NEXT:    and a5, a5, a6
3661; RV32ZBA-NEXT:    mulhu a6, a1, a2
3662; RV32ZBA-NEXT:    snez a6, a6
3663; RV32ZBA-NEXT:    or a5, a5, a6
3664; RV32ZBA-NEXT:    mulhu a6, a0, a2
3665; RV32ZBA-NEXT:    add a4, a6, a4
3666; RV32ZBA-NEXT:    sltu a4, a4, a6
3667; RV32ZBA-NEXT:    mulhu a6, a3, a0
3668; RV32ZBA-NEXT:    snez a6, a6
3669; RV32ZBA-NEXT:    or a5, a5, a6
3670; RV32ZBA-NEXT:    or a4, a5, a4
3671; RV32ZBA-NEXT:    bnez a4, .LBB50_2
3672; RV32ZBA-NEXT:  # %bb.1: # %entry
3673; RV32ZBA-NEXT:    mv a0, a2
3674; RV32ZBA-NEXT:    mv a1, a3
3675; RV32ZBA-NEXT:  .LBB50_2: # %entry
3676; RV32ZBA-NEXT:    ret
3677;
3678; RV64ZBA-LABEL: umulo.select.i64:
3679; RV64ZBA:       # %bb.0: # %entry
3680; RV64ZBA-NEXT:    mulhu a2, a0, a1
3681; RV64ZBA-NEXT:    bnez a2, .LBB50_2
3682; RV64ZBA-NEXT:  # %bb.1: # %entry
3683; RV64ZBA-NEXT:    mv a0, a1
3684; RV64ZBA-NEXT:  .LBB50_2: # %entry
3685; RV64ZBA-NEXT:    ret
3686;
3687; RV32ZICOND-LABEL: umulo.select.i64:
3688; RV32ZICOND:       # %bb.0: # %entry
3689; RV32ZICOND-NEXT:    mul a4, a3, a0
3690; RV32ZICOND-NEXT:    mul a5, a1, a2
3691; RV32ZICOND-NEXT:    snez a6, a3
3692; RV32ZICOND-NEXT:    add a4, a5, a4
3693; RV32ZICOND-NEXT:    snez a5, a1
3694; RV32ZICOND-NEXT:    and a5, a5, a6
3695; RV32ZICOND-NEXT:    mulhu a6, a1, a2
3696; RV32ZICOND-NEXT:    snez a6, a6
3697; RV32ZICOND-NEXT:    or a5, a5, a6
3698; RV32ZICOND-NEXT:    mulhu a6, a0, a2
3699; RV32ZICOND-NEXT:    add a4, a6, a4
3700; RV32ZICOND-NEXT:    sltu a4, a4, a6
3701; RV32ZICOND-NEXT:    mulhu a6, a3, a0
3702; RV32ZICOND-NEXT:    snez a6, a6
3703; RV32ZICOND-NEXT:    or a5, a5, a6
3704; RV32ZICOND-NEXT:    or a4, a5, a4
3705; RV32ZICOND-NEXT:    czero.nez a2, a2, a4
3706; RV32ZICOND-NEXT:    czero.eqz a0, a0, a4
3707; RV32ZICOND-NEXT:    czero.nez a3, a3, a4
3708; RV32ZICOND-NEXT:    czero.eqz a1, a1, a4
3709; RV32ZICOND-NEXT:    or a0, a0, a2
3710; RV32ZICOND-NEXT:    or a1, a1, a3
3711; RV32ZICOND-NEXT:    ret
3712;
3713; RV64ZICOND-LABEL: umulo.select.i64:
3714; RV64ZICOND:       # %bb.0: # %entry
3715; RV64ZICOND-NEXT:    mulhu a2, a0, a1
3716; RV64ZICOND-NEXT:    czero.nez a1, a1, a2
3717; RV64ZICOND-NEXT:    czero.eqz a0, a0, a2
3718; RV64ZICOND-NEXT:    or a0, a0, a1
3719; RV64ZICOND-NEXT:    ret
3720entry:
3721  %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
3722  %obit = extractvalue {i64, i1} %t, 1
3723  %ret = select i1 %obit, i64 %v1, i64 %v2
3724  ret i64 %ret
3725}
3726
3727define i1 @umulo.not.i64(i64 %v1, i64 %v2) {
3728; RV32-LABEL: umulo.not.i64:
3729; RV32:       # %bb.0: # %entry
3730; RV32-NEXT:    mul a4, a3, a0
3731; RV32-NEXT:    mul a5, a1, a2
3732; RV32-NEXT:    mulhu a6, a0, a2
3733; RV32-NEXT:    mulhu a0, a3, a0
3734; RV32-NEXT:    snez a3, a3
3735; RV32-NEXT:    mulhu a2, a1, a2
3736; RV32-NEXT:    snez a1, a1
3737; RV32-NEXT:    add a4, a5, a4
3738; RV32-NEXT:    and a1, a1, a3
3739; RV32-NEXT:    snez a2, a2
3740; RV32-NEXT:    snez a0, a0
3741; RV32-NEXT:    add a4, a6, a4
3742; RV32-NEXT:    or a1, a1, a2
3743; RV32-NEXT:    sltu a2, a4, a6
3744; RV32-NEXT:    or a0, a1, a0
3745; RV32-NEXT:    or a0, a0, a2
3746; RV32-NEXT:    xori a0, a0, 1
3747; RV32-NEXT:    ret
3748;
3749; RV64-LABEL: umulo.not.i64:
3750; RV64:       # %bb.0: # %entry
3751; RV64-NEXT:    mulhu a0, a0, a1
3752; RV64-NEXT:    seqz a0, a0
3753; RV64-NEXT:    ret
3754;
3755; RV32ZBA-LABEL: umulo.not.i64:
3756; RV32ZBA:       # %bb.0: # %entry
3757; RV32ZBA-NEXT:    mul a4, a3, a0
3758; RV32ZBA-NEXT:    mul a5, a1, a2
3759; RV32ZBA-NEXT:    mulhu a6, a0, a2
3760; RV32ZBA-NEXT:    mulhu a0, a3, a0
3761; RV32ZBA-NEXT:    snez a3, a3
3762; RV32ZBA-NEXT:    mulhu a2, a1, a2
3763; RV32ZBA-NEXT:    snez a1, a1
3764; RV32ZBA-NEXT:    add a4, a5, a4
3765; RV32ZBA-NEXT:    and a1, a1, a3
3766; RV32ZBA-NEXT:    snez a2, a2
3767; RV32ZBA-NEXT:    snez a0, a0
3768; RV32ZBA-NEXT:    add a4, a6, a4
3769; RV32ZBA-NEXT:    or a1, a1, a2
3770; RV32ZBA-NEXT:    sltu a2, a4, a6
3771; RV32ZBA-NEXT:    or a0, a1, a0
3772; RV32ZBA-NEXT:    or a0, a0, a2
3773; RV32ZBA-NEXT:    xori a0, a0, 1
3774; RV32ZBA-NEXT:    ret
3775;
3776; RV64ZBA-LABEL: umulo.not.i64:
3777; RV64ZBA:       # %bb.0: # %entry
3778; RV64ZBA-NEXT:    mulhu a0, a0, a1
3779; RV64ZBA-NEXT:    seqz a0, a0
3780; RV64ZBA-NEXT:    ret
3781;
3782; RV32ZICOND-LABEL: umulo.not.i64:
3783; RV32ZICOND:       # %bb.0: # %entry
3784; RV32ZICOND-NEXT:    mul a4, a3, a0
3785; RV32ZICOND-NEXT:    mul a5, a1, a2
3786; RV32ZICOND-NEXT:    mulhu a6, a0, a2
3787; RV32ZICOND-NEXT:    mulhu a0, a3, a0
3788; RV32ZICOND-NEXT:    snez a3, a3
3789; RV32ZICOND-NEXT:    mulhu a2, a1, a2
3790; RV32ZICOND-NEXT:    snez a1, a1
3791; RV32ZICOND-NEXT:    add a4, a5, a4
3792; RV32ZICOND-NEXT:    and a1, a1, a3
3793; RV32ZICOND-NEXT:    snez a2, a2
3794; RV32ZICOND-NEXT:    snez a0, a0
3795; RV32ZICOND-NEXT:    add a4, a6, a4
3796; RV32ZICOND-NEXT:    or a1, a1, a2
3797; RV32ZICOND-NEXT:    sltu a2, a4, a6
3798; RV32ZICOND-NEXT:    or a0, a1, a0
3799; RV32ZICOND-NEXT:    or a0, a0, a2
3800; RV32ZICOND-NEXT:    xori a0, a0, 1
3801; RV32ZICOND-NEXT:    ret
3802;
3803; RV64ZICOND-LABEL: umulo.not.i64:
3804; RV64ZICOND:       # %bb.0: # %entry
3805; RV64ZICOND-NEXT:    mulhu a0, a0, a1
3806; RV64ZICOND-NEXT:    seqz a0, a0
3807; RV64ZICOND-NEXT:    ret
3808entry:
3809  %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
3810  %obit = extractvalue {i64, i1} %t, 1
3811  %ret = xor i1 %obit, true
3812  ret i1 %ret
3813}
3814
3815
3816;
3817; Check the use of the overflow bit in combination with a branch instruction.
3818;
3819define zeroext i1 @saddo.br.i32(i32 signext %v1, i32 signext %v2) {
3820; RV32-LABEL: saddo.br.i32:
3821; RV32:       # %bb.0: # %entry
3822; RV32-NEXT:    add a2, a0, a1
3823; RV32-NEXT:    slt a0, a2, a0
3824; RV32-NEXT:    slti a1, a1, 0
3825; RV32-NEXT:    beq a1, a0, .LBB52_2
3826; RV32-NEXT:  # %bb.1: # %overflow
3827; RV32-NEXT:    li a0, 0
3828; RV32-NEXT:    ret
3829; RV32-NEXT:  .LBB52_2: # %continue
3830; RV32-NEXT:    li a0, 1
3831; RV32-NEXT:    ret
3832;
3833; RV64-LABEL: saddo.br.i32:
3834; RV64:       # %bb.0: # %entry
3835; RV64-NEXT:    add a2, a0, a1
3836; RV64-NEXT:    addw a0, a0, a1
3837; RV64-NEXT:    beq a0, a2, .LBB52_2
3838; RV64-NEXT:  # %bb.1: # %overflow
3839; RV64-NEXT:    li a0, 0
3840; RV64-NEXT:    ret
3841; RV64-NEXT:  .LBB52_2: # %continue
3842; RV64-NEXT:    li a0, 1
3843; RV64-NEXT:    ret
3844;
3845; RV32ZBA-LABEL: saddo.br.i32:
3846; RV32ZBA:       # %bb.0: # %entry
3847; RV32ZBA-NEXT:    add a2, a0, a1
3848; RV32ZBA-NEXT:    slt a0, a2, a0
3849; RV32ZBA-NEXT:    slti a1, a1, 0
3850; RV32ZBA-NEXT:    beq a1, a0, .LBB52_2
3851; RV32ZBA-NEXT:  # %bb.1: # %overflow
3852; RV32ZBA-NEXT:    li a0, 0
3853; RV32ZBA-NEXT:    ret
3854; RV32ZBA-NEXT:  .LBB52_2: # %continue
3855; RV32ZBA-NEXT:    li a0, 1
3856; RV32ZBA-NEXT:    ret
3857;
3858; RV64ZBA-LABEL: saddo.br.i32:
3859; RV64ZBA:       # %bb.0: # %entry
3860; RV64ZBA-NEXT:    add a2, a0, a1
3861; RV64ZBA-NEXT:    addw a0, a0, a1
3862; RV64ZBA-NEXT:    beq a0, a2, .LBB52_2
3863; RV64ZBA-NEXT:  # %bb.1: # %overflow
3864; RV64ZBA-NEXT:    li a0, 0
3865; RV64ZBA-NEXT:    ret
3866; RV64ZBA-NEXT:  .LBB52_2: # %continue
3867; RV64ZBA-NEXT:    li a0, 1
3868; RV64ZBA-NEXT:    ret
3869;
3870; RV32ZICOND-LABEL: saddo.br.i32:
3871; RV32ZICOND:       # %bb.0: # %entry
3872; RV32ZICOND-NEXT:    add a2, a0, a1
3873; RV32ZICOND-NEXT:    slt a0, a2, a0
3874; RV32ZICOND-NEXT:    slti a1, a1, 0
3875; RV32ZICOND-NEXT:    beq a1, a0, .LBB52_2
3876; RV32ZICOND-NEXT:  # %bb.1: # %overflow
3877; RV32ZICOND-NEXT:    li a0, 0
3878; RV32ZICOND-NEXT:    ret
3879; RV32ZICOND-NEXT:  .LBB52_2: # %continue
3880; RV32ZICOND-NEXT:    li a0, 1
3881; RV32ZICOND-NEXT:    ret
3882;
3883; RV64ZICOND-LABEL: saddo.br.i32:
3884; RV64ZICOND:       # %bb.0: # %entry
3885; RV64ZICOND-NEXT:    add a2, a0, a1
3886; RV64ZICOND-NEXT:    addw a0, a0, a1
3887; RV64ZICOND-NEXT:    beq a0, a2, .LBB52_2
3888; RV64ZICOND-NEXT:  # %bb.1: # %overflow
3889; RV64ZICOND-NEXT:    li a0, 0
3890; RV64ZICOND-NEXT:    ret
3891; RV64ZICOND-NEXT:  .LBB52_2: # %continue
3892; RV64ZICOND-NEXT:    li a0, 1
3893; RV64ZICOND-NEXT:    ret
3894entry:
3895  %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2)
3896  %val = extractvalue {i32, i1} %t, 0
3897  %obit = extractvalue {i32, i1} %t, 1
3898  br i1 %obit, label %overflow, label %continue
3899
3900overflow:
3901  ret i1 false
3902
3903continue:
3904  ret i1 true
3905}
3906
3907define zeroext i1 @saddo.br.i64(i64 %v1, i64 %v2) {
3908; RV32-LABEL: saddo.br.i64:
3909; RV32:       # %bb.0: # %entry
3910; RV32-NEXT:    add a4, a1, a3
3911; RV32-NEXT:    add a2, a0, a2
3912; RV32-NEXT:    xor a3, a1, a3
3913; RV32-NEXT:    sltu a0, a2, a0
3914; RV32-NEXT:    add a0, a4, a0
3915; RV32-NEXT:    xor a0, a1, a0
3916; RV32-NEXT:    not a1, a3
3917; RV32-NEXT:    and a0, a1, a0
3918; RV32-NEXT:    bgez a0, .LBB53_2
3919; RV32-NEXT:  # %bb.1: # %overflow
3920; RV32-NEXT:    li a0, 0
3921; RV32-NEXT:    ret
3922; RV32-NEXT:  .LBB53_2: # %continue
3923; RV32-NEXT:    li a0, 1
3924; RV32-NEXT:    ret
3925;
3926; RV64-LABEL: saddo.br.i64:
3927; RV64:       # %bb.0: # %entry
3928; RV64-NEXT:    add a2, a0, a1
3929; RV64-NEXT:    slt a0, a2, a0
3930; RV64-NEXT:    slti a1, a1, 0
3931; RV64-NEXT:    beq a1, a0, .LBB53_2
3932; RV64-NEXT:  # %bb.1: # %overflow
3933; RV64-NEXT:    li a0, 0
3934; RV64-NEXT:    ret
3935; RV64-NEXT:  .LBB53_2: # %continue
3936; RV64-NEXT:    li a0, 1
3937; RV64-NEXT:    ret
3938;
3939; RV32ZBA-LABEL: saddo.br.i64:
3940; RV32ZBA:       # %bb.0: # %entry
3941; RV32ZBA-NEXT:    add a4, a1, a3
3942; RV32ZBA-NEXT:    add a2, a0, a2
3943; RV32ZBA-NEXT:    xor a3, a1, a3
3944; RV32ZBA-NEXT:    sltu a0, a2, a0
3945; RV32ZBA-NEXT:    add a0, a4, a0
3946; RV32ZBA-NEXT:    xor a0, a1, a0
3947; RV32ZBA-NEXT:    not a1, a3
3948; RV32ZBA-NEXT:    and a0, a1, a0
3949; RV32ZBA-NEXT:    bgez a0, .LBB53_2
3950; RV32ZBA-NEXT:  # %bb.1: # %overflow
3951; RV32ZBA-NEXT:    li a0, 0
3952; RV32ZBA-NEXT:    ret
3953; RV32ZBA-NEXT:  .LBB53_2: # %continue
3954; RV32ZBA-NEXT:    li a0, 1
3955; RV32ZBA-NEXT:    ret
3956;
3957; RV64ZBA-LABEL: saddo.br.i64:
3958; RV64ZBA:       # %bb.0: # %entry
3959; RV64ZBA-NEXT:    add a2, a0, a1
3960; RV64ZBA-NEXT:    slt a0, a2, a0
3961; RV64ZBA-NEXT:    slti a1, a1, 0
3962; RV64ZBA-NEXT:    beq a1, a0, .LBB53_2
3963; RV64ZBA-NEXT:  # %bb.1: # %overflow
3964; RV64ZBA-NEXT:    li a0, 0
3965; RV64ZBA-NEXT:    ret
3966; RV64ZBA-NEXT:  .LBB53_2: # %continue
3967; RV64ZBA-NEXT:    li a0, 1
3968; RV64ZBA-NEXT:    ret
3969;
3970; RV32ZICOND-LABEL: saddo.br.i64:
3971; RV32ZICOND:       # %bb.0: # %entry
3972; RV32ZICOND-NEXT:    add a4, a1, a3
3973; RV32ZICOND-NEXT:    add a2, a0, a2
3974; RV32ZICOND-NEXT:    xor a3, a1, a3
3975; RV32ZICOND-NEXT:    sltu a0, a2, a0
3976; RV32ZICOND-NEXT:    add a0, a4, a0
3977; RV32ZICOND-NEXT:    xor a0, a1, a0
3978; RV32ZICOND-NEXT:    not a1, a3
3979; RV32ZICOND-NEXT:    and a0, a1, a0
3980; RV32ZICOND-NEXT:    bgez a0, .LBB53_2
3981; RV32ZICOND-NEXT:  # %bb.1: # %overflow
3982; RV32ZICOND-NEXT:    li a0, 0
3983; RV32ZICOND-NEXT:    ret
3984; RV32ZICOND-NEXT:  .LBB53_2: # %continue
3985; RV32ZICOND-NEXT:    li a0, 1
3986; RV32ZICOND-NEXT:    ret
3987;
3988; RV64ZICOND-LABEL: saddo.br.i64:
3989; RV64ZICOND:       # %bb.0: # %entry
3990; RV64ZICOND-NEXT:    add a2, a0, a1
3991; RV64ZICOND-NEXT:    slt a0, a2, a0
3992; RV64ZICOND-NEXT:    slti a1, a1, 0
3993; RV64ZICOND-NEXT:    beq a1, a0, .LBB53_2
3994; RV64ZICOND-NEXT:  # %bb.1: # %overflow
3995; RV64ZICOND-NEXT:    li a0, 0
3996; RV64ZICOND-NEXT:    ret
3997; RV64ZICOND-NEXT:  .LBB53_2: # %continue
3998; RV64ZICOND-NEXT:    li a0, 1
3999; RV64ZICOND-NEXT:    ret
4000entry:
4001  %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2)
4002  %val = extractvalue {i64, i1} %t, 0
4003  %obit = extractvalue {i64, i1} %t, 1
4004  br i1 %obit, label %overflow, label %continue
4005
4006overflow:
4007  ret i1 false
4008
4009continue:
4010  ret i1 true
4011}
4012
4013define zeroext i1 @uaddo.br.i32(i32 %v1, i32 %v2) {
4014; RV32-LABEL: uaddo.br.i32:
4015; RV32:       # %bb.0: # %entry
4016; RV32-NEXT:    add a1, a0, a1
4017; RV32-NEXT:    bgeu a1, a0, .LBB54_2
4018; RV32-NEXT:  # %bb.1: # %overflow
4019; RV32-NEXT:    li a0, 0
4020; RV32-NEXT:    ret
4021; RV32-NEXT:  .LBB54_2: # %continue
4022; RV32-NEXT:    li a0, 1
4023; RV32-NEXT:    ret
4024;
4025; RV64-LABEL: uaddo.br.i32:
4026; RV64:       # %bb.0: # %entry
4027; RV64-NEXT:    addw a1, a0, a1
4028; RV64-NEXT:    sext.w a0, a0
4029; RV64-NEXT:    bgeu a1, a0, .LBB54_2
4030; RV64-NEXT:  # %bb.1: # %overflow
4031; RV64-NEXT:    li a0, 0
4032; RV64-NEXT:    ret
4033; RV64-NEXT:  .LBB54_2: # %continue
4034; RV64-NEXT:    li a0, 1
4035; RV64-NEXT:    ret
4036;
4037; RV32ZBA-LABEL: uaddo.br.i32:
4038; RV32ZBA:       # %bb.0: # %entry
4039; RV32ZBA-NEXT:    add a1, a0, a1
4040; RV32ZBA-NEXT:    bgeu a1, a0, .LBB54_2
4041; RV32ZBA-NEXT:  # %bb.1: # %overflow
4042; RV32ZBA-NEXT:    li a0, 0
4043; RV32ZBA-NEXT:    ret
4044; RV32ZBA-NEXT:  .LBB54_2: # %continue
4045; RV32ZBA-NEXT:    li a0, 1
4046; RV32ZBA-NEXT:    ret
4047;
4048; RV64ZBA-LABEL: uaddo.br.i32:
4049; RV64ZBA:       # %bb.0: # %entry
4050; RV64ZBA-NEXT:    addw a1, a0, a1
4051; RV64ZBA-NEXT:    sext.w a0, a0
4052; RV64ZBA-NEXT:    bgeu a1, a0, .LBB54_2
4053; RV64ZBA-NEXT:  # %bb.1: # %overflow
4054; RV64ZBA-NEXT:    li a0, 0
4055; RV64ZBA-NEXT:    ret
4056; RV64ZBA-NEXT:  .LBB54_2: # %continue
4057; RV64ZBA-NEXT:    li a0, 1
4058; RV64ZBA-NEXT:    ret
4059;
4060; RV32ZICOND-LABEL: uaddo.br.i32:
4061; RV32ZICOND:       # %bb.0: # %entry
4062; RV32ZICOND-NEXT:    add a1, a0, a1
4063; RV32ZICOND-NEXT:    bgeu a1, a0, .LBB54_2
4064; RV32ZICOND-NEXT:  # %bb.1: # %overflow
4065; RV32ZICOND-NEXT:    li a0, 0
4066; RV32ZICOND-NEXT:    ret
4067; RV32ZICOND-NEXT:  .LBB54_2: # %continue
4068; RV32ZICOND-NEXT:    li a0, 1
4069; RV32ZICOND-NEXT:    ret
4070;
4071; RV64ZICOND-LABEL: uaddo.br.i32:
4072; RV64ZICOND:       # %bb.0: # %entry
4073; RV64ZICOND-NEXT:    addw a1, a0, a1
4074; RV64ZICOND-NEXT:    sext.w a0, a0
4075; RV64ZICOND-NEXT:    bgeu a1, a0, .LBB54_2
4076; RV64ZICOND-NEXT:  # %bb.1: # %overflow
4077; RV64ZICOND-NEXT:    li a0, 0
4078; RV64ZICOND-NEXT:    ret
4079; RV64ZICOND-NEXT:  .LBB54_2: # %continue
4080; RV64ZICOND-NEXT:    li a0, 1
4081; RV64ZICOND-NEXT:    ret
4082entry:
4083  %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)
4084  %val = extractvalue {i32, i1} %t, 0
4085  %obit = extractvalue {i32, i1} %t, 1
4086  br i1 %obit, label %overflow, label %continue
4087
4088overflow:
4089  ret i1 false
4090
4091continue:
4092  ret i1 true
4093}
4094
4095define zeroext i1 @uaddo.br.i64(i64 %v1, i64 %v2) {
4096; RV32-LABEL: uaddo.br.i64:
4097; RV32:       # %bb.0: # %entry
4098; RV32-NEXT:    add a3, a1, a3
4099; RV32-NEXT:    add a2, a0, a2
4100; RV32-NEXT:    sltu a0, a2, a0
4101; RV32-NEXT:    add a2, a3, a0
4102; RV32-NEXT:    beq a2, a1, .LBB55_2
4103; RV32-NEXT:  # %bb.1: # %entry
4104; RV32-NEXT:    sltu a0, a2, a1
4105; RV32-NEXT:  .LBB55_2: # %entry
4106; RV32-NEXT:    beqz a0, .LBB55_4
4107; RV32-NEXT:  # %bb.3: # %overflow
4108; RV32-NEXT:    li a0, 0
4109; RV32-NEXT:    ret
4110; RV32-NEXT:  .LBB55_4: # %continue
4111; RV32-NEXT:    li a0, 1
4112; RV32-NEXT:    ret
4113;
4114; RV64-LABEL: uaddo.br.i64:
4115; RV64:       # %bb.0: # %entry
4116; RV64-NEXT:    add a1, a0, a1
4117; RV64-NEXT:    bgeu a1, a0, .LBB55_2
4118; RV64-NEXT:  # %bb.1: # %overflow
4119; RV64-NEXT:    li a0, 0
4120; RV64-NEXT:    ret
4121; RV64-NEXT:  .LBB55_2: # %continue
4122; RV64-NEXT:    li a0, 1
4123; RV64-NEXT:    ret
4124;
4125; RV32ZBA-LABEL: uaddo.br.i64:
4126; RV32ZBA:       # %bb.0: # %entry
4127; RV32ZBA-NEXT:    add a3, a1, a3
4128; RV32ZBA-NEXT:    add a2, a0, a2
4129; RV32ZBA-NEXT:    sltu a0, a2, a0
4130; RV32ZBA-NEXT:    add a2, a3, a0
4131; RV32ZBA-NEXT:    beq a2, a1, .LBB55_2
4132; RV32ZBA-NEXT:  # %bb.1: # %entry
4133; RV32ZBA-NEXT:    sltu a0, a2, a1
4134; RV32ZBA-NEXT:  .LBB55_2: # %entry
4135; RV32ZBA-NEXT:    beqz a0, .LBB55_4
4136; RV32ZBA-NEXT:  # %bb.3: # %overflow
4137; RV32ZBA-NEXT:    li a0, 0
4138; RV32ZBA-NEXT:    ret
4139; RV32ZBA-NEXT:  .LBB55_4: # %continue
4140; RV32ZBA-NEXT:    li a0, 1
4141; RV32ZBA-NEXT:    ret
4142;
4143; RV64ZBA-LABEL: uaddo.br.i64:
4144; RV64ZBA:       # %bb.0: # %entry
4145; RV64ZBA-NEXT:    add a1, a0, a1
4146; RV64ZBA-NEXT:    bgeu a1, a0, .LBB55_2
4147; RV64ZBA-NEXT:  # %bb.1: # %overflow
4148; RV64ZBA-NEXT:    li a0, 0
4149; RV64ZBA-NEXT:    ret
4150; RV64ZBA-NEXT:  .LBB55_2: # %continue
4151; RV64ZBA-NEXT:    li a0, 1
4152; RV64ZBA-NEXT:    ret
4153;
4154; RV32ZICOND-LABEL: uaddo.br.i64:
4155; RV32ZICOND:       # %bb.0: # %entry
4156; RV32ZICOND-NEXT:    add a3, a1, a3
4157; RV32ZICOND-NEXT:    add a2, a0, a2
4158; RV32ZICOND-NEXT:    sltu a0, a2, a0
4159; RV32ZICOND-NEXT:    add a3, a3, a0
4160; RV32ZICOND-NEXT:    xor a2, a3, a1
4161; RV32ZICOND-NEXT:    sltu a1, a3, a1
4162; RV32ZICOND-NEXT:    czero.eqz a1, a1, a2
4163; RV32ZICOND-NEXT:    czero.nez a0, a0, a2
4164; RV32ZICOND-NEXT:    or a0, a0, a1
4165; RV32ZICOND-NEXT:    beqz a0, .LBB55_2
4166; RV32ZICOND-NEXT:  # %bb.1: # %overflow
4167; RV32ZICOND-NEXT:    li a0, 0
4168; RV32ZICOND-NEXT:    ret
4169; RV32ZICOND-NEXT:  .LBB55_2: # %continue
4170; RV32ZICOND-NEXT:    li a0, 1
4171; RV32ZICOND-NEXT:    ret
4172;
4173; RV64ZICOND-LABEL: uaddo.br.i64:
4174; RV64ZICOND:       # %bb.0: # %entry
4175; RV64ZICOND-NEXT:    add a1, a0, a1
4176; RV64ZICOND-NEXT:    bgeu a1, a0, .LBB55_2
4177; RV64ZICOND-NEXT:  # %bb.1: # %overflow
4178; RV64ZICOND-NEXT:    li a0, 0
4179; RV64ZICOND-NEXT:    ret
4180; RV64ZICOND-NEXT:  .LBB55_2: # %continue
4181; RV64ZICOND-NEXT:    li a0, 1
4182; RV64ZICOND-NEXT:    ret
4183entry:
4184  %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2)
4185  %val = extractvalue {i64, i1} %t, 0
4186  %obit = extractvalue {i64, i1} %t, 1
4187  br i1 %obit, label %overflow, label %continue
4188
4189overflow:
4190  ret i1 false
4191
4192continue:
4193  ret i1 true
4194}
4195
4196define zeroext i1 @ssubo.br.i32(i32 signext %v1, i32 signext %v2) {
4197; RV32-LABEL: ssubo.br.i32:
4198; RV32:       # %bb.0: # %entry
4199; RV32-NEXT:    sgtz a2, a1
4200; RV32-NEXT:    sub a1, a0, a1
4201; RV32-NEXT:    slt a0, a1, a0
4202; RV32-NEXT:    beq a2, a0, .LBB56_2
4203; RV32-NEXT:  # %bb.1: # %overflow
4204; RV32-NEXT:    li a0, 0
4205; RV32-NEXT:    ret
4206; RV32-NEXT:  .LBB56_2: # %continue
4207; RV32-NEXT:    li a0, 1
4208; RV32-NEXT:    ret
4209;
4210; RV64-LABEL: ssubo.br.i32:
4211; RV64:       # %bb.0: # %entry
4212; RV64-NEXT:    sub a2, a0, a1
4213; RV64-NEXT:    subw a0, a0, a1
4214; RV64-NEXT:    beq a0, a2, .LBB56_2
4215; RV64-NEXT:  # %bb.1: # %overflow
4216; RV64-NEXT:    li a0, 0
4217; RV64-NEXT:    ret
4218; RV64-NEXT:  .LBB56_2: # %continue
4219; RV64-NEXT:    li a0, 1
4220; RV64-NEXT:    ret
4221;
4222; RV32ZBA-LABEL: ssubo.br.i32:
4223; RV32ZBA:       # %bb.0: # %entry
4224; RV32ZBA-NEXT:    sgtz a2, a1
4225; RV32ZBA-NEXT:    sub a1, a0, a1
4226; RV32ZBA-NEXT:    slt a0, a1, a0
4227; RV32ZBA-NEXT:    beq a2, a0, .LBB56_2
4228; RV32ZBA-NEXT:  # %bb.1: # %overflow
4229; RV32ZBA-NEXT:    li a0, 0
4230; RV32ZBA-NEXT:    ret
4231; RV32ZBA-NEXT:  .LBB56_2: # %continue
4232; RV32ZBA-NEXT:    li a0, 1
4233; RV32ZBA-NEXT:    ret
4234;
4235; RV64ZBA-LABEL: ssubo.br.i32:
4236; RV64ZBA:       # %bb.0: # %entry
4237; RV64ZBA-NEXT:    sub a2, a0, a1
4238; RV64ZBA-NEXT:    subw a0, a0, a1
4239; RV64ZBA-NEXT:    beq a0, a2, .LBB56_2
4240; RV64ZBA-NEXT:  # %bb.1: # %overflow
4241; RV64ZBA-NEXT:    li a0, 0
4242; RV64ZBA-NEXT:    ret
4243; RV64ZBA-NEXT:  .LBB56_2: # %continue
4244; RV64ZBA-NEXT:    li a0, 1
4245; RV64ZBA-NEXT:    ret
4246;
4247; RV32ZICOND-LABEL: ssubo.br.i32:
4248; RV32ZICOND:       # %bb.0: # %entry
4249; RV32ZICOND-NEXT:    sgtz a2, a1
4250; RV32ZICOND-NEXT:    sub a1, a0, a1
4251; RV32ZICOND-NEXT:    slt a0, a1, a0
4252; RV32ZICOND-NEXT:    beq a2, a0, .LBB56_2
4253; RV32ZICOND-NEXT:  # %bb.1: # %overflow
4254; RV32ZICOND-NEXT:    li a0, 0
4255; RV32ZICOND-NEXT:    ret
4256; RV32ZICOND-NEXT:  .LBB56_2: # %continue
4257; RV32ZICOND-NEXT:    li a0, 1
4258; RV32ZICOND-NEXT:    ret
4259;
4260; RV64ZICOND-LABEL: ssubo.br.i32:
4261; RV64ZICOND:       # %bb.0: # %entry
4262; RV64ZICOND-NEXT:    sub a2, a0, a1
4263; RV64ZICOND-NEXT:    subw a0, a0, a1
4264; RV64ZICOND-NEXT:    beq a0, a2, .LBB56_2
4265; RV64ZICOND-NEXT:  # %bb.1: # %overflow
4266; RV64ZICOND-NEXT:    li a0, 0
4267; RV64ZICOND-NEXT:    ret
4268; RV64ZICOND-NEXT:  .LBB56_2: # %continue
4269; RV64ZICOND-NEXT:    li a0, 1
4270; RV64ZICOND-NEXT:    ret
4271entry:
4272  %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2)
4273  %val = extractvalue {i32, i1} %t, 0
4274  %obit = extractvalue {i32, i1} %t, 1
4275  br i1 %obit, label %overflow, label %continue
4276
4277overflow:
4278  ret i1 false
4279
4280continue:
4281  ret i1 true
4282}
4283
4284define zeroext i1 @ssubo.br.i64(i64 %v1, i64 %v2) {
4285; RV32-LABEL: ssubo.br.i64:
4286; RV32:       # %bb.0: # %entry
4287; RV32-NEXT:    sltu a0, a0, a2
4288; RV32-NEXT:    sub a2, a1, a3
4289; RV32-NEXT:    sub a2, a2, a0
4290; RV32-NEXT:    xor a2, a1, a2
4291; RV32-NEXT:    xor a1, a1, a3
4292; RV32-NEXT:    and a1, a1, a2
4293; RV32-NEXT:    bgez a1, .LBB57_2
4294; RV32-NEXT:  # %bb.1: # %overflow
4295; RV32-NEXT:    li a0, 0
4296; RV32-NEXT:    ret
4297; RV32-NEXT:  .LBB57_2: # %continue
4298; RV32-NEXT:    li a0, 1
4299; RV32-NEXT:    ret
4300;
4301; RV64-LABEL: ssubo.br.i64:
4302; RV64:       # %bb.0: # %entry
4303; RV64-NEXT:    sgtz a2, a1
4304; RV64-NEXT:    sub a1, a0, a1
4305; RV64-NEXT:    slt a0, a1, a0
4306; RV64-NEXT:    beq a2, a0, .LBB57_2
4307; RV64-NEXT:  # %bb.1: # %overflow
4308; RV64-NEXT:    li a0, 0
4309; RV64-NEXT:    ret
4310; RV64-NEXT:  .LBB57_2: # %continue
4311; RV64-NEXT:    li a0, 1
4312; RV64-NEXT:    ret
4313;
4314; RV32ZBA-LABEL: ssubo.br.i64:
4315; RV32ZBA:       # %bb.0: # %entry
4316; RV32ZBA-NEXT:    sltu a0, a0, a2
4317; RV32ZBA-NEXT:    sub a2, a1, a3
4318; RV32ZBA-NEXT:    sub a2, a2, a0
4319; RV32ZBA-NEXT:    xor a2, a1, a2
4320; RV32ZBA-NEXT:    xor a1, a1, a3
4321; RV32ZBA-NEXT:    and a1, a1, a2
4322; RV32ZBA-NEXT:    bgez a1, .LBB57_2
4323; RV32ZBA-NEXT:  # %bb.1: # %overflow
4324; RV32ZBA-NEXT:    li a0, 0
4325; RV32ZBA-NEXT:    ret
4326; RV32ZBA-NEXT:  .LBB57_2: # %continue
4327; RV32ZBA-NEXT:    li a0, 1
4328; RV32ZBA-NEXT:    ret
4329;
4330; RV64ZBA-LABEL: ssubo.br.i64:
4331; RV64ZBA:       # %bb.0: # %entry
4332; RV64ZBA-NEXT:    sgtz a2, a1
4333; RV64ZBA-NEXT:    sub a1, a0, a1
4334; RV64ZBA-NEXT:    slt a0, a1, a0
4335; RV64ZBA-NEXT:    beq a2, a0, .LBB57_2
4336; RV64ZBA-NEXT:  # %bb.1: # %overflow
4337; RV64ZBA-NEXT:    li a0, 0
4338; RV64ZBA-NEXT:    ret
4339; RV64ZBA-NEXT:  .LBB57_2: # %continue
4340; RV64ZBA-NEXT:    li a0, 1
4341; RV64ZBA-NEXT:    ret
4342;
4343; RV32ZICOND-LABEL: ssubo.br.i64:
4344; RV32ZICOND:       # %bb.0: # %entry
4345; RV32ZICOND-NEXT:    sltu a0, a0, a2
4346; RV32ZICOND-NEXT:    sub a2, a1, a3
4347; RV32ZICOND-NEXT:    sub a2, a2, a0
4348; RV32ZICOND-NEXT:    xor a2, a1, a2
4349; RV32ZICOND-NEXT:    xor a1, a1, a3
4350; RV32ZICOND-NEXT:    and a1, a1, a2
4351; RV32ZICOND-NEXT:    bgez a1, .LBB57_2
4352; RV32ZICOND-NEXT:  # %bb.1: # %overflow
4353; RV32ZICOND-NEXT:    li a0, 0
4354; RV32ZICOND-NEXT:    ret
4355; RV32ZICOND-NEXT:  .LBB57_2: # %continue
4356; RV32ZICOND-NEXT:    li a0, 1
4357; RV32ZICOND-NEXT:    ret
4358;
4359; RV64ZICOND-LABEL: ssubo.br.i64:
4360; RV64ZICOND:       # %bb.0: # %entry
4361; RV64ZICOND-NEXT:    sgtz a2, a1
4362; RV64ZICOND-NEXT:    sub a1, a0, a1
4363; RV64ZICOND-NEXT:    slt a0, a1, a0
4364; RV64ZICOND-NEXT:    beq a2, a0, .LBB57_2
4365; RV64ZICOND-NEXT:  # %bb.1: # %overflow
4366; RV64ZICOND-NEXT:    li a0, 0
4367; RV64ZICOND-NEXT:    ret
4368; RV64ZICOND-NEXT:  .LBB57_2: # %continue
4369; RV64ZICOND-NEXT:    li a0, 1
4370; RV64ZICOND-NEXT:    ret
4371entry:
4372  %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2)
4373  %val = extractvalue {i64, i1} %t, 0
4374  %obit = extractvalue {i64, i1} %t, 1
4375  br i1 %obit, label %overflow, label %continue
4376
4377overflow:
4378  ret i1 false
4379
4380continue:
4381  ret i1 true
4382}
4383
4384define zeroext i1 @usubo.br.i32(i32 signext %v1, i32 signext %v2) {
4385; RV32-LABEL: usubo.br.i32:
4386; RV32:       # %bb.0: # %entry
4387; RV32-NEXT:    sub a1, a0, a1
4388; RV32-NEXT:    bgeu a0, a1, .LBB58_2
4389; RV32-NEXT:  # %bb.1: # %overflow
4390; RV32-NEXT:    li a0, 0
4391; RV32-NEXT:    ret
4392; RV32-NEXT:  .LBB58_2: # %continue
4393; RV32-NEXT:    li a0, 1
4394; RV32-NEXT:    ret
4395;
4396; RV64-LABEL: usubo.br.i32:
4397; RV64:       # %bb.0: # %entry
4398; RV64-NEXT:    subw a1, a0, a1
4399; RV64-NEXT:    bgeu a0, a1, .LBB58_2
4400; RV64-NEXT:  # %bb.1: # %overflow
4401; RV64-NEXT:    li a0, 0
4402; RV64-NEXT:    ret
4403; RV64-NEXT:  .LBB58_2: # %continue
4404; RV64-NEXT:    li a0, 1
4405; RV64-NEXT:    ret
4406;
4407; RV32ZBA-LABEL: usubo.br.i32:
4408; RV32ZBA:       # %bb.0: # %entry
4409; RV32ZBA-NEXT:    sub a1, a0, a1
4410; RV32ZBA-NEXT:    bgeu a0, a1, .LBB58_2
4411; RV32ZBA-NEXT:  # %bb.1: # %overflow
4412; RV32ZBA-NEXT:    li a0, 0
4413; RV32ZBA-NEXT:    ret
4414; RV32ZBA-NEXT:  .LBB58_2: # %continue
4415; RV32ZBA-NEXT:    li a0, 1
4416; RV32ZBA-NEXT:    ret
4417;
4418; RV64ZBA-LABEL: usubo.br.i32:
4419; RV64ZBA:       # %bb.0: # %entry
4420; RV64ZBA-NEXT:    subw a1, a0, a1
4421; RV64ZBA-NEXT:    bgeu a0, a1, .LBB58_2
4422; RV64ZBA-NEXT:  # %bb.1: # %overflow
4423; RV64ZBA-NEXT:    li a0, 0
4424; RV64ZBA-NEXT:    ret
4425; RV64ZBA-NEXT:  .LBB58_2: # %continue
4426; RV64ZBA-NEXT:    li a0, 1
4427; RV64ZBA-NEXT:    ret
4428;
4429; RV32ZICOND-LABEL: usubo.br.i32:
4430; RV32ZICOND:       # %bb.0: # %entry
4431; RV32ZICOND-NEXT:    sub a1, a0, a1
4432; RV32ZICOND-NEXT:    bgeu a0, a1, .LBB58_2
4433; RV32ZICOND-NEXT:  # %bb.1: # %overflow
4434; RV32ZICOND-NEXT:    li a0, 0
4435; RV32ZICOND-NEXT:    ret
4436; RV32ZICOND-NEXT:  .LBB58_2: # %continue
4437; RV32ZICOND-NEXT:    li a0, 1
4438; RV32ZICOND-NEXT:    ret
4439;
4440; RV64ZICOND-LABEL: usubo.br.i32:
4441; RV64ZICOND:       # %bb.0: # %entry
4442; RV64ZICOND-NEXT:    subw a1, a0, a1
4443; RV64ZICOND-NEXT:    bgeu a0, a1, .LBB58_2
4444; RV64ZICOND-NEXT:  # %bb.1: # %overflow
4445; RV64ZICOND-NEXT:    li a0, 0
4446; RV64ZICOND-NEXT:    ret
4447; RV64ZICOND-NEXT:  .LBB58_2: # %continue
4448; RV64ZICOND-NEXT:    li a0, 1
4449; RV64ZICOND-NEXT:    ret
4450entry:
4451  %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2)
4452  %val = extractvalue {i32, i1} %t, 0
4453  %obit = extractvalue {i32, i1} %t, 1
4454  br i1 %obit, label %overflow, label %continue
4455
4456overflow:
4457  ret i1 false
4458
4459continue:
4460  ret i1 true
4461}
4462
4463define zeroext i1 @usubo.br.i64(i64 %v1, i64 %v2) {
4464; RV32-LABEL: usubo.br.i64:
4465; RV32:       # %bb.0: # %entry
4466; RV32-NEXT:    sltu a4, a0, a2
4467; RV32-NEXT:    sub a3, a1, a3
4468; RV32-NEXT:    sub a3, a3, a4
4469; RV32-NEXT:    beq a3, a1, .LBB59_3
4470; RV32-NEXT:  # %bb.1: # %entry
4471; RV32-NEXT:    sltu a0, a1, a3
4472; RV32-NEXT:    bnez a0, .LBB59_4
4473; RV32-NEXT:  .LBB59_2: # %continue
4474; RV32-NEXT:    li a0, 1
4475; RV32-NEXT:    ret
4476; RV32-NEXT:  .LBB59_3:
4477; RV32-NEXT:    sub a1, a0, a2
4478; RV32-NEXT:    sltu a0, a0, a1
4479; RV32-NEXT:    beqz a0, .LBB59_2
4480; RV32-NEXT:  .LBB59_4: # %overflow
4481; RV32-NEXT:    li a0, 0
4482; RV32-NEXT:    ret
4483;
4484; RV64-LABEL: usubo.br.i64:
4485; RV64:       # %bb.0: # %entry
4486; RV64-NEXT:    sub a1, a0, a1
4487; RV64-NEXT:    bgeu a0, a1, .LBB59_2
4488; RV64-NEXT:  # %bb.1: # %overflow
4489; RV64-NEXT:    li a0, 0
4490; RV64-NEXT:    ret
4491; RV64-NEXT:  .LBB59_2: # %continue
4492; RV64-NEXT:    li a0, 1
4493; RV64-NEXT:    ret
4494;
4495; RV32ZBA-LABEL: usubo.br.i64:
4496; RV32ZBA:       # %bb.0: # %entry
4497; RV32ZBA-NEXT:    sltu a4, a0, a2
4498; RV32ZBA-NEXT:    sub a3, a1, a3
4499; RV32ZBA-NEXT:    sub a3, a3, a4
4500; RV32ZBA-NEXT:    beq a3, a1, .LBB59_3
4501; RV32ZBA-NEXT:  # %bb.1: # %entry
4502; RV32ZBA-NEXT:    sltu a0, a1, a3
4503; RV32ZBA-NEXT:    bnez a0, .LBB59_4
4504; RV32ZBA-NEXT:  .LBB59_2: # %continue
4505; RV32ZBA-NEXT:    li a0, 1
4506; RV32ZBA-NEXT:    ret
4507; RV32ZBA-NEXT:  .LBB59_3:
4508; RV32ZBA-NEXT:    sub a1, a0, a2
4509; RV32ZBA-NEXT:    sltu a0, a0, a1
4510; RV32ZBA-NEXT:    beqz a0, .LBB59_2
4511; RV32ZBA-NEXT:  .LBB59_4: # %overflow
4512; RV32ZBA-NEXT:    li a0, 0
4513; RV32ZBA-NEXT:    ret
4514;
4515; RV64ZBA-LABEL: usubo.br.i64:
4516; RV64ZBA:       # %bb.0: # %entry
4517; RV64ZBA-NEXT:    sub a1, a0, a1
4518; RV64ZBA-NEXT:    bgeu a0, a1, .LBB59_2
4519; RV64ZBA-NEXT:  # %bb.1: # %overflow
4520; RV64ZBA-NEXT:    li a0, 0
4521; RV64ZBA-NEXT:    ret
4522; RV64ZBA-NEXT:  .LBB59_2: # %continue
4523; RV64ZBA-NEXT:    li a0, 1
4524; RV64ZBA-NEXT:    ret
4525;
4526; RV32ZICOND-LABEL: usubo.br.i64:
4527; RV32ZICOND:       # %bb.0: # %entry
4528; RV32ZICOND-NEXT:    sltu a4, a0, a2
4529; RV32ZICOND-NEXT:    sub a3, a1, a3
4530; RV32ZICOND-NEXT:    sub a2, a0, a2
4531; RV32ZICOND-NEXT:    sub a3, a3, a4
4532; RV32ZICOND-NEXT:    sltu a0, a0, a2
4533; RV32ZICOND-NEXT:    xor a2, a3, a1
4534; RV32ZICOND-NEXT:    sltu a1, a1, a3
4535; RV32ZICOND-NEXT:    czero.eqz a1, a1, a2
4536; RV32ZICOND-NEXT:    czero.nez a0, a0, a2
4537; RV32ZICOND-NEXT:    or a0, a0, a1
4538; RV32ZICOND-NEXT:    beqz a0, .LBB59_2
4539; RV32ZICOND-NEXT:  # %bb.1: # %overflow
4540; RV32ZICOND-NEXT:    li a0, 0
4541; RV32ZICOND-NEXT:    ret
4542; RV32ZICOND-NEXT:  .LBB59_2: # %continue
4543; RV32ZICOND-NEXT:    li a0, 1
4544; RV32ZICOND-NEXT:    ret
4545;
4546; RV64ZICOND-LABEL: usubo.br.i64:
4547; RV64ZICOND:       # %bb.0: # %entry
4548; RV64ZICOND-NEXT:    sub a1, a0, a1
4549; RV64ZICOND-NEXT:    bgeu a0, a1, .LBB59_2
4550; RV64ZICOND-NEXT:  # %bb.1: # %overflow
4551; RV64ZICOND-NEXT:    li a0, 0
4552; RV64ZICOND-NEXT:    ret
4553; RV64ZICOND-NEXT:  .LBB59_2: # %continue
4554; RV64ZICOND-NEXT:    li a0, 1
4555; RV64ZICOND-NEXT:    ret
4556entry:
4557  %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2)
4558  %val = extractvalue {i64, i1} %t, 0
4559  %obit = extractvalue {i64, i1} %t, 1
4560  br i1 %obit, label %overflow, label %continue
4561
4562overflow:
4563  ret i1 false
4564
4565continue:
4566  ret i1 true
4567}
4568
4569define zeroext i1 @smulo.br.i32(i32 signext %v1, i32 signext %v2) {
4570; RV32-LABEL: smulo.br.i32:
4571; RV32:       # %bb.0: # %entry
4572; RV32-NEXT:    mulh a2, a0, a1
4573; RV32-NEXT:    mul a0, a0, a1
4574; RV32-NEXT:    srai a0, a0, 31
4575; RV32-NEXT:    beq a2, a0, .LBB60_2
4576; RV32-NEXT:  # %bb.1: # %overflow
4577; RV32-NEXT:    li a0, 0
4578; RV32-NEXT:    ret
4579; RV32-NEXT:  .LBB60_2: # %continue
4580; RV32-NEXT:    li a0, 1
4581; RV32-NEXT:    ret
4582;
4583; RV64-LABEL: smulo.br.i32:
4584; RV64:       # %bb.0: # %entry
4585; RV64-NEXT:    mul a2, a0, a1
4586; RV64-NEXT:    mulw a0, a0, a1
4587; RV64-NEXT:    beq a0, a2, .LBB60_2
4588; RV64-NEXT:  # %bb.1: # %overflow
4589; RV64-NEXT:    li a0, 0
4590; RV64-NEXT:    ret
4591; RV64-NEXT:  .LBB60_2: # %continue
4592; RV64-NEXT:    li a0, 1
4593; RV64-NEXT:    ret
4594;
4595; RV32ZBA-LABEL: smulo.br.i32:
4596; RV32ZBA:       # %bb.0: # %entry
4597; RV32ZBA-NEXT:    mulh a2, a0, a1
4598; RV32ZBA-NEXT:    mul a0, a0, a1
4599; RV32ZBA-NEXT:    srai a0, a0, 31
4600; RV32ZBA-NEXT:    beq a2, a0, .LBB60_2
4601; RV32ZBA-NEXT:  # %bb.1: # %overflow
4602; RV32ZBA-NEXT:    li a0, 0
4603; RV32ZBA-NEXT:    ret
4604; RV32ZBA-NEXT:  .LBB60_2: # %continue
4605; RV32ZBA-NEXT:    li a0, 1
4606; RV32ZBA-NEXT:    ret
4607;
4608; RV64ZBA-LABEL: smulo.br.i32:
4609; RV64ZBA:       # %bb.0: # %entry
4610; RV64ZBA-NEXT:    mul a2, a0, a1
4611; RV64ZBA-NEXT:    mulw a0, a0, a1
4612; RV64ZBA-NEXT:    beq a0, a2, .LBB60_2
4613; RV64ZBA-NEXT:  # %bb.1: # %overflow
4614; RV64ZBA-NEXT:    li a0, 0
4615; RV64ZBA-NEXT:    ret
4616; RV64ZBA-NEXT:  .LBB60_2: # %continue
4617; RV64ZBA-NEXT:    li a0, 1
4618; RV64ZBA-NEXT:    ret
4619;
4620; RV32ZICOND-LABEL: smulo.br.i32:
4621; RV32ZICOND:       # %bb.0: # %entry
4622; RV32ZICOND-NEXT:    mulh a2, a0, a1
4623; RV32ZICOND-NEXT:    mul a0, a0, a1
4624; RV32ZICOND-NEXT:    srai a0, a0, 31
4625; RV32ZICOND-NEXT:    beq a2, a0, .LBB60_2
4626; RV32ZICOND-NEXT:  # %bb.1: # %overflow
4627; RV32ZICOND-NEXT:    li a0, 0
4628; RV32ZICOND-NEXT:    ret
4629; RV32ZICOND-NEXT:  .LBB60_2: # %continue
4630; RV32ZICOND-NEXT:    li a0, 1
4631; RV32ZICOND-NEXT:    ret
4632;
4633; RV64ZICOND-LABEL: smulo.br.i32:
4634; RV64ZICOND:       # %bb.0: # %entry
4635; RV64ZICOND-NEXT:    mul a2, a0, a1
4636; RV64ZICOND-NEXT:    mulw a0, a0, a1
4637; RV64ZICOND-NEXT:    beq a0, a2, .LBB60_2
4638; RV64ZICOND-NEXT:  # %bb.1: # %overflow
4639; RV64ZICOND-NEXT:    li a0, 0
4640; RV64ZICOND-NEXT:    ret
4641; RV64ZICOND-NEXT:  .LBB60_2: # %continue
4642; RV64ZICOND-NEXT:    li a0, 1
4643; RV64ZICOND-NEXT:    ret
4644entry:
4645  %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
4646  %val = extractvalue {i32, i1} %t, 0
4647  %obit = extractvalue {i32, i1} %t, 1
4648  br i1 %obit, label %overflow, label %continue
4649
4650overflow:
4651  ret i1 false
4652
4653continue:
4654  ret i1 true
4655}
4656
4657define zeroext i1 @smulo.br.i64(i64 %v1, i64 %v2) {
4658; RV32-LABEL: smulo.br.i64:
4659; RV32:       # %bb.0: # %entry
4660; RV32-NEXT:    mulhu a4, a0, a2
4661; RV32-NEXT:    mul a5, a1, a2
4662; RV32-NEXT:    mulhsu a2, a1, a2
4663; RV32-NEXT:    mul a6, a3, a0
4664; RV32-NEXT:    mulhsu a0, a3, a0
4665; RV32-NEXT:    mulh a7, a1, a3
4666; RV32-NEXT:    mul a1, a1, a3
4667; RV32-NEXT:    add a4, a5, a4
4668; RV32-NEXT:    sltu a3, a4, a5
4669; RV32-NEXT:    add a4, a6, a4
4670; RV32-NEXT:    add a2, a2, a3
4671; RV32-NEXT:    sltu a3, a4, a6
4672; RV32-NEXT:    srai a4, a4, 31
4673; RV32-NEXT:    add a0, a0, a3
4674; RV32-NEXT:    srai a3, a2, 31
4675; RV32-NEXT:    add a5, a2, a0
4676; RV32-NEXT:    srai a0, a0, 31
4677; RV32-NEXT:    sltu a2, a5, a2
4678; RV32-NEXT:    add a0, a3, a0
4679; RV32-NEXT:    add a5, a1, a5
4680; RV32-NEXT:    add a0, a0, a2
4681; RV32-NEXT:    sltu a1, a5, a1
4682; RV32-NEXT:    add a0, a7, a0
4683; RV32-NEXT:    add a0, a0, a1
4684; RV32-NEXT:    xor a0, a0, a4
4685; RV32-NEXT:    xor a4, a5, a4
4686; RV32-NEXT:    or a0, a4, a0
4687; RV32-NEXT:    beqz a0, .LBB61_2
4688; RV32-NEXT:  # %bb.1: # %overflow
4689; RV32-NEXT:    li a0, 0
4690; RV32-NEXT:    ret
4691; RV32-NEXT:  .LBB61_2: # %continue
4692; RV32-NEXT:    li a0, 1
4693; RV32-NEXT:    ret
4694;
4695; RV64-LABEL: smulo.br.i64:
4696; RV64:       # %bb.0: # %entry
4697; RV64-NEXT:    mulh a2, a0, a1
4698; RV64-NEXT:    mul a0, a0, a1
4699; RV64-NEXT:    srai a0, a0, 63
4700; RV64-NEXT:    beq a2, a0, .LBB61_2
4701; RV64-NEXT:  # %bb.1: # %overflow
4702; RV64-NEXT:    li a0, 0
4703; RV64-NEXT:    ret
4704; RV64-NEXT:  .LBB61_2: # %continue
4705; RV64-NEXT:    li a0, 1
4706; RV64-NEXT:    ret
4707;
4708; RV32ZBA-LABEL: smulo.br.i64:
4709; RV32ZBA:       # %bb.0: # %entry
4710; RV32ZBA-NEXT:    mulhu a4, a0, a2
4711; RV32ZBA-NEXT:    mul a5, a1, a2
4712; RV32ZBA-NEXT:    mulhsu a2, a1, a2
4713; RV32ZBA-NEXT:    mul a6, a3, a0
4714; RV32ZBA-NEXT:    mulhsu a0, a3, a0
4715; RV32ZBA-NEXT:    mulh a7, a1, a3
4716; RV32ZBA-NEXT:    mul a1, a1, a3
4717; RV32ZBA-NEXT:    add a4, a5, a4
4718; RV32ZBA-NEXT:    sltu a3, a4, a5
4719; RV32ZBA-NEXT:    add a4, a6, a4
4720; RV32ZBA-NEXT:    add a2, a2, a3
4721; RV32ZBA-NEXT:    sltu a3, a4, a6
4722; RV32ZBA-NEXT:    srai a4, a4, 31
4723; RV32ZBA-NEXT:    add a0, a0, a3
4724; RV32ZBA-NEXT:    srai a3, a2, 31
4725; RV32ZBA-NEXT:    add a5, a2, a0
4726; RV32ZBA-NEXT:    srai a0, a0, 31
4727; RV32ZBA-NEXT:    sltu a2, a5, a2
4728; RV32ZBA-NEXT:    add a0, a3, a0
4729; RV32ZBA-NEXT:    add a5, a1, a5
4730; RV32ZBA-NEXT:    add a0, a0, a2
4731; RV32ZBA-NEXT:    sltu a1, a5, a1
4732; RV32ZBA-NEXT:    add a0, a7, a0
4733; RV32ZBA-NEXT:    add a0, a0, a1
4734; RV32ZBA-NEXT:    xor a0, a0, a4
4735; RV32ZBA-NEXT:    xor a4, a5, a4
4736; RV32ZBA-NEXT:    or a0, a4, a0
4737; RV32ZBA-NEXT:    beqz a0, .LBB61_2
4738; RV32ZBA-NEXT:  # %bb.1: # %overflow
4739; RV32ZBA-NEXT:    li a0, 0
4740; RV32ZBA-NEXT:    ret
4741; RV32ZBA-NEXT:  .LBB61_2: # %continue
4742; RV32ZBA-NEXT:    li a0, 1
4743; RV32ZBA-NEXT:    ret
4744;
4745; RV64ZBA-LABEL: smulo.br.i64:
4746; RV64ZBA:       # %bb.0: # %entry
4747; RV64ZBA-NEXT:    mulh a2, a0, a1
4748; RV64ZBA-NEXT:    mul a0, a0, a1
4749; RV64ZBA-NEXT:    srai a0, a0, 63
4750; RV64ZBA-NEXT:    beq a2, a0, .LBB61_2
4751; RV64ZBA-NEXT:  # %bb.1: # %overflow
4752; RV64ZBA-NEXT:    li a0, 0
4753; RV64ZBA-NEXT:    ret
4754; RV64ZBA-NEXT:  .LBB61_2: # %continue
4755; RV64ZBA-NEXT:    li a0, 1
4756; RV64ZBA-NEXT:    ret
4757;
4758; RV32ZICOND-LABEL: smulo.br.i64:
4759; RV32ZICOND:       # %bb.0: # %entry
4760; RV32ZICOND-NEXT:    mulhu a4, a0, a2
4761; RV32ZICOND-NEXT:    mul a5, a1, a2
4762; RV32ZICOND-NEXT:    mulhsu a2, a1, a2
4763; RV32ZICOND-NEXT:    mul a6, a3, a0
4764; RV32ZICOND-NEXT:    mulhsu a0, a3, a0
4765; RV32ZICOND-NEXT:    mulh a7, a1, a3
4766; RV32ZICOND-NEXT:    mul a1, a1, a3
4767; RV32ZICOND-NEXT:    add a4, a5, a4
4768; RV32ZICOND-NEXT:    sltu a3, a4, a5
4769; RV32ZICOND-NEXT:    add a4, a6, a4
4770; RV32ZICOND-NEXT:    add a2, a2, a3
4771; RV32ZICOND-NEXT:    sltu a3, a4, a6
4772; RV32ZICOND-NEXT:    srai a4, a4, 31
4773; RV32ZICOND-NEXT:    add a0, a0, a3
4774; RV32ZICOND-NEXT:    srai a3, a2, 31
4775; RV32ZICOND-NEXT:    add a5, a2, a0
4776; RV32ZICOND-NEXT:    srai a0, a0, 31
4777; RV32ZICOND-NEXT:    sltu a2, a5, a2
4778; RV32ZICOND-NEXT:    add a0, a3, a0
4779; RV32ZICOND-NEXT:    add a5, a1, a5
4780; RV32ZICOND-NEXT:    add a0, a0, a2
4781; RV32ZICOND-NEXT:    sltu a1, a5, a1
4782; RV32ZICOND-NEXT:    add a0, a7, a0
4783; RV32ZICOND-NEXT:    add a0, a0, a1
4784; RV32ZICOND-NEXT:    xor a0, a0, a4
4785; RV32ZICOND-NEXT:    xor a4, a5, a4
4786; RV32ZICOND-NEXT:    or a0, a4, a0
4787; RV32ZICOND-NEXT:    beqz a0, .LBB61_2
4788; RV32ZICOND-NEXT:  # %bb.1: # %overflow
4789; RV32ZICOND-NEXT:    li a0, 0
4790; RV32ZICOND-NEXT:    ret
4791; RV32ZICOND-NEXT:  .LBB61_2: # %continue
4792; RV32ZICOND-NEXT:    li a0, 1
4793; RV32ZICOND-NEXT:    ret
4794;
4795; RV64ZICOND-LABEL: smulo.br.i64:
4796; RV64ZICOND:       # %bb.0: # %entry
4797; RV64ZICOND-NEXT:    mulh a2, a0, a1
4798; RV64ZICOND-NEXT:    mul a0, a0, a1
4799; RV64ZICOND-NEXT:    srai a0, a0, 63
4800; RV64ZICOND-NEXT:    beq a2, a0, .LBB61_2
4801; RV64ZICOND-NEXT:  # %bb.1: # %overflow
4802; RV64ZICOND-NEXT:    li a0, 0
4803; RV64ZICOND-NEXT:    ret
4804; RV64ZICOND-NEXT:  .LBB61_2: # %continue
4805; RV64ZICOND-NEXT:    li a0, 1
4806; RV64ZICOND-NEXT:    ret
4807entry:
4808  %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
4809  %val = extractvalue {i64, i1} %t, 0
4810  %obit = extractvalue {i64, i1} %t, 1
4811  br i1 %obit, label %overflow, label %continue
4812
4813overflow:
4814  ret i1 false
4815
4816continue:
4817  ret i1 true
4818}
4819
4820define zeroext i1 @smulo2.br.i64(i64 %v1) {
4821; RV32-LABEL: smulo2.br.i64:
4822; RV32:       # %bb.0: # %entry
4823; RV32-NEXT:    li a2, -13
4824; RV32-NEXT:    neg a3, a0
4825; RV32-NEXT:    li a4, -1
4826; RV32-NEXT:    mulhu a5, a0, a2
4827; RV32-NEXT:    mul a6, a1, a2
4828; RV32-NEXT:    mulhsu a2, a1, a2
4829; RV32-NEXT:    add a5, a6, a5
4830; RV32-NEXT:    sltu a6, a5, a6
4831; RV32-NEXT:    sub a5, a5, a0
4832; RV32-NEXT:    mulhsu a0, a4, a0
4833; RV32-NEXT:    add a2, a2, a6
4834; RV32-NEXT:    sltu a3, a5, a3
4835; RV32-NEXT:    add a0, a0, a3
4836; RV32-NEXT:    srai a3, a2, 31
4837; RV32-NEXT:    srai a6, a0, 31
4838; RV32-NEXT:    add a3, a3, a6
4839; RV32-NEXT:    neg a6, a1
4840; RV32-NEXT:    mulh a4, a1, a4
4841; RV32-NEXT:    srai a5, a5, 31
4842; RV32-NEXT:    add a0, a2, a0
4843; RV32-NEXT:    sltu a2, a0, a2
4844; RV32-NEXT:    sub a0, a0, a1
4845; RV32-NEXT:    add a2, a3, a2
4846; RV32-NEXT:    sltu a1, a0, a6
4847; RV32-NEXT:    add a2, a4, a2
4848; RV32-NEXT:    add a1, a2, a1
4849; RV32-NEXT:    xor a1, a1, a5
4850; RV32-NEXT:    xor a0, a0, a5
4851; RV32-NEXT:    or a0, a0, a1
4852; RV32-NEXT:    beqz a0, .LBB62_2
4853; RV32-NEXT:  # %bb.1: # %overflow
4854; RV32-NEXT:    li a0, 0
4855; RV32-NEXT:    ret
4856; RV32-NEXT:  .LBB62_2: # %continue
4857; RV32-NEXT:    li a0, 1
4858; RV32-NEXT:    ret
4859;
4860; RV64-LABEL: smulo2.br.i64:
4861; RV64:       # %bb.0: # %entry
4862; RV64-NEXT:    li a1, -13
4863; RV64-NEXT:    mulh a2, a0, a1
4864; RV64-NEXT:    mul a0, a0, a1
4865; RV64-NEXT:    srai a0, a0, 63
4866; RV64-NEXT:    beq a2, a0, .LBB62_2
4867; RV64-NEXT:  # %bb.1: # %overflow
4868; RV64-NEXT:    li a0, 0
4869; RV64-NEXT:    ret
4870; RV64-NEXT:  .LBB62_2: # %continue
4871; RV64-NEXT:    li a0, 1
4872; RV64-NEXT:    ret
4873;
4874; RV32ZBA-LABEL: smulo2.br.i64:
4875; RV32ZBA:       # %bb.0: # %entry
4876; RV32ZBA-NEXT:    li a2, -13
4877; RV32ZBA-NEXT:    neg a3, a0
4878; RV32ZBA-NEXT:    li a4, -1
4879; RV32ZBA-NEXT:    mulhu a5, a0, a2
4880; RV32ZBA-NEXT:    mul a6, a1, a2
4881; RV32ZBA-NEXT:    mulhsu a2, a1, a2
4882; RV32ZBA-NEXT:    add a5, a6, a5
4883; RV32ZBA-NEXT:    sltu a6, a5, a6
4884; RV32ZBA-NEXT:    sub a5, a5, a0
4885; RV32ZBA-NEXT:    mulhsu a0, a4, a0
4886; RV32ZBA-NEXT:    add a2, a2, a6
4887; RV32ZBA-NEXT:    sltu a3, a5, a3
4888; RV32ZBA-NEXT:    add a0, a0, a3
4889; RV32ZBA-NEXT:    srai a3, a2, 31
4890; RV32ZBA-NEXT:    srai a6, a0, 31
4891; RV32ZBA-NEXT:    add a3, a3, a6
4892; RV32ZBA-NEXT:    neg a6, a1
4893; RV32ZBA-NEXT:    mulh a4, a1, a4
4894; RV32ZBA-NEXT:    srai a5, a5, 31
4895; RV32ZBA-NEXT:    add a0, a2, a0
4896; RV32ZBA-NEXT:    sltu a2, a0, a2
4897; RV32ZBA-NEXT:    sub a0, a0, a1
4898; RV32ZBA-NEXT:    add a2, a3, a2
4899; RV32ZBA-NEXT:    sltu a1, a0, a6
4900; RV32ZBA-NEXT:    add a2, a4, a2
4901; RV32ZBA-NEXT:    add a1, a2, a1
4902; RV32ZBA-NEXT:    xor a1, a1, a5
4903; RV32ZBA-NEXT:    xor a0, a0, a5
4904; RV32ZBA-NEXT:    or a0, a0, a1
4905; RV32ZBA-NEXT:    beqz a0, .LBB62_2
4906; RV32ZBA-NEXT:  # %bb.1: # %overflow
4907; RV32ZBA-NEXT:    li a0, 0
4908; RV32ZBA-NEXT:    ret
4909; RV32ZBA-NEXT:  .LBB62_2: # %continue
4910; RV32ZBA-NEXT:    li a0, 1
4911; RV32ZBA-NEXT:    ret
4912;
4913; RV64ZBA-LABEL: smulo2.br.i64:
4914; RV64ZBA:       # %bb.0: # %entry
4915; RV64ZBA-NEXT:    li a1, -13
4916; RV64ZBA-NEXT:    mulh a2, a0, a1
4917; RV64ZBA-NEXT:    mul a0, a0, a1
4918; RV64ZBA-NEXT:    srai a0, a0, 63
4919; RV64ZBA-NEXT:    beq a2, a0, .LBB62_2
4920; RV64ZBA-NEXT:  # %bb.1: # %overflow
4921; RV64ZBA-NEXT:    li a0, 0
4922; RV64ZBA-NEXT:    ret
4923; RV64ZBA-NEXT:  .LBB62_2: # %continue
4924; RV64ZBA-NEXT:    li a0, 1
4925; RV64ZBA-NEXT:    ret
4926;
4927; RV32ZICOND-LABEL: smulo2.br.i64:
4928; RV32ZICOND:       # %bb.0: # %entry
4929; RV32ZICOND-NEXT:    li a2, -13
4930; RV32ZICOND-NEXT:    neg a3, a0
4931; RV32ZICOND-NEXT:    li a4, -1
4932; RV32ZICOND-NEXT:    mulhu a5, a0, a2
4933; RV32ZICOND-NEXT:    mul a6, a1, a2
4934; RV32ZICOND-NEXT:    mulhsu a2, a1, a2
4935; RV32ZICOND-NEXT:    add a5, a6, a5
4936; RV32ZICOND-NEXT:    sltu a6, a5, a6
4937; RV32ZICOND-NEXT:    sub a5, a5, a0
4938; RV32ZICOND-NEXT:    mulhsu a0, a4, a0
4939; RV32ZICOND-NEXT:    add a2, a2, a6
4940; RV32ZICOND-NEXT:    sltu a3, a5, a3
4941; RV32ZICOND-NEXT:    add a0, a0, a3
4942; RV32ZICOND-NEXT:    srai a3, a2, 31
4943; RV32ZICOND-NEXT:    srai a6, a0, 31
4944; RV32ZICOND-NEXT:    add a3, a3, a6
4945; RV32ZICOND-NEXT:    neg a6, a1
4946; RV32ZICOND-NEXT:    mulh a4, a1, a4
4947; RV32ZICOND-NEXT:    srai a5, a5, 31
4948; RV32ZICOND-NEXT:    add a0, a2, a0
4949; RV32ZICOND-NEXT:    sltu a2, a0, a2
4950; RV32ZICOND-NEXT:    sub a0, a0, a1
4951; RV32ZICOND-NEXT:    add a2, a3, a2
4952; RV32ZICOND-NEXT:    sltu a1, a0, a6
4953; RV32ZICOND-NEXT:    add a2, a4, a2
4954; RV32ZICOND-NEXT:    add a1, a2, a1
4955; RV32ZICOND-NEXT:    xor a1, a1, a5
4956; RV32ZICOND-NEXT:    xor a0, a0, a5
4957; RV32ZICOND-NEXT:    or a0, a0, a1
4958; RV32ZICOND-NEXT:    beqz a0, .LBB62_2
4959; RV32ZICOND-NEXT:  # %bb.1: # %overflow
4960; RV32ZICOND-NEXT:    li a0, 0
4961; RV32ZICOND-NEXT:    ret
4962; RV32ZICOND-NEXT:  .LBB62_2: # %continue
4963; RV32ZICOND-NEXT:    li a0, 1
4964; RV32ZICOND-NEXT:    ret
4965;
4966; RV64ZICOND-LABEL: smulo2.br.i64:
4967; RV64ZICOND:       # %bb.0: # %entry
4968; RV64ZICOND-NEXT:    li a1, -13
4969; RV64ZICOND-NEXT:    mulh a2, a0, a1
4970; RV64ZICOND-NEXT:    mul a0, a0, a1
4971; RV64ZICOND-NEXT:    srai a0, a0, 63
4972; RV64ZICOND-NEXT:    beq a2, a0, .LBB62_2
4973; RV64ZICOND-NEXT:  # %bb.1: # %overflow
4974; RV64ZICOND-NEXT:    li a0, 0
4975; RV64ZICOND-NEXT:    ret
4976; RV64ZICOND-NEXT:  .LBB62_2: # %continue
4977; RV64ZICOND-NEXT:    li a0, 1
4978; RV64ZICOND-NEXT:    ret
4979entry:
4980  %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 -13)
4981  %val = extractvalue {i64, i1} %t, 0
4982  %obit = extractvalue {i64, i1} %t, 1
4983  br i1 %obit, label %overflow, label %continue
4984
4985overflow:
4986  ret i1 false
4987
4988continue:
4989  ret i1 true
4990}
4991
4992define zeroext i1 @umulo.br.i32(i32 signext %v1, i32 signext %v2) {
4993; RV32-LABEL: umulo.br.i32:
4994; RV32:       # %bb.0: # %entry
4995; RV32-NEXT:    mulhu a0, a0, a1
4996; RV32-NEXT:    beqz a0, .LBB63_2
4997; RV32-NEXT:  # %bb.1: # %overflow
4998; RV32-NEXT:    li a0, 0
4999; RV32-NEXT:    ret
5000; RV32-NEXT:  .LBB63_2: # %continue
5001; RV32-NEXT:    li a0, 1
5002; RV32-NEXT:    ret
5003;
5004; RV64-LABEL: umulo.br.i32:
5005; RV64:       # %bb.0: # %entry
5006; RV64-NEXT:    slli a1, a1, 32
5007; RV64-NEXT:    slli a0, a0, 32
5008; RV64-NEXT:    mulhu a0, a0, a1
5009; RV64-NEXT:    srli a0, a0, 32
5010; RV64-NEXT:    beqz a0, .LBB63_2
5011; RV64-NEXT:  # %bb.1: # %overflow
5012; RV64-NEXT:    li a0, 0
5013; RV64-NEXT:    ret
5014; RV64-NEXT:  .LBB63_2: # %continue
5015; RV64-NEXT:    li a0, 1
5016; RV64-NEXT:    ret
5017;
5018; RV32ZBA-LABEL: umulo.br.i32:
5019; RV32ZBA:       # %bb.0: # %entry
5020; RV32ZBA-NEXT:    mulhu a0, a0, a1
5021; RV32ZBA-NEXT:    beqz a0, .LBB63_2
5022; RV32ZBA-NEXT:  # %bb.1: # %overflow
5023; RV32ZBA-NEXT:    li a0, 0
5024; RV32ZBA-NEXT:    ret
5025; RV32ZBA-NEXT:  .LBB63_2: # %continue
5026; RV32ZBA-NEXT:    li a0, 1
5027; RV32ZBA-NEXT:    ret
5028;
5029; RV64ZBA-LABEL: umulo.br.i32:
5030; RV64ZBA:       # %bb.0: # %entry
5031; RV64ZBA-NEXT:    zext.w a1, a1
5032; RV64ZBA-NEXT:    zext.w a0, a0
5033; RV64ZBA-NEXT:    mul a0, a0, a1
5034; RV64ZBA-NEXT:    srli a0, a0, 32
5035; RV64ZBA-NEXT:    beqz a0, .LBB63_2
5036; RV64ZBA-NEXT:  # %bb.1: # %overflow
5037; RV64ZBA-NEXT:    li a0, 0
5038; RV64ZBA-NEXT:    ret
5039; RV64ZBA-NEXT:  .LBB63_2: # %continue
5040; RV64ZBA-NEXT:    li a0, 1
5041; RV64ZBA-NEXT:    ret
5042;
5043; RV32ZICOND-LABEL: umulo.br.i32:
5044; RV32ZICOND:       # %bb.0: # %entry
5045; RV32ZICOND-NEXT:    mulhu a0, a0, a1
5046; RV32ZICOND-NEXT:    beqz a0, .LBB63_2
5047; RV32ZICOND-NEXT:  # %bb.1: # %overflow
5048; RV32ZICOND-NEXT:    li a0, 0
5049; RV32ZICOND-NEXT:    ret
5050; RV32ZICOND-NEXT:  .LBB63_2: # %continue
5051; RV32ZICOND-NEXT:    li a0, 1
5052; RV32ZICOND-NEXT:    ret
5053;
5054; RV64ZICOND-LABEL: umulo.br.i32:
5055; RV64ZICOND:       # %bb.0: # %entry
5056; RV64ZICOND-NEXT:    slli a1, a1, 32
5057; RV64ZICOND-NEXT:    slli a0, a0, 32
5058; RV64ZICOND-NEXT:    mulhu a0, a0, a1
5059; RV64ZICOND-NEXT:    srli a0, a0, 32
5060; RV64ZICOND-NEXT:    beqz a0, .LBB63_2
5061; RV64ZICOND-NEXT:  # %bb.1: # %overflow
5062; RV64ZICOND-NEXT:    li a0, 0
5063; RV64ZICOND-NEXT:    ret
5064; RV64ZICOND-NEXT:  .LBB63_2: # %continue
5065; RV64ZICOND-NEXT:    li a0, 1
5066; RV64ZICOND-NEXT:    ret
5067entry:
5068  %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
5069  %val = extractvalue {i32, i1} %t, 0
5070  %obit = extractvalue {i32, i1} %t, 1
5071  br i1 %obit, label %overflow, label %continue
5072
5073overflow:
5074  ret i1 false
5075
5076continue:
5077  ret i1 true
5078}
5079
5080define zeroext i1 @umulo.br.i64(i64 %v1, i64 %v2) {
5081; RV32-LABEL: umulo.br.i64:
5082; RV32:       # %bb.0: # %entry
5083; RV32-NEXT:    mul a4, a3, a0
5084; RV32-NEXT:    mul a5, a1, a2
5085; RV32-NEXT:    mulhu a6, a0, a2
5086; RV32-NEXT:    mulhu a0, a3, a0
5087; RV32-NEXT:    snez a3, a3
5088; RV32-NEXT:    mulhu a2, a1, a2
5089; RV32-NEXT:    snez a1, a1
5090; RV32-NEXT:    add a4, a5, a4
5091; RV32-NEXT:    and a1, a1, a3
5092; RV32-NEXT:    snez a2, a2
5093; RV32-NEXT:    snez a0, a0
5094; RV32-NEXT:    add a4, a6, a4
5095; RV32-NEXT:    or a1, a1, a2
5096; RV32-NEXT:    sltu a2, a4, a6
5097; RV32-NEXT:    or a0, a1, a0
5098; RV32-NEXT:    or a0, a0, a2
5099; RV32-NEXT:    beqz a0, .LBB64_2
5100; RV32-NEXT:  # %bb.1: # %overflow
5101; RV32-NEXT:    li a0, 0
5102; RV32-NEXT:    ret
5103; RV32-NEXT:  .LBB64_2: # %continue
5104; RV32-NEXT:    li a0, 1
5105; RV32-NEXT:    ret
5106;
5107; RV64-LABEL: umulo.br.i64:
5108; RV64:       # %bb.0: # %entry
5109; RV64-NEXT:    mulhu a0, a0, a1
5110; RV64-NEXT:    beqz a0, .LBB64_2
5111; RV64-NEXT:  # %bb.1: # %overflow
5112; RV64-NEXT:    li a0, 0
5113; RV64-NEXT:    ret
5114; RV64-NEXT:  .LBB64_2: # %continue
5115; RV64-NEXT:    li a0, 1
5116; RV64-NEXT:    ret
5117;
5118; RV32ZBA-LABEL: umulo.br.i64:
5119; RV32ZBA:       # %bb.0: # %entry
5120; RV32ZBA-NEXT:    mul a4, a3, a0
5121; RV32ZBA-NEXT:    mul a5, a1, a2
5122; RV32ZBA-NEXT:    mulhu a6, a0, a2
5123; RV32ZBA-NEXT:    mulhu a0, a3, a0
5124; RV32ZBA-NEXT:    snez a3, a3
5125; RV32ZBA-NEXT:    mulhu a2, a1, a2
5126; RV32ZBA-NEXT:    snez a1, a1
5127; RV32ZBA-NEXT:    add a4, a5, a4
5128; RV32ZBA-NEXT:    and a1, a1, a3
5129; RV32ZBA-NEXT:    snez a2, a2
5130; RV32ZBA-NEXT:    snez a0, a0
5131; RV32ZBA-NEXT:    add a4, a6, a4
5132; RV32ZBA-NEXT:    or a1, a1, a2
5133; RV32ZBA-NEXT:    sltu a2, a4, a6
5134; RV32ZBA-NEXT:    or a0, a1, a0
5135; RV32ZBA-NEXT:    or a0, a0, a2
5136; RV32ZBA-NEXT:    beqz a0, .LBB64_2
5137; RV32ZBA-NEXT:  # %bb.1: # %overflow
5138; RV32ZBA-NEXT:    li a0, 0
5139; RV32ZBA-NEXT:    ret
5140; RV32ZBA-NEXT:  .LBB64_2: # %continue
5141; RV32ZBA-NEXT:    li a0, 1
5142; RV32ZBA-NEXT:    ret
5143;
5144; RV64ZBA-LABEL: umulo.br.i64:
5145; RV64ZBA:       # %bb.0: # %entry
5146; RV64ZBA-NEXT:    mulhu a0, a0, a1
5147; RV64ZBA-NEXT:    beqz a0, .LBB64_2
5148; RV64ZBA-NEXT:  # %bb.1: # %overflow
5149; RV64ZBA-NEXT:    li a0, 0
5150; RV64ZBA-NEXT:    ret
5151; RV64ZBA-NEXT:  .LBB64_2: # %continue
5152; RV64ZBA-NEXT:    li a0, 1
5153; RV64ZBA-NEXT:    ret
5154;
5155; RV32ZICOND-LABEL: umulo.br.i64:
5156; RV32ZICOND:       # %bb.0: # %entry
5157; RV32ZICOND-NEXT:    mul a4, a3, a0
5158; RV32ZICOND-NEXT:    mul a5, a1, a2
5159; RV32ZICOND-NEXT:    mulhu a6, a0, a2
5160; RV32ZICOND-NEXT:    mulhu a0, a3, a0
5161; RV32ZICOND-NEXT:    snez a3, a3
5162; RV32ZICOND-NEXT:    mulhu a2, a1, a2
5163; RV32ZICOND-NEXT:    snez a1, a1
5164; RV32ZICOND-NEXT:    add a4, a5, a4
5165; RV32ZICOND-NEXT:    and a1, a1, a3
5166; RV32ZICOND-NEXT:    snez a2, a2
5167; RV32ZICOND-NEXT:    snez a0, a0
5168; RV32ZICOND-NEXT:    add a4, a6, a4
5169; RV32ZICOND-NEXT:    or a1, a1, a2
5170; RV32ZICOND-NEXT:    sltu a2, a4, a6
5171; RV32ZICOND-NEXT:    or a0, a1, a0
5172; RV32ZICOND-NEXT:    or a0, a0, a2
5173; RV32ZICOND-NEXT:    beqz a0, .LBB64_2
5174; RV32ZICOND-NEXT:  # %bb.1: # %overflow
5175; RV32ZICOND-NEXT:    li a0, 0
5176; RV32ZICOND-NEXT:    ret
5177; RV32ZICOND-NEXT:  .LBB64_2: # %continue
5178; RV32ZICOND-NEXT:    li a0, 1
5179; RV32ZICOND-NEXT:    ret
5180;
5181; RV64ZICOND-LABEL: umulo.br.i64:
5182; RV64ZICOND:       # %bb.0: # %entry
5183; RV64ZICOND-NEXT:    mulhu a0, a0, a1
5184; RV64ZICOND-NEXT:    beqz a0, .LBB64_2
5185; RV64ZICOND-NEXT:  # %bb.1: # %overflow
5186; RV64ZICOND-NEXT:    li a0, 0
5187; RV64ZICOND-NEXT:    ret
5188; RV64ZICOND-NEXT:  .LBB64_2: # %continue
5189; RV64ZICOND-NEXT:    li a0, 1
5190; RV64ZICOND-NEXT:    ret
5191entry:
5192  %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
5193  %val = extractvalue {i64, i1} %t, 0
5194  %obit = extractvalue {i64, i1} %t, 1
5195  br i1 %obit, label %overflow, label %continue
5196
5197overflow:
5198  ret i1 false
5199
5200continue:
5201  ret i1 true
5202}
5203
5204define zeroext i1 @umulo2.br.i64(i64 %v1) {
5205; RV32-LABEL: umulo2.br.i64:
5206; RV32:       # %bb.0: # %entry
5207; RV32-NEXT:    add a2, a0, a0
5208; RV32-NEXT:    sltu a0, a2, a0
5209; RV32-NEXT:    add a2, a1, a1
5210; RV32-NEXT:    add a2, a2, a0
5211; RV32-NEXT:    beq a2, a1, .LBB65_2
5212; RV32-NEXT:  # %bb.1: # %entry
5213; RV32-NEXT:    sltu a0, a2, a1
5214; RV32-NEXT:  .LBB65_2: # %entry
5215; RV32-NEXT:    beqz a0, .LBB65_4
5216; RV32-NEXT:  # %bb.3: # %overflow
5217; RV32-NEXT:    li a0, 0
5218; RV32-NEXT:    ret
5219; RV32-NEXT:  .LBB65_4: # %continue
5220; RV32-NEXT:    li a0, 1
5221; RV32-NEXT:    ret
5222;
5223; RV64-LABEL: umulo2.br.i64:
5224; RV64:       # %bb.0: # %entry
5225; RV64-NEXT:    add a1, a0, a0
5226; RV64-NEXT:    bgeu a1, a0, .LBB65_2
5227; RV64-NEXT:  # %bb.1: # %overflow
5228; RV64-NEXT:    li a0, 0
5229; RV64-NEXT:    ret
5230; RV64-NEXT:  .LBB65_2: # %continue
5231; RV64-NEXT:    li a0, 1
5232; RV64-NEXT:    ret
5233;
5234; RV32ZBA-LABEL: umulo2.br.i64:
5235; RV32ZBA:       # %bb.0: # %entry
5236; RV32ZBA-NEXT:    add a2, a0, a0
5237; RV32ZBA-NEXT:    sltu a0, a2, a0
5238; RV32ZBA-NEXT:    add a2, a1, a1
5239; RV32ZBA-NEXT:    add a2, a2, a0
5240; RV32ZBA-NEXT:    beq a2, a1, .LBB65_2
5241; RV32ZBA-NEXT:  # %bb.1: # %entry
5242; RV32ZBA-NEXT:    sltu a0, a2, a1
5243; RV32ZBA-NEXT:  .LBB65_2: # %entry
5244; RV32ZBA-NEXT:    beqz a0, .LBB65_4
5245; RV32ZBA-NEXT:  # %bb.3: # %overflow
5246; RV32ZBA-NEXT:    li a0, 0
5247; RV32ZBA-NEXT:    ret
5248; RV32ZBA-NEXT:  .LBB65_4: # %continue
5249; RV32ZBA-NEXT:    li a0, 1
5250; RV32ZBA-NEXT:    ret
5251;
5252; RV64ZBA-LABEL: umulo2.br.i64:
5253; RV64ZBA:       # %bb.0: # %entry
5254; RV64ZBA-NEXT:    add a1, a0, a0
5255; RV64ZBA-NEXT:    bgeu a1, a0, .LBB65_2
5256; RV64ZBA-NEXT:  # %bb.1: # %overflow
5257; RV64ZBA-NEXT:    li a0, 0
5258; RV64ZBA-NEXT:    ret
5259; RV64ZBA-NEXT:  .LBB65_2: # %continue
5260; RV64ZBA-NEXT:    li a0, 1
5261; RV64ZBA-NEXT:    ret
5262;
5263; RV32ZICOND-LABEL: umulo2.br.i64:
5264; RV32ZICOND:       # %bb.0: # %entry
5265; RV32ZICOND-NEXT:    add a2, a0, a0
5266; RV32ZICOND-NEXT:    add a3, a1, a1
5267; RV32ZICOND-NEXT:    sltu a0, a2, a0
5268; RV32ZICOND-NEXT:    add a3, a3, a0
5269; RV32ZICOND-NEXT:    xor a2, a3, a1
5270; RV32ZICOND-NEXT:    sltu a1, a3, a1
5271; RV32ZICOND-NEXT:    czero.eqz a1, a1, a2
5272; RV32ZICOND-NEXT:    czero.nez a0, a0, a2
5273; RV32ZICOND-NEXT:    or a0, a0, a1
5274; RV32ZICOND-NEXT:    beqz a0, .LBB65_2
5275; RV32ZICOND-NEXT:  # %bb.1: # %overflow
5276; RV32ZICOND-NEXT:    li a0, 0
5277; RV32ZICOND-NEXT:    ret
5278; RV32ZICOND-NEXT:  .LBB65_2: # %continue
5279; RV32ZICOND-NEXT:    li a0, 1
5280; RV32ZICOND-NEXT:    ret
5281;
5282; RV64ZICOND-LABEL: umulo2.br.i64:
5283; RV64ZICOND:       # %bb.0: # %entry
5284; RV64ZICOND-NEXT:    add a1, a0, a0
5285; RV64ZICOND-NEXT:    bgeu a1, a0, .LBB65_2
5286; RV64ZICOND-NEXT:  # %bb.1: # %overflow
5287; RV64ZICOND-NEXT:    li a0, 0
5288; RV64ZICOND-NEXT:    ret
5289; RV64ZICOND-NEXT:  .LBB65_2: # %continue
5290; RV64ZICOND-NEXT:    li a0, 1
5291; RV64ZICOND-NEXT:    ret
5292entry:
5293  %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 2)
5294  %val = extractvalue {i64, i1} %t, 0
5295  %obit = extractvalue {i64, i1} %t, 1
5296  br i1 %obit, label %overflow, label %continue
5297
5298overflow:
5299  ret i1 false
5300
5301continue:
5302  ret i1 true
5303}
5304
5305define zeroext i1 @uaddo.i64.constant(i64 %v1, ptr %res) {
5306; RV32-LABEL: uaddo.i64.constant:
5307; RV32:       # %bb.0: # %entry
5308; RV32-NEXT:    addi a3, a0, 2
5309; RV32-NEXT:    sltu a0, a3, a0
5310; RV32-NEXT:    add a4, a1, a0
5311; RV32-NEXT:    sltu a1, a4, a1
5312; RV32-NEXT:    and a0, a0, a1
5313; RV32-NEXT:    sw a3, 0(a2)
5314; RV32-NEXT:    sw a4, 4(a2)
5315; RV32-NEXT:    ret
5316;
5317; RV64-LABEL: uaddo.i64.constant:
5318; RV64:       # %bb.0: # %entry
5319; RV64-NEXT:    addi a2, a0, 2
5320; RV64-NEXT:    sltu a0, a2, a0
5321; RV64-NEXT:    sd a2, 0(a1)
5322; RV64-NEXT:    ret
5323;
5324; RV32ZBA-LABEL: uaddo.i64.constant:
5325; RV32ZBA:       # %bb.0: # %entry
5326; RV32ZBA-NEXT:    addi a3, a0, 2
5327; RV32ZBA-NEXT:    sltu a0, a3, a0
5328; RV32ZBA-NEXT:    add a4, a1, a0
5329; RV32ZBA-NEXT:    sltu a1, a4, a1
5330; RV32ZBA-NEXT:    and a0, a0, a1
5331; RV32ZBA-NEXT:    sw a3, 0(a2)
5332; RV32ZBA-NEXT:    sw a4, 4(a2)
5333; RV32ZBA-NEXT:    ret
5334;
5335; RV64ZBA-LABEL: uaddo.i64.constant:
5336; RV64ZBA:       # %bb.0: # %entry
5337; RV64ZBA-NEXT:    addi a2, a0, 2
5338; RV64ZBA-NEXT:    sltu a0, a2, a0
5339; RV64ZBA-NEXT:    sd a2, 0(a1)
5340; RV64ZBA-NEXT:    ret
5341;
5342; RV32ZICOND-LABEL: uaddo.i64.constant:
5343; RV32ZICOND:       # %bb.0: # %entry
5344; RV32ZICOND-NEXT:    addi a3, a0, 2
5345; RV32ZICOND-NEXT:    sltu a0, a3, a0
5346; RV32ZICOND-NEXT:    add a4, a1, a0
5347; RV32ZICOND-NEXT:    sltu a1, a4, a1
5348; RV32ZICOND-NEXT:    and a0, a0, a1
5349; RV32ZICOND-NEXT:    sw a3, 0(a2)
5350; RV32ZICOND-NEXT:    sw a4, 4(a2)
5351; RV32ZICOND-NEXT:    ret
5352;
5353; RV64ZICOND-LABEL: uaddo.i64.constant:
5354; RV64ZICOND:       # %bb.0: # %entry
5355; RV64ZICOND-NEXT:    addi a2, a0, 2
5356; RV64ZICOND-NEXT:    sltu a0, a2, a0
5357; RV64ZICOND-NEXT:    sd a2, 0(a1)
5358; RV64ZICOND-NEXT:    ret
5359entry:
5360  %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 2)
5361  %val = extractvalue {i64, i1} %t, 0
5362  %obit = extractvalue {i64, i1} %t, 1
5363  store i64 %val, ptr %res
5364  ret i1 %obit
5365}
5366
5367define zeroext i1 @uaddo.i64.constant_2048(i64 %v1, ptr %res) {
5368; RV32-LABEL: uaddo.i64.constant_2048:
5369; RV32:       # %bb.0: # %entry
5370; RV32-NEXT:    addi a3, a0, 2047
5371; RV32-NEXT:    addi a3, a3, 1
5372; RV32-NEXT:    sltu a0, a3, a0
5373; RV32-NEXT:    add a4, a1, a0
5374; RV32-NEXT:    sltu a1, a4, a1
5375; RV32-NEXT:    and a0, a0, a1
5376; RV32-NEXT:    sw a3, 0(a2)
5377; RV32-NEXT:    sw a4, 4(a2)
5378; RV32-NEXT:    ret
5379;
5380; RV64-LABEL: uaddo.i64.constant_2048:
5381; RV64:       # %bb.0: # %entry
5382; RV64-NEXT:    addi a2, a0, 2047
5383; RV64-NEXT:    addi a2, a2, 1
5384; RV64-NEXT:    sltu a0, a2, a0
5385; RV64-NEXT:    sd a2, 0(a1)
5386; RV64-NEXT:    ret
5387;
5388; RV32ZBA-LABEL: uaddo.i64.constant_2048:
5389; RV32ZBA:       # %bb.0: # %entry
5390; RV32ZBA-NEXT:    addi a3, a0, 2047
5391; RV32ZBA-NEXT:    addi a3, a3, 1
5392; RV32ZBA-NEXT:    sltu a0, a3, a0
5393; RV32ZBA-NEXT:    add a4, a1, a0
5394; RV32ZBA-NEXT:    sltu a1, a4, a1
5395; RV32ZBA-NEXT:    and a0, a0, a1
5396; RV32ZBA-NEXT:    sw a3, 0(a2)
5397; RV32ZBA-NEXT:    sw a4, 4(a2)
5398; RV32ZBA-NEXT:    ret
5399;
5400; RV64ZBA-LABEL: uaddo.i64.constant_2048:
5401; RV64ZBA:       # %bb.0: # %entry
5402; RV64ZBA-NEXT:    addi a2, a0, 2047
5403; RV64ZBA-NEXT:    addi a2, a2, 1
5404; RV64ZBA-NEXT:    sltu a0, a2, a0
5405; RV64ZBA-NEXT:    sd a2, 0(a1)
5406; RV64ZBA-NEXT:    ret
5407;
5408; RV32ZICOND-LABEL: uaddo.i64.constant_2048:
5409; RV32ZICOND:       # %bb.0: # %entry
5410; RV32ZICOND-NEXT:    addi a3, a0, 2047
5411; RV32ZICOND-NEXT:    addi a3, a3, 1
5412; RV32ZICOND-NEXT:    sltu a0, a3, a0
5413; RV32ZICOND-NEXT:    add a4, a1, a0
5414; RV32ZICOND-NEXT:    sltu a1, a4, a1
5415; RV32ZICOND-NEXT:    and a0, a0, a1
5416; RV32ZICOND-NEXT:    sw a3, 0(a2)
5417; RV32ZICOND-NEXT:    sw a4, 4(a2)
5418; RV32ZICOND-NEXT:    ret
5419;
5420; RV64ZICOND-LABEL: uaddo.i64.constant_2048:
5421; RV64ZICOND:       # %bb.0: # %entry
5422; RV64ZICOND-NEXT:    addi a2, a0, 2047
5423; RV64ZICOND-NEXT:    addi a2, a2, 1
5424; RV64ZICOND-NEXT:    sltu a0, a2, a0
5425; RV64ZICOND-NEXT:    sd a2, 0(a1)
5426; RV64ZICOND-NEXT:    ret
5427entry:
5428  %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 2048)
5429  %val = extractvalue {i64, i1} %t, 0
5430  %obit = extractvalue {i64, i1} %t, 1
5431  store i64 %val, ptr %res
5432  ret i1 %obit
5433}
5434
5435define zeroext i1 @uaddo.i64.constant_2049(i64 %v1, ptr %res) {
5436; RV32-LABEL: uaddo.i64.constant_2049:
5437; RV32:       # %bb.0: # %entry
5438; RV32-NEXT:    addi a3, a0, 2047
5439; RV32-NEXT:    addi a3, a3, 2
5440; RV32-NEXT:    sltu a0, a3, a0
5441; RV32-NEXT:    add a4, a1, a0
5442; RV32-NEXT:    sltu a1, a4, a1
5443; RV32-NEXT:    and a0, a0, a1
5444; RV32-NEXT:    sw a3, 0(a2)
5445; RV32-NEXT:    sw a4, 4(a2)
5446; RV32-NEXT:    ret
5447;
5448; RV64-LABEL: uaddo.i64.constant_2049:
5449; RV64:       # %bb.0: # %entry
5450; RV64-NEXT:    addi a2, a0, 2047
5451; RV64-NEXT:    addi a2, a2, 2
5452; RV64-NEXT:    sltu a0, a2, a0
5453; RV64-NEXT:    sd a2, 0(a1)
5454; RV64-NEXT:    ret
5455;
5456; RV32ZBA-LABEL: uaddo.i64.constant_2049:
5457; RV32ZBA:       # %bb.0: # %entry
5458; RV32ZBA-NEXT:    addi a3, a0, 2047
5459; RV32ZBA-NEXT:    addi a3, a3, 2
5460; RV32ZBA-NEXT:    sltu a0, a3, a0
5461; RV32ZBA-NEXT:    add a4, a1, a0
5462; RV32ZBA-NEXT:    sltu a1, a4, a1
5463; RV32ZBA-NEXT:    and a0, a0, a1
5464; RV32ZBA-NEXT:    sw a3, 0(a2)
5465; RV32ZBA-NEXT:    sw a4, 4(a2)
5466; RV32ZBA-NEXT:    ret
5467;
5468; RV64ZBA-LABEL: uaddo.i64.constant_2049:
5469; RV64ZBA:       # %bb.0: # %entry
5470; RV64ZBA-NEXT:    addi a2, a0, 2047
5471; RV64ZBA-NEXT:    addi a2, a2, 2
5472; RV64ZBA-NEXT:    sltu a0, a2, a0
5473; RV64ZBA-NEXT:    sd a2, 0(a1)
5474; RV64ZBA-NEXT:    ret
5475;
5476; RV32ZICOND-LABEL: uaddo.i64.constant_2049:
5477; RV32ZICOND:       # %bb.0: # %entry
5478; RV32ZICOND-NEXT:    addi a3, a0, 2047
5479; RV32ZICOND-NEXT:    addi a3, a3, 2
5480; RV32ZICOND-NEXT:    sltu a0, a3, a0
5481; RV32ZICOND-NEXT:    add a4, a1, a0
5482; RV32ZICOND-NEXT:    sltu a1, a4, a1
5483; RV32ZICOND-NEXT:    and a0, a0, a1
5484; RV32ZICOND-NEXT:    sw a3, 0(a2)
5485; RV32ZICOND-NEXT:    sw a4, 4(a2)
5486; RV32ZICOND-NEXT:    ret
5487;
5488; RV64ZICOND-LABEL: uaddo.i64.constant_2049:
5489; RV64ZICOND:       # %bb.0: # %entry
5490; RV64ZICOND-NEXT:    addi a2, a0, 2047
5491; RV64ZICOND-NEXT:    addi a2, a2, 2
5492; RV64ZICOND-NEXT:    sltu a0, a2, a0
5493; RV64ZICOND-NEXT:    sd a2, 0(a1)
5494; RV64ZICOND-NEXT:    ret
5495entry:
5496  %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 2049)
5497  %val = extractvalue {i64, i1} %t, 0
5498  %obit = extractvalue {i64, i1} %t, 1
5499  store i64 %val, ptr %res
5500  ret i1 %obit
5501}
5502
5503define i64 @uaddo.i64.constant_setcc_on_overflow_flag(ptr %p) {
5504; RV32-LABEL: uaddo.i64.constant_setcc_on_overflow_flag:
5505; RV32:       # %bb.0: # %entry
5506; RV32-NEXT:    lw a1, 0(a0)
5507; RV32-NEXT:    lw a2, 4(a0)
5508; RV32-NEXT:    addi a0, a1, 2
5509; RV32-NEXT:    sltu a3, a0, a1
5510; RV32-NEXT:    add a1, a2, a3
5511; RV32-NEXT:    sltu a2, a1, a2
5512; RV32-NEXT:    and a2, a3, a2
5513; RV32-NEXT:    bnez a2, .LBB69_2
5514; RV32-NEXT:  # %bb.1: # %IfOverflow
5515; RV32-NEXT:    li a0, 0
5516; RV32-NEXT:    li a1, 0
5517; RV32-NEXT:  .LBB69_2: # %IfNoOverflow
5518; RV32-NEXT:    ret
5519;
5520; RV64-LABEL: uaddo.i64.constant_setcc_on_overflow_flag:
5521; RV64:       # %bb.0: # %entry
5522; RV64-NEXT:    ld a1, 0(a0)
5523; RV64-NEXT:    addi a0, a1, 2
5524; RV64-NEXT:    bltu a0, a1, .LBB69_2
5525; RV64-NEXT:  # %bb.1: # %IfOverflow
5526; RV64-NEXT:    li a0, 0
5527; RV64-NEXT:  .LBB69_2: # %IfNoOverflow
5528; RV64-NEXT:    ret
5529;
5530; RV32ZBA-LABEL: uaddo.i64.constant_setcc_on_overflow_flag:
5531; RV32ZBA:       # %bb.0: # %entry
5532; RV32ZBA-NEXT:    lw a1, 0(a0)
5533; RV32ZBA-NEXT:    lw a2, 4(a0)
5534; RV32ZBA-NEXT:    addi a0, a1, 2
5535; RV32ZBA-NEXT:    sltu a3, a0, a1
5536; RV32ZBA-NEXT:    add a1, a2, a3
5537; RV32ZBA-NEXT:    sltu a2, a1, a2
5538; RV32ZBA-NEXT:    and a2, a3, a2
5539; RV32ZBA-NEXT:    bnez a2, .LBB69_2
5540; RV32ZBA-NEXT:  # %bb.1: # %IfOverflow
5541; RV32ZBA-NEXT:    li a0, 0
5542; RV32ZBA-NEXT:    li a1, 0
5543; RV32ZBA-NEXT:  .LBB69_2: # %IfNoOverflow
5544; RV32ZBA-NEXT:    ret
5545;
5546; RV64ZBA-LABEL: uaddo.i64.constant_setcc_on_overflow_flag:
5547; RV64ZBA:       # %bb.0: # %entry
5548; RV64ZBA-NEXT:    ld a1, 0(a0)
5549; RV64ZBA-NEXT:    addi a0, a1, 2
5550; RV64ZBA-NEXT:    bltu a0, a1, .LBB69_2
5551; RV64ZBA-NEXT:  # %bb.1: # %IfOverflow
5552; RV64ZBA-NEXT:    li a0, 0
5553; RV64ZBA-NEXT:  .LBB69_2: # %IfNoOverflow
5554; RV64ZBA-NEXT:    ret
5555;
5556; RV32ZICOND-LABEL: uaddo.i64.constant_setcc_on_overflow_flag:
5557; RV32ZICOND:       # %bb.0: # %entry
5558; RV32ZICOND-NEXT:    lw a1, 0(a0)
5559; RV32ZICOND-NEXT:    lw a2, 4(a0)
5560; RV32ZICOND-NEXT:    addi a0, a1, 2
5561; RV32ZICOND-NEXT:    sltu a3, a0, a1
5562; RV32ZICOND-NEXT:    add a1, a2, a3
5563; RV32ZICOND-NEXT:    sltu a2, a1, a2
5564; RV32ZICOND-NEXT:    and a2, a3, a2
5565; RV32ZICOND-NEXT:    bnez a2, .LBB69_2
5566; RV32ZICOND-NEXT:  # %bb.1: # %IfOverflow
5567; RV32ZICOND-NEXT:    li a0, 0
5568; RV32ZICOND-NEXT:    li a1, 0
5569; RV32ZICOND-NEXT:  .LBB69_2: # %IfNoOverflow
5570; RV32ZICOND-NEXT:    ret
5571;
5572; RV64ZICOND-LABEL: uaddo.i64.constant_setcc_on_overflow_flag:
5573; RV64ZICOND:       # %bb.0: # %entry
5574; RV64ZICOND-NEXT:    ld a1, 0(a0)
5575; RV64ZICOND-NEXT:    addi a0, a1, 2
5576; RV64ZICOND-NEXT:    bltu a0, a1, .LBB69_2
5577; RV64ZICOND-NEXT:  # %bb.1: # %IfOverflow
5578; RV64ZICOND-NEXT:    li a0, 0
5579; RV64ZICOND-NEXT:  .LBB69_2: # %IfNoOverflow
5580; RV64ZICOND-NEXT:    ret
5581entry:
5582  %v1 = load i64, ptr %p
5583  %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 2)
5584  %val = extractvalue {i64, i1} %t, 0
5585  %obit = extractvalue {i64, i1} %t, 1
5586  br i1 %obit, label %IfNoOverflow, label %IfOverflow
5587IfOverflow:
5588  ret i64 0
5589IfNoOverflow:
5590  ret i64 %val
5591}
5592
5593declare {i32, i1} @llvm.sadd.with.overflow.i32(i32, i32) nounwind readnone
5594declare {i64, i1} @llvm.sadd.with.overflow.i64(i64, i64) nounwind readnone
5595declare {i32, i1} @llvm.uadd.with.overflow.i32(i32, i32) nounwind readnone
5596declare {i64, i1} @llvm.uadd.with.overflow.i64(i64, i64) nounwind readnone
5597declare {i32, i1} @llvm.ssub.with.overflow.i32(i32, i32) nounwind readnone
5598declare {i64, i1} @llvm.ssub.with.overflow.i64(i64, i64) nounwind readnone
5599declare {i32, i1} @llvm.usub.with.overflow.i32(i32, i32) nounwind readnone
5600declare {i64, i1} @llvm.usub.with.overflow.i64(i64, i64) nounwind readnone
5601declare {i32, i1} @llvm.smul.with.overflow.i32(i32, i32) nounwind readnone
5602declare {i64, i1} @llvm.smul.with.overflow.i64(i64, i64) nounwind readnone
5603declare {i32, i1} @llvm.umul.with.overflow.i32(i32, i32) nounwind readnone
5604declare {i64, i1} @llvm.umul.with.overflow.i64(i64, i64) nounwind readnone
5605