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 5 declare {i32, i1} @llvm.sadd.with.overflow.i32(i32 %a, i32 %b) 6 declare {i32, i1} @llvm.ssub.with.overflow.i32(i32 %a, i32 %b) 7 declare {i32, i1} @llvm.uadd.with.overflow.i32(i32 %a, i32 %b) 8 declare {i32, i1} @llvm.usub.with.overflow.i32(i32 %a, i32 %b) 9 10 define 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 25 entry: 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 33 define 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 48 entry: 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 56 define 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 63 entry: 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 71 define 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 78 entry: 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