1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \
3; RUN:   | FileCheck -check-prefix=RV32I %s
4
5declare {i32, i1} @llvm.sadd.with.overflow.i32(i32 %a, i32 %b)
6declare {i32, i1} @llvm.ssub.with.overflow.i32(i32 %a, i32 %b)
7declare {i32, i1} @llvm.uadd.with.overflow.i32(i32 %a, i32 %b)
8declare {i32, i1} @llvm.usub.with.overflow.i32(i32 %a, i32 %b)
9
10define i1 @sadd(i32 %a, i32 %b, i32* %c) nounwind {
11; RV32I-LABEL: sadd:
12; RV32I:       # %bb.0: # %entry
13; RV32I-NEXT:    add a3, a0, a1
14; RV32I-NEXT:    sw a3, 0(a2)
15; RV32I-NEXT:    addi a2, zero, -1
16; RV32I-NEXT:    slt a1, a2, a1
17; RV32I-NEXT:    slt a0, a2, a0
18; RV32I-NEXT:    slt a2, a2, a3
19; RV32I-NEXT:    xor a2, a0, a2
20; RV32I-NEXT:    xor a0, a0, a1
21; RV32I-NEXT:    seqz a0, a0
22; RV32I-NEXT:    snez a1, a2
23; RV32I-NEXT:    and a0, a0, a1
24; RV32I-NEXT:    ret
25entry:
26  %x = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %a, i32 %b)
27  %calc = extractvalue {i32, i1} %x, 0
28  %ovf = extractvalue {i32, i1} %x, 1
29  store i32 %calc, i32* %c
30  ret i1 %ovf
31}
32
33define i1 @ssub(i32 %a, i32 %b, i32* %c) nounwind {
34; RV32I-LABEL: ssub:
35; RV32I:       # %bb.0: # %entry
36; RV32I-NEXT:    sub a3, a0, a1
37; RV32I-NEXT:    sw a3, 0(a2)
38; RV32I-NEXT:    addi a2, zero, -1
39; RV32I-NEXT:    slt a1, a2, a1
40; RV32I-NEXT:    slt a0, a2, a0
41; RV32I-NEXT:    slt a2, a2, a3
42; RV32I-NEXT:    xor a2, a0, a2
43; RV32I-NEXT:    xor a0, a0, a1
44; RV32I-NEXT:    snez a0, a0
45; RV32I-NEXT:    snez a1, a2
46; RV32I-NEXT:    and a0, a0, a1
47; RV32I-NEXT:    ret
48entry:
49  %x = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %a, i32 %b)
50  %calc = extractvalue {i32, i1} %x, 0
51  %ovf = extractvalue {i32, i1} %x, 1
52  store i32 %calc, i32* %c
53  ret i1 %ovf
54}
55
56define i1 @uadd(i32 %a, i32 %b, i32* %c) nounwind {
57; RV32I-LABEL: uadd:
58; RV32I:       # %bb.0: # %entry
59; RV32I-NEXT:    add a1, a0, a1
60; RV32I-NEXT:    sw a1, 0(a2)
61; RV32I-NEXT:    sltu a0, a1, a0
62; RV32I-NEXT:    ret
63entry:
64  %x = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %a, i32 %b)
65  %calc = extractvalue {i32, i1} %x, 0
66  %ovf = extractvalue {i32, i1} %x, 1
67  store i32 %calc, i32* %c
68  ret i1 %ovf
69}
70
71define i1 @usub(i32 %a, i32 %b, i32* %c) nounwind {
72; RV32I-LABEL: usub:
73; RV32I:       # %bb.0: # %entry
74; RV32I-NEXT:    sub a1, a0, a1
75; RV32I-NEXT:    sw a1, 0(a2)
76; RV32I-NEXT:    sltu a0, a0, a1
77; RV32I-NEXT:    ret
78entry:
79  %x = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %a, i32 %b)
80  %calc = extractvalue {i32, i1} %x, 0
81  %ovf = extractvalue {i32, i1} %x, 1
82  store i32 %calc, i32* %c
83  ret i1 %ovf
84}
85