; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ; RUN: llc -mtriple=riscv32 -mattr=+v,+d -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,RV32 ; RUN: llc -mtriple=riscv64 -mattr=+v,+d -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,RV64 ; ; SABD ; define @sabd_b( %a, %b) { ; CHECK-LABEL: sabd_b: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli a0, zero, e8, m2, ta, ma ; CHECK-NEXT: vmin.vv v12, v8, v10 ; CHECK-NEXT: vmax.vv v8, v8, v10 ; CHECK-NEXT: vsub.vv v8, v8, v12 ; CHECK-NEXT: ret %a.sext = sext %a to %b.sext = sext %b to %sub = sub %a.sext, %b.sext %abs = call @llvm.abs.nxv16i16( %sub, i1 true) %trunc = trunc %abs to ret %trunc } define @sabd_b_promoted_ops( %a, %b) { ; CHECK-LABEL: sabd_b_promoted_ops: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli a0, zero, e8, m2, ta, ma ; CHECK-NEXT: vmxor.mm v0, v0, v8 ; CHECK-NEXT: vmv.v.i v8, 0 ; CHECK-NEXT: vmerge.vim v8, v8, 1, v0 ; CHECK-NEXT: ret %a.sext = sext %a to %b.sext = sext %b to %sub = sub %a.sext, %b.sext %abs = call @llvm.abs.nxv16i8( %sub, i1 true) ret %abs } define @sabd_h( %a, %b) { ; CHECK-LABEL: sabd_h: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli a0, zero, e16, m2, ta, ma ; CHECK-NEXT: vmin.vv v12, v8, v10 ; CHECK-NEXT: vmax.vv v8, v8, v10 ; CHECK-NEXT: vsub.vv v8, v8, v12 ; CHECK-NEXT: ret %a.sext = sext %a to %b.sext = sext %b to %sub = sub %a.sext, %b.sext %abs = call @llvm.abs.nxv8i32( %sub, i1 true) %trunc = trunc %abs to ret %trunc } define @sabd_h_promoted_ops( %a, %b) { ; CHECK-LABEL: sabd_h_promoted_ops: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli a0, zero, e8, m1, ta, ma ; CHECK-NEXT: vmin.vv v10, v8, v9 ; CHECK-NEXT: vmax.vv v8, v8, v9 ; CHECK-NEXT: vsub.vv v10, v8, v10 ; CHECK-NEXT: vsetvli zero, zero, e16, m2, ta, ma ; CHECK-NEXT: vzext.vf2 v8, v10 ; CHECK-NEXT: ret %a.sext = sext %a to %b.sext = sext %b to %sub = sub %a.sext, %b.sext %abs = call @llvm.abs.nxv8i16( %sub, i1 true) ret %abs } define @sabd_s( %a, %b) { ; CHECK-LABEL: sabd_s: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli a0, zero, e32, m2, ta, ma ; CHECK-NEXT: vmin.vv v12, v8, v10 ; CHECK-NEXT: vmax.vv v8, v8, v10 ; CHECK-NEXT: vsub.vv v8, v8, v12 ; CHECK-NEXT: ret %a.sext = sext %a to %b.sext = sext %b to %sub = sub %a.sext, %b.sext %abs = call @llvm.abs.nxv4i64( %sub, i1 true) %trunc = trunc %abs to ret %trunc } define @sabd_s_promoted_ops( %a, %b) { ; CHECK-LABEL: sabd_s_promoted_ops: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli a0, zero, e16, m1, ta, ma ; CHECK-NEXT: vmin.vv v10, v8, v9 ; CHECK-NEXT: vmax.vv v8, v8, v9 ; CHECK-NEXT: vsub.vv v10, v8, v10 ; CHECK-NEXT: vsetvli zero, zero, e32, m2, ta, ma ; CHECK-NEXT: vzext.vf2 v8, v10 ; CHECK-NEXT: ret %a.sext = sext %a to %b.sext = sext %b to %sub = sub %a.sext, %b.sext %abs = call @llvm.abs.nxv4i32( %sub, i1 true) ret %abs } define @sabd_d( %a, %b) { ; CHECK-LABEL: sabd_d: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli a0, zero, e64, m2, ta, ma ; CHECK-NEXT: vmin.vv v12, v8, v10 ; CHECK-NEXT: vmax.vv v8, v8, v10 ; CHECK-NEXT: vsub.vv v8, v8, v12 ; CHECK-NEXT: ret %a.sext = sext %a to %b.sext = sext %b to %sub = sub %a.sext, %b.sext %abs = call @llvm.abs.nxv2i128( %sub, i1 true) %trunc = trunc %abs to ret %trunc } define @sabd_d_promoted_ops( %a, %b) { ; CHECK-LABEL: sabd_d_promoted_ops: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli a0, zero, e32, m1, ta, ma ; CHECK-NEXT: vmin.vv v10, v8, v9 ; CHECK-NEXT: vmax.vv v8, v8, v9 ; CHECK-NEXT: vsub.vv v10, v8, v10 ; CHECK-NEXT: vsetvli zero, zero, e64, m2, ta, ma ; CHECK-NEXT: vzext.vf2 v8, v10 ; CHECK-NEXT: ret %a.sext = sext %a to %b.sext = sext %b to %sub = sub %a.sext, %b.sext %abs = call @llvm.abs.nxv2i64( %sub, i1 true) ret %abs } ; ; UABD ; define @uabd_b( %a, %b) { ; CHECK-LABEL: uabd_b: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli a0, zero, e8, m2, ta, ma ; CHECK-NEXT: vminu.vv v12, v8, v10 ; CHECK-NEXT: vmaxu.vv v8, v8, v10 ; CHECK-NEXT: vsub.vv v8, v8, v12 ; CHECK-NEXT: ret %a.zext = zext %a to %b.zext = zext %b to %sub = sub %a.zext, %b.zext %abs = call @llvm.abs.nxv16i16( %sub, i1 true) %trunc = trunc %abs to ret %trunc } define @uabd_b_promoted_ops( %a, %b) { ; CHECK-LABEL: uabd_b_promoted_ops: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli a0, zero, e8, m2, ta, ma ; CHECK-NEXT: vmxor.mm v0, v0, v8 ; CHECK-NEXT: vmv.v.i v8, 0 ; CHECK-NEXT: vmerge.vim v8, v8, 1, v0 ; CHECK-NEXT: ret %a.zext = zext %a to %b.zext = zext %b to %sub = sub %a.zext, %b.zext %abs = call @llvm.abs.nxv16i8( %sub, i1 true) ret %abs } define @uabd_h( %a, %b) { ; CHECK-LABEL: uabd_h: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli a0, zero, e16, m2, ta, ma ; CHECK-NEXT: vminu.vv v12, v8, v10 ; CHECK-NEXT: vmaxu.vv v8, v8, v10 ; CHECK-NEXT: vsub.vv v8, v8, v12 ; CHECK-NEXT: ret %a.zext = zext %a to %b.zext = zext %b to %sub = sub %a.zext, %b.zext %abs = call @llvm.abs.nxv8i32( %sub, i1 true) %trunc = trunc %abs to ret %trunc } define @uabd_h_promoted_ops( %a, %b) { ; CHECK-LABEL: uabd_h_promoted_ops: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli a0, zero, e8, m1, ta, ma ; CHECK-NEXT: vminu.vv v10, v8, v9 ; CHECK-NEXT: vmaxu.vv v8, v8, v9 ; CHECK-NEXT: vsub.vv v10, v8, v10 ; CHECK-NEXT: vsetvli zero, zero, e16, m2, ta, ma ; CHECK-NEXT: vzext.vf2 v8, v10 ; CHECK-NEXT: ret %a.zext = zext %a to %b.zext = zext %b to %sub = sub %a.zext, %b.zext %abs = call @llvm.abs.nxv8i16( %sub, i1 true) ret %abs } define @uabd_s( %a, %b) { ; CHECK-LABEL: uabd_s: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli a0, zero, e32, m2, ta, ma ; CHECK-NEXT: vminu.vv v12, v8, v10 ; CHECK-NEXT: vmaxu.vv v8, v8, v10 ; CHECK-NEXT: vsub.vv v8, v8, v12 ; CHECK-NEXT: ret %a.zext = zext %a to %b.zext = zext %b to %sub = sub %a.zext, %b.zext %abs = call @llvm.abs.nxv4i64( %sub, i1 true) %trunc = trunc %abs to ret %trunc } define @uabd_s_promoted_ops( %a, %b) { ; CHECK-LABEL: uabd_s_promoted_ops: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli a0, zero, e16, m1, ta, ma ; CHECK-NEXT: vminu.vv v10, v8, v9 ; CHECK-NEXT: vmaxu.vv v8, v8, v9 ; CHECK-NEXT: vsub.vv v10, v8, v10 ; CHECK-NEXT: vsetvli zero, zero, e32, m2, ta, ma ; CHECK-NEXT: vzext.vf2 v8, v10 ; CHECK-NEXT: ret %a.zext = zext %a to %b.zext = zext %b to %sub = sub %a.zext, %b.zext %abs = call @llvm.abs.nxv4i32( %sub, i1 true) ret %abs } define @uabd_d( %a, %b) { ; CHECK-LABEL: uabd_d: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli a0, zero, e64, m2, ta, ma ; CHECK-NEXT: vminu.vv v12, v8, v10 ; CHECK-NEXT: vmaxu.vv v8, v8, v10 ; CHECK-NEXT: vsub.vv v8, v8, v12 ; CHECK-NEXT: ret %a.zext = zext %a to %b.zext = zext %b to %sub = sub %a.zext, %b.zext %abs = call @llvm.abs.nxv2i128( %sub, i1 true) %trunc = trunc %abs to ret %trunc } define @uabd_d_promoted_ops( %a, %b) { ; CHECK-LABEL: uabd_d_promoted_ops: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli a0, zero, e32, m1, ta, ma ; CHECK-NEXT: vminu.vv v10, v8, v9 ; CHECK-NEXT: vmaxu.vv v8, v8, v9 ; CHECK-NEXT: vsub.vv v10, v8, v10 ; CHECK-NEXT: vsetvli zero, zero, e64, m2, ta, ma ; CHECK-NEXT: vzext.vf2 v8, v10 ; CHECK-NEXT: ret %a.zext = zext %a to %b.zext = zext %b to %sub = sub %a.zext, %b.zext %abs = call @llvm.abs.nxv2i64( %sub, i1 true) ret %abs } ; Test the situation where isLegal(ISD::ABD, typeof(%a)) returns true but %a and ; %b have differing types. define @uabd_non_matching_extension( %a, %b) { ; CHECK-LABEL: uabd_non_matching_extension: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli a0, zero, e32, m2, ta, ma ; CHECK-NEXT: vzext.vf4 v12, v10 ; CHECK-NEXT: vminu.vv v10, v8, v12 ; CHECK-NEXT: vmaxu.vv v8, v8, v12 ; CHECK-NEXT: vsub.vv v8, v8, v10 ; CHECK-NEXT: ret %a.zext = zext %a to %b.zext = zext %b to %sub = sub %a.zext, %b.zext %abs = call @llvm.abs.nxv4i64( %sub, i1 true) %trunc = trunc %abs to ret %trunc } ; Test the situation where isLegal(ISD::ABD, typeof(%a.zext)) returns true but ; %a and %b have differing types. define @uabd_non_matching_promoted_ops( %a, %b) { ; CHECK-LABEL: uabd_non_matching_promoted_ops: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli a0, zero, e16, m1, ta, ma ; CHECK-NEXT: vzext.vf2 v10, v8 ; CHECK-NEXT: vminu.vv v8, v10, v9 ; CHECK-NEXT: vmaxu.vv v9, v10, v9 ; CHECK-NEXT: vsub.vv v10, v9, v8 ; CHECK-NEXT: vsetvli zero, zero, e32, m2, ta, ma ; CHECK-NEXT: vzext.vf2 v8, v10 ; CHECK-NEXT: ret %a.zext = zext %a to %b.zext = zext %b to %sub = sub %a.zext, %b.zext %abs = call @llvm.abs.nxv4i32( %sub, i1 true) ret %abs } ; Test the situation where isLegal(ISD::ABD, typeof(%a)) returns true but %a and ; %b are promoted differently. define @uabd_non_matching_promotion( %a, %b) { ; CHECK-LABEL: uabd_non_matching_promotion: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetvli a0, zero, e32, m2, ta, ma ; CHECK-NEXT: vzext.vf4 v10, v8 ; CHECK-NEXT: vsext.vf4 v12, v9 ; CHECK-NEXT: vmin.vv v8, v10, v12 ; CHECK-NEXT: vmax.vv v10, v10, v12 ; CHECK-NEXT: vsub.vv v8, v10, v8 ; CHECK-NEXT: ret %a.zext = zext %a to %b.zext = sext %b to %sub = sub %a.zext, %b.zext %abs = call @llvm.abs.nxv4i32( %sub, i1 true) ret %abs } declare @llvm.abs.nxv16i8(, i1) declare @llvm.abs.nxv8i16(, i1) declare @llvm.abs.nxv16i16(, i1) declare @llvm.abs.nxv4i32(, i1) declare @llvm.abs.nxv8i32(, i1) declare @llvm.abs.nxv2i64(, i1) declare @llvm.abs.nxv4i64(, i1) declare @llvm.abs.nxv2i128(, i1) ;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: ; RV32: {{.*}} ; RV64: {{.*}}