1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=riscv32 -mattr=+m | FileCheck %s --check-prefix=RV32I 3; RUN: llc < %s -mtriple=riscv64 -mattr=+m | FileCheck %s --check-prefix=RV64I 4 5declare i4 @llvm.usub.sat.i4(i4, i4) 6declare i8 @llvm.usub.sat.i8(i8, i8) 7declare i16 @llvm.usub.sat.i16(i16, i16) 8declare i32 @llvm.usub.sat.i32(i32, i32) 9declare i64 @llvm.usub.sat.i64(i64, i64) 10 11define i32 @func32(i32 %x, i32 %y, i32 %z) nounwind { 12; RV32I-LABEL: func32: 13; RV32I: # %bb.0: 14; RV32I-NEXT: mul a1, a1, a2 15; RV32I-NEXT: sub a1, a0, a1 16; RV32I-NEXT: sltu a2, a0, a1 17; RV32I-NEXT: mv a0, zero 18; RV32I-NEXT: bnez a2, .LBB0_2 19; RV32I-NEXT: # %bb.1: 20; RV32I-NEXT: mv a0, a1 21; RV32I-NEXT: .LBB0_2: 22; RV32I-NEXT: ret 23; 24; RV64I-LABEL: func32: 25; RV64I: # %bb.0: 26; RV64I-NEXT: slli a0, a0, 32 27; RV64I-NEXT: srli a0, a0, 32 28; RV64I-NEXT: mul a1, a1, a2 29; RV64I-NEXT: slli a1, a1, 32 30; RV64I-NEXT: srli a1, a1, 32 31; RV64I-NEXT: sub a1, a0, a1 32; RV64I-NEXT: sltu a2, a0, a1 33; RV64I-NEXT: mv a0, zero 34; RV64I-NEXT: bnez a2, .LBB0_2 35; RV64I-NEXT: # %bb.1: 36; RV64I-NEXT: mv a0, a1 37; RV64I-NEXT: .LBB0_2: 38; RV64I-NEXT: ret 39 %a = mul i32 %y, %z 40 %tmp = call i32 @llvm.usub.sat.i32(i32 %x, i32 %a) 41 ret i32 %tmp 42} 43 44define i64 @func64(i64 %x, i64 %y, i64 %z) nounwind { 45; RV32I-LABEL: func64: 46; RV32I: # %bb.0: 47; RV32I-NEXT: sltu a2, a0, a4 48; RV32I-NEXT: sub a3, a1, a5 49; RV32I-NEXT: sub a2, a3, a2 50; RV32I-NEXT: sub a3, a0, a4 51; RV32I-NEXT: beq a2, a1, .LBB1_2 52; RV32I-NEXT: # %bb.1: 53; RV32I-NEXT: sltu a4, a1, a2 54; RV32I-NEXT: j .LBB1_3 55; RV32I-NEXT: .LBB1_2: 56; RV32I-NEXT: sltu a4, a0, a3 57; RV32I-NEXT: .LBB1_3: 58; RV32I-NEXT: mv a0, zero 59; RV32I-NEXT: mv a1, zero 60; RV32I-NEXT: bnez a4, .LBB1_5 61; RV32I-NEXT: # %bb.4: 62; RV32I-NEXT: mv a0, a3 63; RV32I-NEXT: mv a1, a2 64; RV32I-NEXT: .LBB1_5: 65; RV32I-NEXT: ret 66; 67; RV64I-LABEL: func64: 68; RV64I: # %bb.0: 69; RV64I-NEXT: sub a1, a0, a2 70; RV64I-NEXT: sltu a2, a0, a1 71; RV64I-NEXT: mv a0, zero 72; RV64I-NEXT: bnez a2, .LBB1_2 73; RV64I-NEXT: # %bb.1: 74; RV64I-NEXT: mv a0, a1 75; RV64I-NEXT: .LBB1_2: 76; RV64I-NEXT: ret 77 %a = mul i64 %y, %z 78 %tmp = call i64 @llvm.usub.sat.i64(i64 %x, i64 %z) 79 ret i64 %tmp 80} 81 82define i16 @func16(i16 %x, i16 %y, i16 %z) nounwind { 83; RV32I-LABEL: func16: 84; RV32I: # %bb.0: 85; RV32I-NEXT: lui a3, 16 86; RV32I-NEXT: addi a3, a3, -1 87; RV32I-NEXT: and a0, a0, a3 88; RV32I-NEXT: mul a1, a1, a2 89; RV32I-NEXT: and a1, a1, a3 90; RV32I-NEXT: sub a1, a0, a1 91; RV32I-NEXT: sltu a2, a0, a1 92; RV32I-NEXT: mv a0, zero 93; RV32I-NEXT: bnez a2, .LBB2_2 94; RV32I-NEXT: # %bb.1: 95; RV32I-NEXT: mv a0, a1 96; RV32I-NEXT: .LBB2_2: 97; RV32I-NEXT: ret 98; 99; RV64I-LABEL: func16: 100; RV64I: # %bb.0: 101; RV64I-NEXT: lui a3, 16 102; RV64I-NEXT: addiw a3, a3, -1 103; RV64I-NEXT: and a0, a0, a3 104; RV64I-NEXT: mul a1, a1, a2 105; RV64I-NEXT: and a1, a1, a3 106; RV64I-NEXT: sub a1, a0, a1 107; RV64I-NEXT: sltu a2, a0, a1 108; RV64I-NEXT: mv a0, zero 109; RV64I-NEXT: bnez a2, .LBB2_2 110; RV64I-NEXT: # %bb.1: 111; RV64I-NEXT: mv a0, a1 112; RV64I-NEXT: .LBB2_2: 113; RV64I-NEXT: ret 114 %a = mul i16 %y, %z 115 %tmp = call i16 @llvm.usub.sat.i16(i16 %x, i16 %a) 116 ret i16 %tmp 117} 118 119define i8 @func8(i8 %x, i8 %y, i8 %z) nounwind { 120; RV32I-LABEL: func8: 121; RV32I: # %bb.0: 122; RV32I-NEXT: andi a0, a0, 255 123; RV32I-NEXT: mul a1, a1, a2 124; RV32I-NEXT: andi a1, a1, 255 125; RV32I-NEXT: sub a1, a0, a1 126; RV32I-NEXT: sltu a2, a0, a1 127; RV32I-NEXT: mv a0, zero 128; RV32I-NEXT: bnez a2, .LBB3_2 129; RV32I-NEXT: # %bb.1: 130; RV32I-NEXT: mv a0, a1 131; RV32I-NEXT: .LBB3_2: 132; RV32I-NEXT: ret 133; 134; RV64I-LABEL: func8: 135; RV64I: # %bb.0: 136; RV64I-NEXT: andi a0, a0, 255 137; RV64I-NEXT: mul a1, a1, a2 138; RV64I-NEXT: andi a1, a1, 255 139; RV64I-NEXT: sub a1, a0, a1 140; RV64I-NEXT: sltu a2, a0, a1 141; RV64I-NEXT: mv a0, zero 142; RV64I-NEXT: bnez a2, .LBB3_2 143; RV64I-NEXT: # %bb.1: 144; RV64I-NEXT: mv a0, a1 145; RV64I-NEXT: .LBB3_2: 146; RV64I-NEXT: ret 147 %a = mul i8 %y, %z 148 %tmp = call i8 @llvm.usub.sat.i8(i8 %x, i8 %a) 149 ret i8 %tmp 150} 151 152define i4 @func4(i4 %x, i4 %y, i4 %z) nounwind { 153; RV32I-LABEL: func4: 154; RV32I: # %bb.0: 155; RV32I-NEXT: andi a0, a0, 15 156; RV32I-NEXT: mul a1, a1, a2 157; RV32I-NEXT: andi a1, a1, 15 158; RV32I-NEXT: sub a1, a0, a1 159; RV32I-NEXT: sltu a2, a0, a1 160; RV32I-NEXT: mv a0, zero 161; RV32I-NEXT: bnez a2, .LBB4_2 162; RV32I-NEXT: # %bb.1: 163; RV32I-NEXT: mv a0, a1 164; RV32I-NEXT: .LBB4_2: 165; RV32I-NEXT: ret 166; 167; RV64I-LABEL: func4: 168; RV64I: # %bb.0: 169; RV64I-NEXT: andi a0, a0, 15 170; RV64I-NEXT: mul a1, a1, a2 171; RV64I-NEXT: andi a1, a1, 15 172; RV64I-NEXT: sub a1, a0, a1 173; RV64I-NEXT: sltu a2, a0, a1 174; RV64I-NEXT: mv a0, zero 175; RV64I-NEXT: bnez a2, .LBB4_2 176; RV64I-NEXT: # %bb.1: 177; RV64I-NEXT: mv a0, a1 178; RV64I-NEXT: .LBB4_2: 179; RV64I-NEXT: ret 180 %a = mul i4 %y, %z 181 %tmp = call i4 @llvm.usub.sat.i4(i4 %x, i4 %a) 182 ret i4 %tmp 183} 184