xref: /llvm-project/llvm/test/CodeGen/RISCV/arith-with-overflow.ll (revision 3d0fbafd0bce43bb9106230a45d1130f7a40e5ec)
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:    addi a3, zero, -1
14; RV32I-NEXT:    slt a4, a3, a1
15; RV32I-NEXT:    slt a5, a3, a0
16; RV32I-NEXT:    xor a4, a5, a4
17; RV32I-NEXT:    seqz a4, a4
18; RV32I-NEXT:    add a1, a0, a1
19; RV32I-NEXT:    slt a0, a3, a1
20; RV32I-NEXT:    xor a0, a5, a0
21; RV32I-NEXT:    snez a0, a0
22; RV32I-NEXT:    and a0, a4, a0
23; RV32I-NEXT:    sw a1, 0(a2)
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:    addi a3, zero, -1
37; RV32I-NEXT:    slt a4, a3, a1
38; RV32I-NEXT:    slt a5, a3, a0
39; RV32I-NEXT:    xor a4, a5, a4
40; RV32I-NEXT:    snez a4, a4
41; RV32I-NEXT:    sub a1, a0, a1
42; RV32I-NEXT:    slt a0, a3, a1
43; RV32I-NEXT:    xor a0, a5, a0
44; RV32I-NEXT:    snez a0, a0
45; RV32I-NEXT:    and a0, a4, a0
46; RV32I-NEXT:    sw a1, 0(a2)
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:    sltu a0, a1, a0
61; RV32I-NEXT:    sw a1, 0(a2)
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:    sltu a0, a0, a1
76; RV32I-NEXT:    sw a1, 0(a2)
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