https://github.com/TelGome updated https://github.com/llvm/llvm-project/pull/207978
>From f9ba72b7623f99f59aa7e05cd23bc1ef073d86ad Mon Sep 17 00:00:00 2001 From: Dongyan Chen <[email protected]> Date: Tue, 7 Jul 2026 07:19:20 +0000 Subject: [PATCH 1/2] Support Packed Saturating Absolute Value --- clang/include/clang/Basic/BuiltinsRISCV.td | 8 ++ clang/lib/CodeGen/TargetBuiltins/RISCV.cpp | 13 ++- clang/lib/Headers/riscv_packed_simd.h | 14 ++++ clang/test/CodeGen/RISCV/rvp-intrinsics.c | 84 +++++++++++++++++++ .../riscv_packed_simd.c | 18 ++++ llvm/include/llvm/IR/IntrinsicsRISCV.td | 7 ++ llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 30 +++++-- llvm/lib/Target/RISCV/RISCVInstrInfoP.td | 20 +++++ llvm/test/CodeGen/RISCV/rvp-simd-32.ll | 19 +++++ llvm/test/CodeGen/RISCV/rvp-simd-64.ll | 29 +++++++ 10 files changed, 234 insertions(+), 8 deletions(-) diff --git a/clang/include/clang/Basic/BuiltinsRISCV.td b/clang/include/clang/Basic/BuiltinsRISCV.td index df94565b0a242..3814958d81f8b 100644 --- a/clang/include/clang/Basic/BuiltinsRISCV.td +++ b/clang/include/clang/Basic/BuiltinsRISCV.td @@ -257,6 +257,14 @@ def pabdsumu_u8x8_u64 : RISCVBuiltin<"uint64_t(_Vector<8, unsigned char>, _Vecto def pabdsumau_u8x8_u32 : RISCVBuiltin<"unsigned int(unsigned int, _Vector<8, unsigned char>, _Vector<8, unsigned char>)">; def pabdsumau_u8x8_u64 : RISCVBuiltin<"uint64_t(uint64_t, _Vector<8, unsigned char>, _Vector<8, unsigned char>)">; +// Packed Saturating Absolute Value (32-bit) +def psabs_i8x4 : RISCVBuiltin<"_Vector<4, signed char>(_Vector<4, signed char>)">; +def psabs_i16x2 : RISCVBuiltin<"_Vector<2, short>(_Vector<2, short>)">; + +// Packed Saturating Absolute Value (64-bit) +def psabs_i8x8 : RISCVBuiltin<"_Vector<8, signed char>(_Vector<8, signed char>)">; +def psabs_i16x4 : RISCVBuiltin<"_Vector<4, short>(_Vector<4, short>)">; + } // Features = "experimental-p" //===----------------------------------------------------------------------===// diff --git a/clang/lib/CodeGen/TargetBuiltins/RISCV.cpp b/clang/lib/CodeGen/TargetBuiltins/RISCV.cpp index 168d24eddf7b6..a3b1db1732af9 100644 --- a/clang/lib/CodeGen/TargetBuiltins/RISCV.cpp +++ b/clang/lib/CodeGen/TargetBuiltins/RISCV.cpp @@ -1258,7 +1258,12 @@ Value *CodeGenFunction::EmitRISCVBuiltinExpr(unsigned BuiltinID, case RISCV::BI__builtin_riscv_pmerge_u16x4: case RISCV::BI__builtin_riscv_pmerge_i16x4: case RISCV::BI__builtin_riscv_pmerge_u32x2: - case RISCV::BI__builtin_riscv_pmerge_i32x2: { + case RISCV::BI__builtin_riscv_pmerge_i32x2: + // Packed Saturating Absolute Value + case RISCV::BI__builtin_riscv_psabs_i8x4: + case RISCV::BI__builtin_riscv_psabs_i16x2: + case RISCV::BI__builtin_riscv_psabs_i8x8: + case RISCV::BI__builtin_riscv_psabs_i16x4: { switch (BuiltinID) { default: llvm_unreachable("unexpected builtin ID"); @@ -1344,6 +1349,12 @@ Value *CodeGenFunction::EmitRISCVBuiltinExpr(unsigned BuiltinID, case RISCV::BI__builtin_riscv_pmerge_i32x2: ID = Intrinsic::riscv_pmerge; break; + case RISCV::BI__builtin_riscv_psabs_i8x4: + case RISCV::BI__builtin_riscv_psabs_i16x2: + case RISCV::BI__builtin_riscv_psabs_i8x8: + case RISCV::BI__builtin_riscv_psabs_i16x4: + ID = Intrinsic::riscv_psabs; + break; } IntrinsicTypes = {ResultType}; diff --git a/clang/lib/Headers/riscv_packed_simd.h b/clang/lib/Headers/riscv_packed_simd.h index aca82f298ef21..499ef7087a807 100644 --- a/clang/lib/Headers/riscv_packed_simd.h +++ b/clang/lib/Headers/riscv_packed_simd.h @@ -115,6 +115,11 @@ typedef uint32_t uint32x2_t __attribute__((__vector_size__(8))); return (ty)builtin(__rs1, __rs2, __rd); \ } +#define __packed_psabs(name, ty, builtin) \ + static __inline__ ty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1) { \ + return builtin(__rs1); \ + } + /* Packed Reverse: reverse the order of the elements. Lowered to a single * rev8/rev16/ppairoe.* by the backend's packed reverse-shuffle handling. */ #define __packed_reverse2(name, ty) \ @@ -519,6 +524,14 @@ __packed_abdsum(pabdsumu_u8x8_u64, uint64_t, uint8x8_t, __builtin_riscv_pabdsumu __packed_abdsum_acc(pabdsumau_u8x8_u32, uint32_t, uint8x8_t, __builtin_riscv_pabdsumau_u8x8_u32) __packed_abdsum_acc(pabdsumau_u8x8_u64, uint64_t, uint8x8_t, __builtin_riscv_pabdsumau_u8x8_u64) +/* Packed Saturating Absolute Value (32-bit) */ +__packed_psabs(psabs_i8x4, int8x4_t, __builtin_riscv_psabs_i8x4) +__packed_psabs(psabs_i16x2, int16x2_t, __builtin_riscv_psabs_i16x2) + +/* Packed Saturating Absolute Value (64-bit) */ +__packed_psabs(psabs_i8x8, int8x8_t, __builtin_riscv_psabs_i8x8) +__packed_psabs(psabs_i16x4, int16x4_t, __builtin_riscv_psabs_i16x4) + // clang-format on #undef __packed_splat2 @@ -540,6 +553,7 @@ __packed_abdsum_acc(pabdsumau_u8x8_u64, uint64_t, uint8x8_t, __builtin_riscv_pab #undef __packed_binary_builtin_cast #undef __packed_reduction #undef __packed_merge_builtin +#undef __packed_psabs #undef __packed_reverse2 #undef __packed_reverse4 #undef __packed_reverse8 diff --git a/clang/test/CodeGen/RISCV/rvp-intrinsics.c b/clang/test/CodeGen/RISCV/rvp-intrinsics.c index e0398aa5b19ba..e2204c6c6537e 100644 --- a/clang/test/CodeGen/RISCV/rvp-intrinsics.c +++ b/clang/test/CodeGen/RISCV/rvp-intrinsics.c @@ -6697,3 +6697,87 @@ uint32_t test_pabdsumau_u8x8_u32(uint32_t rd, uint8x8_t rs1, uint8x8_t rs2) { uint64_t test_pabdsumau_u8x8_u64(uint64_t rd, uint8x8_t rs1, uint8x8_t rs2) { return __riscv_pabdsumau_u8x8_u64(rd, rs1, rs2); } + +/* Packed Saturating Absolute Value (32-bit) */ + +// RV32-LABEL: define dso_local i32 @test_psabs_i8x4( +// RV32-SAME: i32 noundef [[RS1_COERCE:%.*]]) #[[ATTR0]] { +// RV32-NEXT: [[ENTRY:.*:]] +// RV32-NEXT: [[TMP0:%.*]] = bitcast i32 [[RS1_COERCE]] to <4 x i8> +// RV32-NEXT: [[TMP1:%.*]] = call <4 x i8> @llvm.riscv.psabs.v4i8(<4 x i8> [[TMP0]]) +// RV32-NEXT: [[TMP2:%.*]] = bitcast <4 x i8> [[TMP1]] to i32 +// RV32-NEXT: ret i32 [[TMP2]] +// +// RV64-LABEL: define dso_local i32 @test_psabs_i8x4( +// RV64-SAME: i32 noundef [[RS1_COERCE:%.*]]) #[[ATTR0]] { +// RV64-NEXT: [[ENTRY:.*:]] +// RV64-NEXT: [[TMP0:%.*]] = bitcast i32 [[RS1_COERCE]] to <4 x i8> +// RV64-NEXT: [[TMP1:%.*]] = call <4 x i8> @llvm.riscv.psabs.v4i8(<4 x i8> [[TMP0]]) +// RV64-NEXT: [[TMP2:%.*]] = bitcast <4 x i8> [[TMP1]] to i32 +// RV64-NEXT: ret i32 [[TMP2]] +// +int8x4_t test_psabs_i8x4(int8x4_t rs1) { + return __riscv_psabs_i8x4(rs1); +} + +// RV32-LABEL: define dso_local i32 @test_psabs_i16x2( +// RV32-SAME: i32 noundef [[RS1_COERCE:%.*]]) #[[ATTR0]] { +// RV32-NEXT: [[ENTRY:.*:]] +// RV32-NEXT: [[TMP0:%.*]] = bitcast i32 [[RS1_COERCE]] to <2 x i16> +// RV32-NEXT: [[TMP1:%.*]] = call <2 x i16> @llvm.riscv.psabs.v2i16(<2 x i16> [[TMP0]]) +// RV32-NEXT: [[TMP2:%.*]] = bitcast <2 x i16> [[TMP1]] to i32 +// RV32-NEXT: ret i32 [[TMP2]] +// +// RV64-LABEL: define dso_local i32 @test_psabs_i16x2( +// RV64-SAME: i32 noundef [[RS1_COERCE:%.*]]) #[[ATTR0]] { +// RV64-NEXT: [[ENTRY:.*:]] +// RV64-NEXT: [[TMP0:%.*]] = bitcast i32 [[RS1_COERCE]] to <2 x i16> +// RV64-NEXT: [[TMP1:%.*]] = call <2 x i16> @llvm.riscv.psabs.v2i16(<2 x i16> [[TMP0]]) +// RV64-NEXT: [[TMP2:%.*]] = bitcast <2 x i16> [[TMP1]] to i32 +// RV64-NEXT: ret i32 [[TMP2]] +// +int16x2_t test_psabs_i16x2(int16x2_t rs1) { + return __riscv_psabs_i16x2(rs1); +} + +/* Packed Saturating Absolute Value (64-bit) */ + +// RV32-LABEL: define dso_local i64 @test_psabs_i8x8( +// RV32-SAME: i64 noundef [[RS1_COERCE:%.*]]) #[[ATTR0]] { +// RV32-NEXT: [[ENTRY:.*:]] +// RV32-NEXT: [[TMP0:%.*]] = bitcast i64 [[RS1_COERCE]] to <8 x i8> +// RV32-NEXT: [[TMP1:%.*]] = call <8 x i8> @llvm.riscv.psabs.v8i8(<8 x i8> [[TMP0]]) +// RV32-NEXT: [[TMP2:%.*]] = bitcast <8 x i8> [[TMP1]] to i64 +// RV32-NEXT: ret i64 [[TMP2]] +// +// RV64-LABEL: define dso_local i64 @test_psabs_i8x8( +// RV64-SAME: i64 noundef [[RS1_COERCE:%.*]]) #[[ATTR0]] { +// RV64-NEXT: [[ENTRY:.*:]] +// RV64-NEXT: [[TMP0:%.*]] = bitcast i64 [[RS1_COERCE]] to <8 x i8> +// RV64-NEXT: [[TMP1:%.*]] = call <8 x i8> @llvm.riscv.psabs.v8i8(<8 x i8> [[TMP0]]) +// RV64-NEXT: [[TMP2:%.*]] = bitcast <8 x i8> [[TMP1]] to i64 +// RV64-NEXT: ret i64 [[TMP2]] +// +int8x8_t test_psabs_i8x8(int8x8_t rs1) { + return __riscv_psabs_i8x8(rs1); +} + +// RV32-LABEL: define dso_local i64 @test_psabs_i16x4( +// RV32-SAME: i64 noundef [[RS1_COERCE:%.*]]) #[[ATTR0]] { +// RV32-NEXT: [[ENTRY:.*:]] +// RV32-NEXT: [[TMP0:%.*]] = bitcast i64 [[RS1_COERCE]] to <4 x i16> +// RV32-NEXT: [[TMP1:%.*]] = call <4 x i16> @llvm.riscv.psabs.v4i16(<4 x i16> [[TMP0]]) +// RV32-NEXT: [[TMP2:%.*]] = bitcast <4 x i16> [[TMP1]] to i64 +// RV32-NEXT: ret i64 [[TMP2]] +// +// RV64-LABEL: define dso_local i64 @test_psabs_i16x4( +// RV64-SAME: i64 noundef [[RS1_COERCE:%.*]]) #[[ATTR0]] { +// RV64-NEXT: [[ENTRY:.*:]] +// RV64-NEXT: [[TMP0:%.*]] = bitcast i64 [[RS1_COERCE]] to <4 x i16> +// RV64-NEXT: [[TMP1:%.*]] = call <4 x i16> @llvm.riscv.psabs.v4i16(<4 x i16> [[TMP0]]) +// RV64-NEXT: [[TMP2:%.*]] = bitcast <4 x i16> [[TMP1]] to i64 +// RV64-NEXT: ret i64 [[TMP2]] +// +int16x4_t test_psabs_i16x4(int16x4_t rs1) { + return __riscv_psabs_i16x4(rs1); +} diff --git a/cross-project-tests/intrinsic-header-tests/riscv_packed_simd.c b/cross-project-tests/intrinsic-header-tests/riscv_packed_simd.c index f3e2f25629026..f23e43d4634d9 100644 --- a/cross-project-tests/intrinsic-header-tests/riscv_packed_simd.c +++ b/cross-project-tests/intrinsic-header-tests/riscv_packed_simd.c @@ -2336,3 +2336,21 @@ uint32_t test_pabdsumau_u8x8_u32(uint32_t rd, uint8x8_t a, uint8x8_t b) { uint64_t test_pabdsumau_u8x8_u64(uint64_t rd, uint8x8_t a, uint8x8_t b) { return __riscv_pabdsumau_u8x8_u64(rd, a, b); } + +// CHECK-LABEL: test_psabs_i8x4: +// CHECK: psabs.b +int8x4_t test_psabs_i8x4(int8x4_t a) { return __riscv_psabs_i8x4(a); } + +// CHECK-LABEL: test_psabs_i16x2: +// CHECK: psabs.h +int16x2_t test_psabs_i16x2(int16x2_t a) { return __riscv_psabs_i16x2(a); } + +// CHECK-LABEL: test_psabs_i8x8: +// RV32: psabs.db +// RV64: psabs.b +int8x8_t test_psabs_i8x8(int8x8_t a) { return __riscv_psabs_i8x8(a); } + +// CHECK-LABEL: test_psabs_i16x4: +// RV32: psabs.dh +// RV64: psabs.h +int16x4_t test_psabs_i16x4(int16x4_t a) { return __riscv_psabs_i16x4(a); } diff --git a/llvm/include/llvm/IR/IntrinsicsRISCV.td b/llvm/include/llvm/IR/IntrinsicsRISCV.td index c7f33f30ace58..28cde8111241c 100644 --- a/llvm/include/llvm/IR/IntrinsicsRISCV.td +++ b/llvm/include/llvm/IR/IntrinsicsRISCV.td @@ -2095,6 +2095,13 @@ class RVPBinaryIntrinsic [LLVMMatchType<0>, llvm_anyvector_ty, LLVMMatchType<1>], [IntrNoMem, IntrSpeculatable]>; + + // Packed Saturating Absolute Value + class RVPUnaryIntrinsic + : DefaultAttrsIntrinsic<[llvm_anyvector_ty], + [LLVMMatchType<0>], + [IntrNoMem, IntrSpeculatable]>; + def int_riscv_psabs : RVPUnaryIntrinsic; } // TargetPrefix = "riscv" //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index e1cfb2cba0a10..4d1e700cb71de 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -11856,7 +11856,8 @@ SDValue RISCVTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op, case Intrinsic::riscv_pasub: case Intrinsic::riscv_pasubu: case Intrinsic::riscv_pabd: - case Intrinsic::riscv_pabdu: { + case Intrinsic::riscv_pabdu: + case Intrinsic::riscv_psabs: { unsigned Opc; switch (IntNo) { case Intrinsic::riscv_paadd: @@ -11877,8 +11878,14 @@ SDValue RISCVTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op, case Intrinsic::riscv_pabdu: Opc = ISD::ABDU; break; + case Intrinsic::riscv_psabs: + Opc = RISCVISD::PSABS; + break; } + if (IntNo == Intrinsic::riscv_psabs) + return DAG.getNode(Opc, DL, Op.getValueType(), Op.getOperand(1)); + return DAG.getNode(Opc, DL, Op.getValueType(), Op.getOperand(1), Op.getOperand(2)); } @@ -15882,7 +15889,8 @@ void RISCVTargetLowering::ReplaceNodeResults(SDNode *N, case Intrinsic::riscv_pssa: case Intrinsic::riscv_paas: case Intrinsic::riscv_pasa: - case Intrinsic::riscv_pmerge: { + case Intrinsic::riscv_pmerge: + case Intrinsic::riscv_psabs: { EVT VT = N->getValueType(0); if (!Subtarget.is64Bit() || (VT != MVT::v4i8 && VT != MVT::v2i16)) return; @@ -15907,6 +15915,9 @@ void RISCVTargetLowering::ReplaceNodeResults(SDNode *N, case Intrinsic::riscv_pabdu: Opc = ISD::ABDU; break; + case Intrinsic::riscv_psabs: + Opc = RISCVISD::PSABS; + break; default: // pas/psa/psas/pssa/paas/pasa and pmerge: re-emit at the widened type // rather than lowering to a generic node. @@ -15918,20 +15929,25 @@ void RISCVTargetLowering::ReplaceNodeResults(SDNode *N, SDValue Undef = DAG.getUNDEF(VT); SDValue Op0 = DAG.getNode(ISD::CONCAT_VECTORS, DL, WideVT, N->getOperand(1), Undef); - SDValue Op1 = - DAG.getNode(ISD::CONCAT_VECTORS, DL, WideVT, N->getOperand(2), Undef); SDValue Res; - if (Opc == ISD::INTRINSIC_WO_CHAIN) { + if (IntNo == Intrinsic::riscv_psabs) { + // Unary: v4i8/v2i16 is illegal on RV64, so perform the operation on + // the widened (legal) type v8i8/v4i16, then extract the low half. + Res = DAG.getNode(Opc, DL, WideVT, Op0); + } else if (Opc == ISD::INTRINSIC_WO_CHAIN) { SmallVector<SDValue, 5> Ops; Ops.push_back(N->getOperand(0)); Ops.push_back(Op0); - Ops.push_back(Op1); + Ops.push_back(DAG.getNode(ISD::CONCAT_VECTORS, DL, WideVT, + N->getOperand(2), Undef)); if (N->getNumOperands() > 3) Ops.push_back(DAG.getNode(ISD::CONCAT_VECTORS, DL, WideVT, N->getOperand(3), Undef)); Res = DAG.getNode(Opc, DL, WideVT, Ops); } else { - Res = DAG.getNode(Opc, DL, WideVT, Op0, Op1); + Res = DAG.getNode(Opc, DL, WideVT, Op0, + DAG.getNode(ISD::CONCAT_VECTORS, DL, WideVT, + N->getOperand(2), Undef)); } Results.push_back(DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, VT, Res, DAG.getVectorIdxConstant(0, DL))); diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoP.td b/llvm/lib/Target/RISCV/RISCVInstrInfoP.td index 0eaeb78634114..2b1f8d7d8265f 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoP.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoP.td @@ -1754,6 +1754,11 @@ class PatGprPairGprPair<SDPatternOperator OpNode, RVInst Inst, ValueType vt> : Pat<(vt (OpNode (vt GPRPair:$rs1), (vt GPRPair:$rs2))), (Inst GPRPair:$rs1, GPRPair:$rs2)>; +// Unary GPRPair operation, one source register pair. +class PatGprPair<SDPatternOperator OpNode, RVInst Inst, ValueType vt> + : Pat<(vt (OpNode (vt GPRPair:$rs1))), + (Inst GPRPair:$rs1)>; + // Reduction sum. PatRedSum is the single-GPR source (predsum.bs/hs/ws), result // XLenVT; PatRedSumPair is the RV32 paired source (predsum.dbs/dhs), result i32. // Target-illegal results (i32 accumulator on RV64, i64 on RV32) don't reach @@ -1898,6 +1903,11 @@ def SDT_RISCVPPairE_DB : SDTypeProfile<2, 4, [SDTCisVT<0, v4i8>, SDTCisSameAs<0, 5>]>; def riscv_ppaire_db : RVSDNode<"PPAIRE_DB", SDT_RISCVPPairE_DB>; +// signed-saturating abs of each lane; an INT_MIN lane maps to INT_MAX. +def SDT_RISCVPackedUnary : SDTypeProfile<1, 1, [SDTCisVec<0>, + SDTCisSameAs<0, 1>]>; +def riscv_psabs : RVSDNode<"PSABS", SDT_RISCVPackedUnary>; + // Add one to the immediate. Used by RISCVISD::SATI. def IncImm : SDNodeXForm<imm, [{ return CurDAG->getTargetConstant(N->getZExtValue() + 1, SDLoc(N), @@ -2118,6 +2128,10 @@ let Predicates = [HasStdExtP] in { def : PatGprGpr<smax, PMAX_H, XLenVecI16VT>; def : PatGprGpr<umax, PMAXU_H, XLenVecI16VT>; + // 8/16-bit saturating absolute value patterns + def : PatGpr<riscv_psabs, PSABS_B, XLenVecI8VT>; + def : PatGpr<riscv_psabs, PSABS_H, XLenVecI16VT>; + // 8/16-bit vselect patterns def : Pat<(XLenVecI8VT (vselect (XLenVecI8VT GPR:$mask), GPR:$true_v, GPR:$false_v)), (MERGE GPR:$mask, GPR:$false_v, GPR:$true_v)>; @@ -2449,6 +2463,10 @@ let append Predicates = [IsRV32] in { def : PatGprPairGprPair<smax, PMAX_DW, v2i32>; def : PatGprPairGprPair<umax, PMAXU_DW, v2i32>; + // 8/16-bit saturating absolute value patterns + def : PatGprPair<riscv_psabs, PSABS_DB, v8i8>; + def : PatGprPair<riscv_psabs, PSABS_DH, v4i16>; + // 16-bit bswap patterns def : Pat<(v4i16 (bswap GPRPair:$rs)), (PPAIROE_DB GPRPair:$rs, GPRPair:$rs)>; @@ -2505,6 +2523,7 @@ let append Predicates = [IsRV32] in { (EXTRACT_SUBREG GPRPair:$vec, sub_gpr_even)>; def : Pat<(i32 (extractelt (v2i32 GPRPair:$vec), (i32 1))), (EXTRACT_SUBREG GPRPair:$vec, sub_gpr_odd)>; + } // append Predicates = [IsRV32] let append Predicates = [IsRV64] in { @@ -2736,4 +2755,5 @@ let append Predicates = [IsRV64] in { def : Pat<(v4i16 (sext_inreg GPR:$rs1, v4i8)), (PSEXT_H_B GPR:$rs1)>; def : Pat<(v2i32 (sext_inreg GPR:$rs1, v2i16)), (PSEXT_W_H GPR:$rs1)>; } // append Predicates = [IsRV64] + } // Predicates = [HasStdExtP] diff --git a/llvm/test/CodeGen/RISCV/rvp-simd-32.ll b/llvm/test/CodeGen/RISCV/rvp-simd-32.ll index 6b11524a700ae..48c7b3b14847e 100644 --- a/llvm/test/CodeGen/RISCV/rvp-simd-32.ll +++ b/llvm/test/CodeGen/RISCV/rvp-simd-32.ll @@ -2664,3 +2664,22 @@ define i32 @test_pabdsumau_u8x4_u32(i32 %rd, <4 x i8> %a, <4 x i8> %b) { %res = call i32 @llvm.riscv.pabdsumau.i32.v4i8(i32 %rd, <4 x i8> %a, <4 x i8> %b) ret i32 %res } + +; Packed Saturating Absolute Value +define <4 x i8> @test_psabs_v4i8(<4 x i8> %a) { +; CHECK-LABEL: test_psabs_v4i8: +; CHECK: # %bb.0: +; CHECK-NEXT: psabs.b a0, a0 +; CHECK-NEXT: ret + %res = call <4 x i8> @llvm.riscv.psabs.v4i8(<4 x i8> %a) + ret <4 x i8> %res +} + +define <2 x i16> @test_psabs_v2i16(<2 x i16> %a) { +; CHECK-LABEL: test_psabs_v2i16: +; CHECK: # %bb.0: +; CHECK-NEXT: psabs.h a0, a0 +; CHECK-NEXT: ret + %res = call <2 x i16> @llvm.riscv.psabs.v2i16(<2 x i16> %a) + ret <2 x i16> %res +} diff --git a/llvm/test/CodeGen/RISCV/rvp-simd-64.ll b/llvm/test/CodeGen/RISCV/rvp-simd-64.ll index 1f41bdf730910..9cbd64717c1d5 100644 --- a/llvm/test/CodeGen/RISCV/rvp-simd-64.ll +++ b/llvm/test/CodeGen/RISCV/rvp-simd-64.ll @@ -5817,3 +5817,32 @@ define i64 @test_pabdsumau_u8x8_u64(i64 %rd, <8 x i8> %a, <8 x i8> %b) { %res = call i64 @llvm.riscv.pabdsumau.i64.v8i8(i64 %rd, <8 x i8> %a, <8 x i8> %b) ret i64 %res } + +; Packed Saturating Absolute Value +define <8 x i8> @test_psabs_v8i8(<8 x i8> %a) { +; RV32-LABEL: test_psabs_v8i8: +; RV32: # %bb.0: +; RV32-NEXT: psabs.db a0, a0 +; RV32-NEXT: ret +; +; RV64-LABEL: test_psabs_v8i8: +; RV64: # %bb.0: +; RV64-NEXT: psabs.b a0, a0 +; RV64-NEXT: ret + %res = call <8 x i8> @llvm.riscv.psabs.v8i8(<8 x i8> %a) + ret <8 x i8> %res +} + +define <4 x i16> @test_psabs_v4i16(<4 x i16> %a) { +; RV32-LABEL: test_psabs_v4i16: +; RV32: # %bb.0: +; RV32-NEXT: psabs.dh a0, a0 +; RV32-NEXT: ret +; +; RV64-LABEL: test_psabs_v4i16: +; RV64: # %bb.0: +; RV64-NEXT: psabs.h a0, a0 +; RV64-NEXT: ret + %res = call <4 x i16> @llvm.riscv.psabs.v4i16(<4 x i16> %a) + ret <4 x i16> %res +} \ No newline at end of file >From 29f51163f03e53764039cd2f65472edfff94a1ac Mon Sep 17 00:00:00 2001 From: Dongyan Chen <[email protected]> Date: Wed, 8 Jul 2026 01:12:19 +0000 Subject: [PATCH 2/2] delete blank line --- llvm/lib/Target/RISCV/RISCVInstrInfoP.td | 2 -- 1 file changed, 2 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoP.td b/llvm/lib/Target/RISCV/RISCVInstrInfoP.td index 2b1f8d7d8265f..1f547fe3ff2a2 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoP.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoP.td @@ -2523,7 +2523,6 @@ let append Predicates = [IsRV32] in { (EXTRACT_SUBREG GPRPair:$vec, sub_gpr_even)>; def : Pat<(i32 (extractelt (v2i32 GPRPair:$vec), (i32 1))), (EXTRACT_SUBREG GPRPair:$vec, sub_gpr_odd)>; - } // append Predicates = [IsRV32] let append Predicates = [IsRV64] in { @@ -2755,5 +2754,4 @@ let append Predicates = [IsRV64] in { def : Pat<(v4i16 (sext_inreg GPR:$rs1, v4i8)), (PSEXT_H_B GPR:$rs1)>; def : Pat<(v2i32 (sext_inreg GPR:$rs1, v2i16)), (PSEXT_W_H GPR:$rs1)>; } // append Predicates = [IsRV64] - } // Predicates = [HasStdExtP] _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
