https://github.com/XChy created https://github.com/llvm/llvm-project/pull/211223
None >From cc4efb7f7329d04520d239aeb67ea56240975ab5 Mon Sep 17 00:00:00 2001 From: XChy <[email protected]> Date: Sat, 18 Jul 2026 02:31:50 +0800 Subject: [PATCH] [RISCV][P-ext] Support Packed Multiply High --- clang/include/clang/Basic/BuiltinsRISCV.td | 22 +++ clang/lib/CodeGen/TargetBuiltins/RISCV.cpp | 49 +++++ clang/lib/Headers/riscv_packed_simd.h | 29 +++ .../riscv_packed_simd.c | 120 ++++++++++++ llvm/include/llvm/IR/IntrinsicsRISCV.td | 8 + llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 67 ++++++- llvm/test/CodeGen/RISCV/rvp-simd-32.ll | 55 ++++++ llvm/test/CodeGen/RISCV/rvp-simd-64.ll | 181 ++++++++++++++++++ 8 files changed, 529 insertions(+), 2 deletions(-) diff --git a/clang/include/clang/Basic/BuiltinsRISCV.td b/clang/include/clang/Basic/BuiltinsRISCV.td index 3814958d81f8b..4e1eb7bc5621b 100644 --- a/clang/include/clang/Basic/BuiltinsRISCV.td +++ b/clang/include/clang/Basic/BuiltinsRISCV.td @@ -247,6 +247,28 @@ def pmerge_i16x4 : RISCVBuiltin<"_Vector<4, short>(_Vector<4, short>, _Vector<4, def pmerge_u32x2 : RISCVBuiltin<"_Vector<2, unsigned int>(_Vector<2, unsigned int>, _Vector<2, unsigned int>, _Vector<2, unsigned int>)">; def pmerge_i32x2 : RISCVBuiltin<"_Vector<2, int>(_Vector<2, int>, _Vector<2, int>, _Vector<2, unsigned int>)">; +// Packed Multiply High (32-bit) +def pmulh_i16x2 : RISCVBuiltin<"_Vector<2, short>(_Vector<2, short>, _Vector<2, short>)">; +def pmulhr_i16x2 : RISCVBuiltin<"_Vector<2, short>(_Vector<2, short>, _Vector<2, short>)">; +def pmulhu_u16x2 : RISCVBuiltin<"_Vector<2, unsigned short>(_Vector<2, unsigned short>, _Vector<2, unsigned short>)">; +def pmulhru_u16x2 : RISCVBuiltin<"_Vector<2, unsigned short>(_Vector<2, unsigned short>, _Vector<2, unsigned short>)">; +def pmulhsu_i16x2 : RISCVBuiltin<"_Vector<2, short>(_Vector<2, short>, _Vector<2, unsigned short>)">; +def pmulhrsu_i16x2 : RISCVBuiltin<"_Vector<2, short>(_Vector<2, short>, _Vector<2, unsigned short>)">; + +// Packed Multiply High (64-bit) +def pmulh_i16x4 : RISCVBuiltin<"_Vector<4, short>(_Vector<4, short>, _Vector<4, short>)">; +def pmulh_i32x2 : RISCVBuiltin<"_Vector<2, int>(_Vector<2, int>, _Vector<2, int>)">; +def pmulhr_i16x4 : RISCVBuiltin<"_Vector<4, short>(_Vector<4, short>, _Vector<4, short>)">; +def pmulhr_i32x2 : RISCVBuiltin<"_Vector<2, int>(_Vector<2, int>, _Vector<2, int>)">; +def pmulhu_u16x4 : RISCVBuiltin<"_Vector<4, unsigned short>(_Vector<4, unsigned short>, _Vector<4, unsigned short>)">; +def pmulhu_u32x2 : RISCVBuiltin<"_Vector<2, unsigned int>(_Vector<2, unsigned int>, _Vector<2, unsigned int>)">; +def pmulhru_u16x4 : RISCVBuiltin<"_Vector<4, unsigned short>(_Vector<4, unsigned short>, _Vector<4, unsigned short>)">; +def pmulhru_u32x2 : RISCVBuiltin<"_Vector<2, unsigned int>(_Vector<2, unsigned int>, _Vector<2, unsigned int>)">; +def pmulhsu_i16x4 : RISCVBuiltin<"_Vector<4, short>(_Vector<4, short>, _Vector<4, unsigned short>)">; +def pmulhsu_i32x2 : RISCVBuiltin<"_Vector<2, int>(_Vector<2, int>, _Vector<2, unsigned int>)">; +def pmulhrsu_i16x4 : RISCVBuiltin<"_Vector<4, short>(_Vector<4, short>, _Vector<4, unsigned short>)">; +def pmulhrsu_i32x2 : RISCVBuiltin<"_Vector<2, int>(_Vector<2, int>, _Vector<2, unsigned int>)">; + // Packed Absolute Difference Sum (32-bit) def pabdsumu_u8x4_u32 : RISCVBuiltin<"unsigned int(_Vector<4, unsigned char>, _Vector<4, unsigned char>)">; def pabdsumau_u8x4_u32 : RISCVBuiltin<"unsigned int(unsigned int, _Vector<4, unsigned char>, _Vector<4, unsigned char>)">; diff --git a/clang/lib/CodeGen/TargetBuiltins/RISCV.cpp b/clang/lib/CodeGen/TargetBuiltins/RISCV.cpp index a3b1db1732af9..782c1ee1903d2 100644 --- a/clang/lib/CodeGen/TargetBuiltins/RISCV.cpp +++ b/clang/lib/CodeGen/TargetBuiltins/RISCV.cpp @@ -1259,6 +1259,25 @@ Value *CodeGenFunction::EmitRISCVBuiltinExpr(unsigned BuiltinID, case RISCV::BI__builtin_riscv_pmerge_i16x4: case RISCV::BI__builtin_riscv_pmerge_u32x2: case RISCV::BI__builtin_riscv_pmerge_i32x2: + // Packed Multiply High + case RISCV::BI__builtin_riscv_pmulh_i16x2: + case RISCV::BI__builtin_riscv_pmulh_i16x4: + case RISCV::BI__builtin_riscv_pmulh_i32x2: + case RISCV::BI__builtin_riscv_pmulhr_i16x2: + case RISCV::BI__builtin_riscv_pmulhr_i16x4: + case RISCV::BI__builtin_riscv_pmulhr_i32x2: + case RISCV::BI__builtin_riscv_pmulhu_u16x2: + case RISCV::BI__builtin_riscv_pmulhu_u16x4: + case RISCV::BI__builtin_riscv_pmulhu_u32x2: + case RISCV::BI__builtin_riscv_pmulhru_u16x2: + case RISCV::BI__builtin_riscv_pmulhru_u16x4: + case RISCV::BI__builtin_riscv_pmulhru_u32x2: + case RISCV::BI__builtin_riscv_pmulhsu_i16x2: + case RISCV::BI__builtin_riscv_pmulhsu_i16x4: + case RISCV::BI__builtin_riscv_pmulhsu_i32x2: + case RISCV::BI__builtin_riscv_pmulhrsu_i16x2: + case RISCV::BI__builtin_riscv_pmulhrsu_i16x4: + case RISCV::BI__builtin_riscv_pmulhrsu_i32x2: // Packed Saturating Absolute Value case RISCV::BI__builtin_riscv_psabs_i8x4: case RISCV::BI__builtin_riscv_psabs_i16x2: @@ -1349,6 +1368,36 @@ Value *CodeGenFunction::EmitRISCVBuiltinExpr(unsigned BuiltinID, case RISCV::BI__builtin_riscv_pmerge_i32x2: ID = Intrinsic::riscv_pmerge; break; + case RISCV::BI__builtin_riscv_pmulh_i16x2: + case RISCV::BI__builtin_riscv_pmulh_i16x4: + case RISCV::BI__builtin_riscv_pmulh_i32x2: + ID = Intrinsic::riscv_pmulh; + break; + case RISCV::BI__builtin_riscv_pmulhr_i16x2: + case RISCV::BI__builtin_riscv_pmulhr_i16x4: + case RISCV::BI__builtin_riscv_pmulhr_i32x2: + ID = Intrinsic::riscv_pmulhr; + break; + case RISCV::BI__builtin_riscv_pmulhu_u16x2: + case RISCV::BI__builtin_riscv_pmulhu_u16x4: + case RISCV::BI__builtin_riscv_pmulhu_u32x2: + ID = Intrinsic::riscv_pmulhu; + break; + case RISCV::BI__builtin_riscv_pmulhru_u16x2: + case RISCV::BI__builtin_riscv_pmulhru_u16x4: + case RISCV::BI__builtin_riscv_pmulhru_u32x2: + ID = Intrinsic::riscv_pmulhru; + break; + case RISCV::BI__builtin_riscv_pmulhsu_i16x2: + case RISCV::BI__builtin_riscv_pmulhsu_i16x4: + case RISCV::BI__builtin_riscv_pmulhsu_i32x2: + ID = Intrinsic::riscv_pmulhsu; + break; + case RISCV::BI__builtin_riscv_pmulhrsu_i16x2: + case RISCV::BI__builtin_riscv_pmulhrsu_i16x4: + case RISCV::BI__builtin_riscv_pmulhrsu_i32x2: + ID = Intrinsic::riscv_pmulhrsu; + break; case RISCV::BI__builtin_riscv_psabs_i8x4: case RISCV::BI__builtin_riscv_psabs_i16x2: case RISCV::BI__builtin_riscv_psabs_i8x8: diff --git a/clang/lib/Headers/riscv_packed_simd.h b/clang/lib/Headers/riscv_packed_simd.h index 7d40f046eba80..7ca98aaa21553 100644 --- a/clang/lib/Headers/riscv_packed_simd.h +++ b/clang/lib/Headers/riscv_packed_simd.h @@ -71,6 +71,12 @@ typedef uint32_t uint32x2_t __attribute__((__vector_size__(8))); return builtin(__rs1, __rs2); \ } +#define __packed_binary_builtin_mixed(name, rty, ty1, ty2, builtin) \ + static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(ty1 __rs1, \ + ty2 __rs2) { \ + return builtin(__rs1, __rs2); \ + } + #define __packed_sh1add(name, ty) \ static __inline__ ty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1, ty __rs2) { \ return (__rs1 << 1) + __rs2; \ @@ -672,6 +678,28 @@ __packed_merge_builtin(pmerge_i16x4, int16x4_t, uint16x4_t, __builtin_riscv_pmer __packed_merge_builtin(pmerge_u32x2, uint32x2_t, uint32x2_t, __builtin_riscv_pmerge_u32x2) __packed_merge_builtin(pmerge_i32x2, int32x2_t, uint32x2_t, __builtin_riscv_pmerge_i32x2) +/* Packed Multiply High (32-bit) */ +__packed_binary_builtin(pmulh_i16x2, int16x2_t, __builtin_riscv_pmulh_i16x2) +__packed_binary_builtin(pmulhr_i16x2, int16x2_t, __builtin_riscv_pmulhr_i16x2) +__packed_binary_builtin(pmulhu_u16x2, uint16x2_t, __builtin_riscv_pmulhu_u16x2) +__packed_binary_builtin(pmulhru_u16x2, uint16x2_t, __builtin_riscv_pmulhru_u16x2) +__packed_binary_builtin_mixed(pmulhsu_i16x2, int16x2_t, int16x2_t, uint16x2_t, __builtin_riscv_pmulhsu_i16x2) +__packed_binary_builtin_mixed(pmulhrsu_i16x2, int16x2_t, int16x2_t, uint16x2_t, __builtin_riscv_pmulhrsu_i16x2) + +/* Packed Multiply High (64-bit) */ +__packed_binary_builtin(pmulh_i16x4, int16x4_t, __builtin_riscv_pmulh_i16x4) +__packed_binary_builtin(pmulh_i32x2, int32x2_t, __builtin_riscv_pmulh_i32x2) +__packed_binary_builtin(pmulhr_i16x4, int16x4_t, __builtin_riscv_pmulhr_i16x4) +__packed_binary_builtin(pmulhr_i32x2, int32x2_t, __builtin_riscv_pmulhr_i32x2) +__packed_binary_builtin(pmulhu_u16x4, uint16x4_t, __builtin_riscv_pmulhu_u16x4) +__packed_binary_builtin(pmulhu_u32x2, uint32x2_t, __builtin_riscv_pmulhu_u32x2) +__packed_binary_builtin(pmulhru_u16x4, uint16x4_t, __builtin_riscv_pmulhru_u16x4) +__packed_binary_builtin(pmulhru_u32x2, uint32x2_t, __builtin_riscv_pmulhru_u32x2) +__packed_binary_builtin_mixed(pmulhsu_i16x4, int16x4_t, int16x4_t, uint16x4_t, __builtin_riscv_pmulhsu_i16x4) +__packed_binary_builtin_mixed(pmulhsu_i32x2, int32x2_t, int32x2_t, uint32x2_t, __builtin_riscv_pmulhsu_i32x2) +__packed_binary_builtin_mixed(pmulhrsu_i16x4, int16x4_t, int16x4_t, uint16x4_t, __builtin_riscv_pmulhrsu_i16x4) +__packed_binary_builtin_mixed(pmulhrsu_i32x2, int32x2_t, int32x2_t, uint32x2_t, __builtin_riscv_pmulhrsu_i32x2) + /* Packed Absolute Difference Sum (32-bit) */ __packed_abdsum(pabdsumu_u8x4_u32, uint32_t, uint8x4_t, __builtin_riscv_pabdsumu_u8x4_u32) __packed_abdsum_acc(pabdsumau_u8x4_u32, uint32_t, uint8x4_t, __builtin_riscv_pabdsumau_u8x4_u32) @@ -794,6 +822,7 @@ __packed_reinterpret(u32x2_i32x2, int32x2_t, uint32x2_t) #undef __packed_binary_op #undef __packed_unary_op #undef __packed_binary_builtin +#undef __packed_binary_builtin_mixed #undef __packed_sh1add #undef __packed_sh1sadd #undef __packed_cmp 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 2af196cdaadc0..fe3f56a0a6a3a 100644 --- a/cross-project-tests/intrinsic-header-tests/riscv_packed_simd.c +++ b/cross-project-tests/intrinsic-header-tests/riscv_packed_simd.c @@ -2382,6 +2382,126 @@ int32x2_t test_pmerge_mvmn_i32x2(int32x2_t rs2, int32x2_t rs1, uint32x2_t rd) { return __riscv_pmerge_i32x2(rs1, rs2, rd); } +// CHECK-LABEL: test_pmulh_i16x2: +// CHECK: pmulh.h +int16x2_t test_pmulh_i16x2(int16x2_t rs1, int16x2_t rs2) { + return __riscv_pmulh_i16x2(rs1, rs2); +} + +// CHECK-LABEL: test_pmulhr_i16x2: +// CHECK: pmulhr.h +int16x2_t test_pmulhr_i16x2(int16x2_t rs1, int16x2_t rs2) { + return __riscv_pmulhr_i16x2(rs1, rs2); +} + +// CHECK-LABEL: test_pmulhu_u16x2: +// CHECK: pmulhu.h +uint16x2_t test_pmulhu_u16x2(uint16x2_t rs1, uint16x2_t rs2) { + return __riscv_pmulhu_u16x2(rs1, rs2); +} + +// CHECK-LABEL: test_pmulhru_u16x2: +// CHECK: pmulhru.h +uint16x2_t test_pmulhru_u16x2(uint16x2_t rs1, uint16x2_t rs2) { + return __riscv_pmulhru_u16x2(rs1, rs2); +} + +// CHECK-LABEL: test_pmulhsu_i16x2: +// CHECK: pmulhsu.h +int16x2_t test_pmulhsu_i16x2(int16x2_t rs1, uint16x2_t rs2) { + return __riscv_pmulhsu_i16x2(rs1, rs2); +} + +// CHECK-LABEL: test_pmulhrsu_i16x2: +// CHECK: pmulhrsu.h +int16x2_t test_pmulhrsu_i16x2(int16x2_t rs1, uint16x2_t rs2) { + return __riscv_pmulhrsu_i16x2(rs1, rs2); +} + +// CHECK-LABEL: test_pmulh_i16x4: +// RV32-COUNT-2: pmulh.h +// RV64: pmulh.h +int16x4_t test_pmulh_i16x4(int16x4_t rs1, int16x4_t rs2) { + return __riscv_pmulh_i16x4(rs1, rs2); +} + +// CHECK-LABEL: test_pmulhr_i16x4: +// RV32-COUNT-2: pmulhr.h +// RV64: pmulhr.h +int16x4_t test_pmulhr_i16x4(int16x4_t rs1, int16x4_t rs2) { + return __riscv_pmulhr_i16x4(rs1, rs2); +} + +// CHECK-LABEL: test_pmulhu_u16x4: +// RV32-COUNT-2: pmulhu.h +// RV64: pmulhu.h +uint16x4_t test_pmulhu_u16x4(uint16x4_t rs1, uint16x4_t rs2) { + return __riscv_pmulhu_u16x4(rs1, rs2); +} + +// CHECK-LABEL: test_pmulhru_u16x4: +// RV32-COUNT-2: pmulhru.h +// RV64: pmulhru.h +uint16x4_t test_pmulhru_u16x4(uint16x4_t rs1, uint16x4_t rs2) { + return __riscv_pmulhru_u16x4(rs1, rs2); +} + +// CHECK-LABEL: test_pmulhsu_i16x4: +// RV32-COUNT-2: pmulhsu.h +// RV64: pmulhsu.h +int16x4_t test_pmulhsu_i16x4(int16x4_t rs1, uint16x4_t rs2) { + return __riscv_pmulhsu_i16x4(rs1, rs2); +} + +// CHECK-LABEL: test_pmulhrsu_i16x4: +// RV32-COUNT-2: pmulhrsu.h +// RV64: pmulhrsu.h +int16x4_t test_pmulhrsu_i16x4(int16x4_t rs1, uint16x4_t rs2) { + return __riscv_pmulhrsu_i16x4(rs1, rs2); +} + +// CHECK-LABEL: test_pmulh_i32x2: +// RV32-COUNT-2: mulh +// RV64: pmulh.w +int32x2_t test_pmulh_i32x2(int32x2_t rs1, int32x2_t rs2) { + return __riscv_pmulh_i32x2(rs1, rs2); +} + +// CHECK-LABEL: test_pmulhr_i32x2: +// RV32-COUNT-2: mulhr +// RV64: pmulhr.w +int32x2_t test_pmulhr_i32x2(int32x2_t rs1, int32x2_t rs2) { + return __riscv_pmulhr_i32x2(rs1, rs2); +} + +// CHECK-LABEL: test_pmulhu_u32x2: +// RV32-COUNT-2: mulhu +// RV64: pmulhu.w +uint32x2_t test_pmulhu_u32x2(uint32x2_t rs1, uint32x2_t rs2) { + return __riscv_pmulhu_u32x2(rs1, rs2); +} + +// CHECK-LABEL: test_pmulhru_u32x2: +// RV32-COUNT-2: mulhru +// RV64: pmulhru.w +uint32x2_t test_pmulhru_u32x2(uint32x2_t rs1, uint32x2_t rs2) { + return __riscv_pmulhru_u32x2(rs1, rs2); +} + +// CHECK-LABEL: test_pmulhsu_i32x2: +// RV32-COUNT-2: mulhsu +// RV64: pmulhsu.w +int32x2_t test_pmulhsu_i32x2(int32x2_t rs1, uint32x2_t rs2) { + return __riscv_pmulhsu_i32x2(rs1, rs2); +} + +// CHECK-LABEL: test_pmulhrsu_i32x2: +// RV32-COUNT-2: mulhrsu +// RV64: pmulhrsu.w +int32x2_t test_pmulhrsu_i32x2(int32x2_t rs1, uint32x2_t rs2) { + return __riscv_pmulhrsu_i32x2(rs1, rs2); +} + // CHECK-LABEL: test_prev_i8x4: // CHECK: rev8 int8x4_t test_prev_i8x4(int8x4_t a) { return __riscv_prev_i8x4(a); } diff --git a/llvm/include/llvm/IR/IntrinsicsRISCV.td b/llvm/include/llvm/IR/IntrinsicsRISCV.td index fca28455f2117..972942f565c83 100644 --- a/llvm/include/llvm/IR/IntrinsicsRISCV.td +++ b/llvm/include/llvm/IR/IntrinsicsRISCV.td @@ -2095,6 +2095,14 @@ class RVPBinaryIntrinsic [IntrNoMem, IntrSpeculatable]>; def int_riscv_pmerge : RVPTernaryIntrinsic; + // Packed Multiply High. + def int_riscv_pmulh : RVPBinaryIntrinsic; + def int_riscv_pmulhr : RVPBinaryIntrinsic; + def int_riscv_pmulhu : RVPBinaryIntrinsic; + def int_riscv_pmulhru : RVPBinaryIntrinsic; + def int_riscv_pmulhsu : RVPBinaryIntrinsic; + def int_riscv_pmulhrsu : RVPBinaryIntrinsic; + // Packed Absolute Difference Sum. def int_riscv_pabdsumu : DefaultAttrsIntrinsic<[llvm_anyint_ty], diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index 0e33e140aaa72..521a9be84596f 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -11974,6 +11974,25 @@ static unsigned getRVPShiftOpcode(Intrinsic::ID IntNo) { } } +static unsigned getRVPMulHighOpcode(unsigned IntNo) { + switch (IntNo) { + default: + llvm_unreachable("Unexpected RISC-V packed multiply high intrinsic"); + case Intrinsic::riscv_pmulh: + return ISD::MULHS; + case Intrinsic::riscv_pmulhr: + return RISCVISD::MULHR; + case Intrinsic::riscv_pmulhu: + return ISD::MULHU; + case Intrinsic::riscv_pmulhru: + return RISCVISD::MULHRU; + case Intrinsic::riscv_pmulhsu: + return RISCVISD::MULHSU; + case Intrinsic::riscv_pmulhrsu: + return RISCVISD::MULHRSU; + } +} + SDValue RISCVTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const { unsigned IntNo = Op.getConstantOperandVal(0); @@ -12175,6 +12194,44 @@ SDValue RISCVTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op, return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, DL, MVT::i32, AbdsumauId, Lo, Rs1Hi, Rs2Hi); } + case Intrinsic::riscv_pmulh: + case Intrinsic::riscv_pmulhr: + case Intrinsic::riscv_pmulhu: + case Intrinsic::riscv_pmulhru: + case Intrinsic::riscv_pmulhsu: + case Intrinsic::riscv_pmulhrsu: { + EVT VT = Op.getValueType(); + unsigned Opc = getRVPMulHighOpcode(IntNo); + + // RV32 has no single instruction for 64-bit packed multiply high. Split + // v4i16 into two v2i16 packed operations, and split v2i32 into scalar i32 + // operations so isel can use MULH*. + if (!Subtarget.is64Bit() && VT == MVT::v4i16) { + auto [Rs1Lo, Rs1Hi] = DAG.SplitVector(Op.getOperand(1), DL); + auto [Rs2Lo, Rs2Hi] = DAG.SplitVector(Op.getOperand(2), DL); + SDValue Id = Op.getOperand(0); + SDValue Lo = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, DL, MVT::v2i16, Id, + Rs1Lo, Rs2Lo); + SDValue Hi = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, DL, MVT::v2i16, Id, + Rs1Hi, Rs2Hi); + return DAG.getNode(ISD::CONCAT_VECTORS, DL, VT, Lo, Hi); + } + + if (!Subtarget.is64Bit() && VT == MVT::v2i32) { + auto Extract = [&](SDValue V, unsigned Idx) { + return DAG.getExtractVectorElt(DL, MVT::i32, V, Idx); + }; + SDValue Rs1 = Op.getOperand(1); + SDValue Rs2 = Op.getOperand(2); + SDValue Lo = DAG.getNode(Opc, DL, MVT::i32, Extract(Rs1, 0), + Extract(Rs2, 0)); + SDValue Hi = DAG.getNode(Opc, DL, MVT::i32, Extract(Rs1, 1), + Extract(Rs2, 1)); + return DAG.getNode(ISD::BUILD_VECTOR, DL, VT, Lo, Hi); + } + + return DAG.getNode(Opc, DL, VT, Op.getOperand(1), Op.getOperand(2)); + } case Intrinsic::riscv_pmerge: { EVT VT = Op.getValueType(); auto buildMerge = [&](SDValue Rs1, SDValue Rs2, SDValue Mask, @@ -16204,6 +16261,12 @@ void RISCVTargetLowering::ReplaceNodeResults(SDNode *N, case Intrinsic::riscv_paas: case Intrinsic::riscv_pasa: case Intrinsic::riscv_pmerge: + case Intrinsic::riscv_pmulh: + case Intrinsic::riscv_pmulhr: + case Intrinsic::riscv_pmulhu: + case Intrinsic::riscv_pmulhru: + case Intrinsic::riscv_pmulhsu: + case Intrinsic::riscv_pmulhrsu: case Intrinsic::riscv_psabs: { EVT VT = N->getValueType(0); if (!Subtarget.is64Bit() || (VT != MVT::v4i8 && VT != MVT::v2i16)) @@ -16233,8 +16296,8 @@ void RISCVTargetLowering::ReplaceNodeResults(SDNode *N, 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. + // pas/psa/psas/pssa/paas/pasa, pmerge, and pmulh*: re-emit at the + // widened type rather than lowering to a generic node. Opc = ISD::INTRINSIC_WO_CHAIN; break; } diff --git a/llvm/test/CodeGen/RISCV/rvp-simd-32.ll b/llvm/test/CodeGen/RISCV/rvp-simd-32.ll index a490494f7a464..cfdc0141b0e1d 100644 --- a/llvm/test/CodeGen/RISCV/rvp-simd-32.ll +++ b/llvm/test/CodeGen/RISCV/rvp-simd-32.ll @@ -2681,6 +2681,61 @@ define <2 x i16> @test_pmerge_mvmn_i16x2(<2 x i16> %rs2, <2 x i16> %rs1, <2 x i1 ret <2 x i16> %res } +; Packed multiply high +define <2 x i16> @test_pmulh_v2i16(<2 x i16> %rs1, <2 x i16> %rs2) { +; CHECK-LABEL: test_pmulh_v2i16: +; CHECK: # %bb.0: +; CHECK-NEXT: pmulh.h a0, a0, a1 +; CHECK-NEXT: ret + %res = call <2 x i16> @llvm.riscv.pmulh.v2i16(<2 x i16> %rs1, <2 x i16> %rs2) + ret <2 x i16> %res +} + +define <2 x i16> @test_pmulhr_v2i16(<2 x i16> %rs1, <2 x i16> %rs2) { +; CHECK-LABEL: test_pmulhr_v2i16: +; CHECK: # %bb.0: +; CHECK-NEXT: pmulhr.h a0, a0, a1 +; CHECK-NEXT: ret + %res = call <2 x i16> @llvm.riscv.pmulhr.v2i16(<2 x i16> %rs1, <2 x i16> %rs2) + ret <2 x i16> %res +} + +define <2 x i16> @test_pmulhu_v2i16(<2 x i16> %rs1, <2 x i16> %rs2) { +; CHECK-LABEL: test_pmulhu_v2i16: +; CHECK: # %bb.0: +; CHECK-NEXT: pmulhu.h a0, a0, a1 +; CHECK-NEXT: ret + %res = call <2 x i16> @llvm.riscv.pmulhu.v2i16(<2 x i16> %rs1, <2 x i16> %rs2) + ret <2 x i16> %res +} + +define <2 x i16> @test_pmulhru_v2i16(<2 x i16> %rs1, <2 x i16> %rs2) { +; CHECK-LABEL: test_pmulhru_v2i16: +; CHECK: # %bb.0: +; CHECK-NEXT: pmulhru.h a0, a0, a1 +; CHECK-NEXT: ret + %res = call <2 x i16> @llvm.riscv.pmulhru.v2i16(<2 x i16> %rs1, <2 x i16> %rs2) + ret <2 x i16> %res +} + +define <2 x i16> @test_pmulhsu_v2i16(<2 x i16> %rs1, <2 x i16> %rs2) { +; CHECK-LABEL: test_pmulhsu_v2i16: +; CHECK: # %bb.0: +; CHECK-NEXT: pmulhsu.h a0, a0, a1 +; CHECK-NEXT: ret + %res = call <2 x i16> @llvm.riscv.pmulhsu.v2i16(<2 x i16> %rs1, <2 x i16> %rs2) + ret <2 x i16> %res +} + +define <2 x i16> @test_pmulhrsu_v2i16(<2 x i16> %rs1, <2 x i16> %rs2) { +; CHECK-LABEL: test_pmulhrsu_v2i16: +; CHECK: # %bb.0: +; CHECK-NEXT: pmulhrsu.h a0, a0, a1 +; CHECK-NEXT: ret + %res = call <2 x i16> @llvm.riscv.pmulhrsu.v2i16(<2 x i16> %rs1, <2 x i16> %rs2) + ret <2 x i16> %res +} + ; Packed absolute difference sum define i32 @test_pabdsumu_u8x4_u32(<4 x i8> %a, <4 x i8> %b) { ; RV32-LABEL: test_pabdsumu_u8x4_u32: diff --git a/llvm/test/CodeGen/RISCV/rvp-simd-64.ll b/llvm/test/CodeGen/RISCV/rvp-simd-64.ll index f49d66019458d..2eeabe8fcee10 100644 --- a/llvm/test/CodeGen/RISCV/rvp-simd-64.ll +++ b/llvm/test/CodeGen/RISCV/rvp-simd-64.ll @@ -5892,6 +5892,187 @@ define <2 x i32> @test_pmerge_mvmn_i32x2(<2 x i32> %rs2, <2 x i32> %rs1, <2 x i3 ret <2 x i32> %res } +; Packed multiply high +define <4 x i16> @test_pmulh_v4i16(<4 x i16> %rs1, <4 x i16> %rs2) { +; RV32-LABEL: test_pmulh_v4i16: +; RV32: # %bb.0: +; RV32-NEXT: pmulh.h a1, a1, a3 +; RV32-NEXT: pmulh.h a0, a0, a2 +; RV32-NEXT: ret +; +; RV64-LABEL: test_pmulh_v4i16: +; RV64: # %bb.0: +; RV64-NEXT: pmulh.h a0, a0, a1 +; RV64-NEXT: ret + %res = call <4 x i16> @llvm.riscv.pmulh.v4i16(<4 x i16> %rs1, <4 x i16> %rs2) + ret <4 x i16> %res +} + +define <4 x i16> @test_pmulhr_v4i16(<4 x i16> %rs1, <4 x i16> %rs2) { +; RV32-LABEL: test_pmulhr_v4i16: +; RV32: # %bb.0: +; RV32-NEXT: pmulhr.h a1, a1, a3 +; RV32-NEXT: pmulhr.h a0, a0, a2 +; RV32-NEXT: ret +; +; RV64-LABEL: test_pmulhr_v4i16: +; RV64: # %bb.0: +; RV64-NEXT: pmulhr.h a0, a0, a1 +; RV64-NEXT: ret + %res = call <4 x i16> @llvm.riscv.pmulhr.v4i16(<4 x i16> %rs1, <4 x i16> %rs2) + ret <4 x i16> %res +} + +define <4 x i16> @test_pmulhu_v4i16(<4 x i16> %rs1, <4 x i16> %rs2) { +; RV32-LABEL: test_pmulhu_v4i16: +; RV32: # %bb.0: +; RV32-NEXT: pmulhu.h a1, a1, a3 +; RV32-NEXT: pmulhu.h a0, a0, a2 +; RV32-NEXT: ret +; +; RV64-LABEL: test_pmulhu_v4i16: +; RV64: # %bb.0: +; RV64-NEXT: pmulhu.h a0, a0, a1 +; RV64-NEXT: ret + %res = call <4 x i16> @llvm.riscv.pmulhu.v4i16(<4 x i16> %rs1, <4 x i16> %rs2) + ret <4 x i16> %res +} + +define <4 x i16> @test_pmulhru_v4i16(<4 x i16> %rs1, <4 x i16> %rs2) { +; RV32-LABEL: test_pmulhru_v4i16: +; RV32: # %bb.0: +; RV32-NEXT: pmulhru.h a1, a1, a3 +; RV32-NEXT: pmulhru.h a0, a0, a2 +; RV32-NEXT: ret +; +; RV64-LABEL: test_pmulhru_v4i16: +; RV64: # %bb.0: +; RV64-NEXT: pmulhru.h a0, a0, a1 +; RV64-NEXT: ret + %res = call <4 x i16> @llvm.riscv.pmulhru.v4i16(<4 x i16> %rs1, <4 x i16> %rs2) + ret <4 x i16> %res +} + +define <4 x i16> @test_pmulhsu_v4i16(<4 x i16> %rs1, <4 x i16> %rs2) { +; RV32-LABEL: test_pmulhsu_v4i16: +; RV32: # %bb.0: +; RV32-NEXT: pmulhsu.h a1, a1, a3 +; RV32-NEXT: pmulhsu.h a0, a0, a2 +; RV32-NEXT: ret +; +; RV64-LABEL: test_pmulhsu_v4i16: +; RV64: # %bb.0: +; RV64-NEXT: pmulhsu.h a0, a0, a1 +; RV64-NEXT: ret + %res = call <4 x i16> @llvm.riscv.pmulhsu.v4i16(<4 x i16> %rs1, <4 x i16> %rs2) + ret <4 x i16> %res +} + +define <4 x i16> @test_pmulhrsu_v4i16(<4 x i16> %rs1, <4 x i16> %rs2) { +; RV32-LABEL: test_pmulhrsu_v4i16: +; RV32: # %bb.0: +; RV32-NEXT: pmulhrsu.h a1, a1, a3 +; RV32-NEXT: pmulhrsu.h a0, a0, a2 +; RV32-NEXT: ret +; +; RV64-LABEL: test_pmulhrsu_v4i16: +; RV64: # %bb.0: +; RV64-NEXT: pmulhrsu.h a0, a0, a1 +; RV64-NEXT: ret + %res = call <4 x i16> @llvm.riscv.pmulhrsu.v4i16(<4 x i16> %rs1, <4 x i16> %rs2) + ret <4 x i16> %res +} + +define <2 x i32> @test_pmulh_v2i32(<2 x i32> %rs1, <2 x i32> %rs2) { +; RV32-LABEL: test_pmulh_v2i32: +; RV32: # %bb.0: +; RV32-NEXT: mulh a1, a1, a3 +; RV32-NEXT: mulh a0, a0, a2 +; RV32-NEXT: ret +; +; RV64-LABEL: test_pmulh_v2i32: +; RV64: # %bb.0: +; RV64-NEXT: pmulh.w a0, a0, a1 +; RV64-NEXT: ret + %res = call <2 x i32> @llvm.riscv.pmulh.v2i32(<2 x i32> %rs1, <2 x i32> %rs2) + ret <2 x i32> %res +} + +define <2 x i32> @test_pmulhr_v2i32(<2 x i32> %rs1, <2 x i32> %rs2) { +; RV32-LABEL: test_pmulhr_v2i32: +; RV32: # %bb.0: +; RV32-NEXT: mulhr a1, a1, a3 +; RV32-NEXT: mulhr a0, a0, a2 +; RV32-NEXT: ret +; +; RV64-LABEL: test_pmulhr_v2i32: +; RV64: # %bb.0: +; RV64-NEXT: pmulhr.w a0, a0, a1 +; RV64-NEXT: ret + %res = call <2 x i32> @llvm.riscv.pmulhr.v2i32(<2 x i32> %rs1, <2 x i32> %rs2) + ret <2 x i32> %res +} + +define <2 x i32> @test_pmulhu_v2i32(<2 x i32> %rs1, <2 x i32> %rs2) { +; RV32-LABEL: test_pmulhu_v2i32: +; RV32: # %bb.0: +; RV32-NEXT: mulhu a1, a1, a3 +; RV32-NEXT: mulhu a0, a0, a2 +; RV32-NEXT: ret +; +; RV64-LABEL: test_pmulhu_v2i32: +; RV64: # %bb.0: +; RV64-NEXT: pmulhu.w a0, a0, a1 +; RV64-NEXT: ret + %res = call <2 x i32> @llvm.riscv.pmulhu.v2i32(<2 x i32> %rs1, <2 x i32> %rs2) + ret <2 x i32> %res +} + +define <2 x i32> @test_pmulhru_v2i32(<2 x i32> %rs1, <2 x i32> %rs2) { +; RV32-LABEL: test_pmulhru_v2i32: +; RV32: # %bb.0: +; RV32-NEXT: mulhru a1, a1, a3 +; RV32-NEXT: mulhru a0, a0, a2 +; RV32-NEXT: ret +; +; RV64-LABEL: test_pmulhru_v2i32: +; RV64: # %bb.0: +; RV64-NEXT: pmulhru.w a0, a0, a1 +; RV64-NEXT: ret + %res = call <2 x i32> @llvm.riscv.pmulhru.v2i32(<2 x i32> %rs1, <2 x i32> %rs2) + ret <2 x i32> %res +} + +define <2 x i32> @test_pmulhsu_v2i32(<2 x i32> %rs1, <2 x i32> %rs2) { +; RV32-LABEL: test_pmulhsu_v2i32: +; RV32: # %bb.0: +; RV32-NEXT: mulhsu a1, a1, a3 +; RV32-NEXT: mulhsu a0, a0, a2 +; RV32-NEXT: ret +; +; RV64-LABEL: test_pmulhsu_v2i32: +; RV64: # %bb.0: +; RV64-NEXT: pmulhsu.w a0, a0, a1 +; RV64-NEXT: ret + %res = call <2 x i32> @llvm.riscv.pmulhsu.v2i32(<2 x i32> %rs1, <2 x i32> %rs2) + ret <2 x i32> %res +} + +define <2 x i32> @test_pmulhrsu_v2i32(<2 x i32> %rs1, <2 x i32> %rs2) { +; RV32-LABEL: test_pmulhrsu_v2i32: +; RV32: # %bb.0: +; RV32-NEXT: mulhrsu a1, a1, a3 +; RV32-NEXT: mulhrsu a0, a0, a2 +; RV32-NEXT: ret +; +; RV64-LABEL: test_pmulhrsu_v2i32: +; RV64: # %bb.0: +; RV64-NEXT: pmulhrsu.w a0, a0, a1 +; RV64-NEXT: ret + %res = call <2 x i32> @llvm.riscv.pmulhrsu.v2i32(<2 x i32> %rs1, <2 x i32> %rs2) + ret <2 x i32> %res +} + ; Packed absolute difference sum define i32 @test_pabdsumu_u8x8_u32(<8 x i8> %a, <8 x i8> %b) { ; RV32-LABEL: test_pabdsumu_u8x8_u32: _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
