https://github.com/StarryCSF created https://github.com/llvm/llvm-project/pull/224261
Add intrinsics, Clang builtins and SelectionDAG support for the RISC-V P multiply high accumulate with byte/halfword index operations. See https://github.com/riscv/riscv-p-spec/blob/master/P-ext-intrinsics.adoc#packed-multiply-high-parts-accumulate. The pmhacc.h.bXX forms operate on the whole register and select directly on both RV32 and RV64. The pmhacc.w.hXX forms select directly on RV64, on RV32 there is no 64-bit packed form, so the intrinsics split into a pair of scalar mhacc.h0/mhacc.h1 accumulations, one per result word. >From ad8f7a3e2976b8eb31814d07bb2a69fad13bec74 Mon Sep 17 00:00:00 2001 From: "ZhiQiang.Fan" <[email protected]> Date: Thu, 17 Sep 2026 18:31:43 +0800 Subject: [PATCH] [RISCV][P-ext] Add packed multiply high accumulate with byte/halfword index intrinsics --- clang/include/clang/Basic/BuiltinsRISCV.td | 16 ++ clang/lib/CodeGen/TargetBuiltins/RISCV.cpp | 41 +++++ clang/lib/Headers/riscv_packed_simd.h | 16 ++ .../riscv_packed_simd.c | 79 ++++++++ llvm/include/llvm/IR/IntrinsicsRISCV.td | 45 +++++ llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 97 ++++++++++ llvm/lib/Target/RISCV/RISCVInstrInfoP.td | 85 +++++++++ llvm/test/CodeGen/RISCV/rvp-simd-32.ll | 37 ++++ llvm/test/CodeGen/RISCV/rvp-simd-64.ll | 171 ++++++++++++++++++ 9 files changed, 587 insertions(+) diff --git a/clang/include/clang/Basic/BuiltinsRISCV.td b/clang/include/clang/Basic/BuiltinsRISCV.td index ee840e45a65ba..3b3b04fc36268 100644 --- a/clang/include/clang/Basic/BuiltinsRISCV.td +++ b/clang/include/clang/Basic/BuiltinsRISCV.td @@ -291,6 +291,22 @@ def pmhaccsu_i32x2 : RISCVBuiltin<"_Vector<2, int>(_Vector<2, int>, _Vector<2, i def pmhraccsu_i16x4 : RISCVBuiltin<"_Vector<4, short>(_Vector<4, short>, _Vector<4, short>, _Vector<4, unsigned short>)">; def pmhraccsu_i32x2 : RISCVBuiltin<"_Vector<2, int>(_Vector<2, int>, _Vector<2, int>, _Vector<2, unsigned int>)">; +// Packed Multiply High Accumulate with Byte Index (32-bit) +def pmhacc_b0_i16x2 : RISCVBuiltin<"_Vector<2, short>(_Vector<2, short>, _Vector<2, short>, _Vector<4, signed char>)">; +def pmhacc_b1_i16x2 : RISCVBuiltin<"_Vector<2, short>(_Vector<2, short>, _Vector<2, short>, _Vector<4, signed char>)">; +def pmhaccsu_b0_i16x2 : RISCVBuiltin<"_Vector<2, short>(_Vector<2, short>, _Vector<2, short>, _Vector<4, unsigned char>)">; +def pmhaccsu_b1_i16x2 : RISCVBuiltin<"_Vector<2, short>(_Vector<2, short>, _Vector<2, short>, _Vector<4, unsigned char>)">; + +// Packed Multiply High Accumulate with Byte/Halfword Index (64-bit) +def pmhacc_b0_i16x4 : RISCVBuiltin<"_Vector<4, short>(_Vector<4, short>, _Vector<4, short>, _Vector<8, signed char>)">; +def pmhacc_b1_i16x4 : RISCVBuiltin<"_Vector<4, short>(_Vector<4, short>, _Vector<4, short>, _Vector<8, signed char>)">; +def pmhaccsu_b0_i16x4 : RISCVBuiltin<"_Vector<4, short>(_Vector<4, short>, _Vector<4, short>, _Vector<8, unsigned char>)">; +def pmhaccsu_b1_i16x4 : RISCVBuiltin<"_Vector<4, short>(_Vector<4, short>, _Vector<4, short>, _Vector<8, unsigned char>)">; +def pmhacc_h0_i32x2 : RISCVBuiltin<"_Vector<2, int>(_Vector<2, int>, _Vector<2, int>, _Vector<4, short>)">; +def pmhacc_h1_i32x2 : RISCVBuiltin<"_Vector<2, int>(_Vector<2, int>, _Vector<2, int>, _Vector<4, short>)">; +def pmhaccsu_h0_i32x2 : RISCVBuiltin<"_Vector<2, int>(_Vector<2, int>, _Vector<2, int>, _Vector<4, unsigned short>)">; +def pmhaccsu_h1_i32x2 : RISCVBuiltin<"_Vector<2, int>(_Vector<2, int>, _Vector<2, int>, _Vector<4, unsigned short>)">; + // Packed Multiplication with Horizontal Addition (32-bit) def pm4add_i8x4 : RISCVBuiltin<"int(_Vector<4, signed char>, _Vector<4, signed char>)">; def pm2add_i16x2 : RISCVBuiltin<"int(_Vector<2, short>, _Vector<2, short>)">; diff --git a/clang/lib/CodeGen/TargetBuiltins/RISCV.cpp b/clang/lib/CodeGen/TargetBuiltins/RISCV.cpp index f99a05ce673aa..3810012fadfa1 100644 --- a/clang/lib/CodeGen/TargetBuiltins/RISCV.cpp +++ b/clang/lib/CodeGen/TargetBuiltins/RISCV.cpp @@ -1297,6 +1297,19 @@ Value *CodeGenFunction::EmitRISCVBuiltinExpr(unsigned BuiltinID, case RISCV::BI__builtin_riscv_pmhraccsu_i16x2: case RISCV::BI__builtin_riscv_pmhraccsu_i16x4: case RISCV::BI__builtin_riscv_pmhraccsu_i32x2: + // Packed Multiply High Accumulate with Byte/Halfword Index + case RISCV::BI__builtin_riscv_pmhacc_b0_i16x2: + case RISCV::BI__builtin_riscv_pmhacc_b1_i16x2: + case RISCV::BI__builtin_riscv_pmhaccsu_b0_i16x2: + case RISCV::BI__builtin_riscv_pmhaccsu_b1_i16x2: + case RISCV::BI__builtin_riscv_pmhacc_b0_i16x4: + case RISCV::BI__builtin_riscv_pmhacc_b1_i16x4: + case RISCV::BI__builtin_riscv_pmhaccsu_b0_i16x4: + case RISCV::BI__builtin_riscv_pmhaccsu_b1_i16x4: + case RISCV::BI__builtin_riscv_pmhacc_h0_i32x2: + case RISCV::BI__builtin_riscv_pmhacc_h1_i32x2: + case RISCV::BI__builtin_riscv_pmhaccsu_h0_i32x2: + case RISCV::BI__builtin_riscv_pmhaccsu_h1_i32x2: // Packed Saturating Absolute Value case RISCV::BI__builtin_riscv_psabs_i8x4: case RISCV::BI__builtin_riscv_psabs_i16x2: @@ -1474,6 +1487,34 @@ Value *CodeGenFunction::EmitRISCVBuiltinExpr(unsigned BuiltinID, case RISCV::BI__builtin_riscv_pmhraccsu_i32x2: ID = Intrinsic::riscv_pmhraccsu; break; + case RISCV::BI__builtin_riscv_pmhacc_b0_i16x2: + case RISCV::BI__builtin_riscv_pmhacc_b0_i16x4: + ID = Intrinsic::riscv_pmhacc_b0; + break; + case RISCV::BI__builtin_riscv_pmhacc_b1_i16x2: + case RISCV::BI__builtin_riscv_pmhacc_b1_i16x4: + ID = Intrinsic::riscv_pmhacc_b1; + break; + case RISCV::BI__builtin_riscv_pmhaccsu_b0_i16x2: + case RISCV::BI__builtin_riscv_pmhaccsu_b0_i16x4: + ID = Intrinsic::riscv_pmhaccsu_b0; + break; + case RISCV::BI__builtin_riscv_pmhaccsu_b1_i16x2: + case RISCV::BI__builtin_riscv_pmhaccsu_b1_i16x4: + ID = Intrinsic::riscv_pmhaccsu_b1; + break; + case RISCV::BI__builtin_riscv_pmhacc_h0_i32x2: + ID = Intrinsic::riscv_pmhacc_h0; + break; + case RISCV::BI__builtin_riscv_pmhacc_h1_i32x2: + ID = Intrinsic::riscv_pmhacc_h1; + break; + case RISCV::BI__builtin_riscv_pmhaccsu_h0_i32x2: + ID = Intrinsic::riscv_pmhaccsu_h0; + break; + case RISCV::BI__builtin_riscv_pmhaccsu_h1_i32x2: + ID = Intrinsic::riscv_pmhaccsu_h1; + 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 92320df12e988..97eadc9b92847 100644 --- a/clang/lib/Headers/riscv_packed_simd.h +++ b/clang/lib/Headers/riscv_packed_simd.h @@ -905,6 +905,22 @@ __packed_ternary_builtin_mixed(pmhaccsu_i32x2, int32x2_t, int32x2_t, uint32x2_t, __packed_ternary_builtin_mixed(pmhraccsu_i16x4, int16x4_t, int16x4_t, uint16x4_t, __builtin_riscv_pmhraccsu_i16x4) __packed_ternary_builtin_mixed(pmhraccsu_i32x2, int32x2_t, int32x2_t, uint32x2_t, __builtin_riscv_pmhraccsu_i32x2) +/* Packed Multiply High Accumulate with Byte Index (32-bit) */ +__packed_ternary_builtin_mixed(pmhacc_b0_i16x2, int16x2_t, int16x2_t, int8x4_t, __builtin_riscv_pmhacc_b0_i16x2) +__packed_ternary_builtin_mixed(pmhacc_b1_i16x2, int16x2_t, int16x2_t, int8x4_t, __builtin_riscv_pmhacc_b1_i16x2) +__packed_ternary_builtin_mixed(pmhaccsu_b0_i16x2, int16x2_t, int16x2_t, uint8x4_t, __builtin_riscv_pmhaccsu_b0_i16x2) +__packed_ternary_builtin_mixed(pmhaccsu_b1_i16x2, int16x2_t, int16x2_t, uint8x4_t, __builtin_riscv_pmhaccsu_b1_i16x2) + +/* Packed Multiply High Accumulate with Byte/Halfword Index (64-bit) */ +__packed_ternary_builtin_mixed(pmhacc_b0_i16x4, int16x4_t, int16x4_t, int8x8_t, __builtin_riscv_pmhacc_b0_i16x4) +__packed_ternary_builtin_mixed(pmhacc_b1_i16x4, int16x4_t, int16x4_t, int8x8_t, __builtin_riscv_pmhacc_b1_i16x4) +__packed_ternary_builtin_mixed(pmhaccsu_b0_i16x4, int16x4_t, int16x4_t, uint8x8_t, __builtin_riscv_pmhaccsu_b0_i16x4) +__packed_ternary_builtin_mixed(pmhaccsu_b1_i16x4, int16x4_t, int16x4_t, uint8x8_t, __builtin_riscv_pmhaccsu_b1_i16x4) +__packed_ternary_builtin_mixed(pmhacc_h0_i32x2, int32x2_t, int32x2_t, int16x4_t, __builtin_riscv_pmhacc_h0_i32x2) +__packed_ternary_builtin_mixed(pmhacc_h1_i32x2, int32x2_t, int32x2_t, int16x4_t, __builtin_riscv_pmhacc_h1_i32x2) +__packed_ternary_builtin_mixed(pmhaccsu_h0_i32x2, int32x2_t, int32x2_t, uint16x4_t, __builtin_riscv_pmhaccsu_h0_i32x2) +__packed_ternary_builtin_mixed(pmhaccsu_h1_i32x2, int32x2_t, int32x2_t, uint16x4_t, __builtin_riscv_pmhaccsu_h1_i32x2) + /* Packed Multiplication with Horizontal Addition (32-bit) */ __packed_binary_builtin_mixed(pm4add_i8x4, int32_t, int8x4_t, int8x4_t, __builtin_riscv_pm4add_i8x4) __packed_binary_builtin_mixed(pm2add_i16x2, int32_t, int16x2_t, int16x2_t, __builtin_riscv_pm2add_i16x2) 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 0cb773dd21c33..4fe1d223af16f 100644 --- a/cross-project-tests/intrinsic-header-tests/riscv_packed_simd.c +++ b/cross-project-tests/intrinsic-header-tests/riscv_packed_simd.c @@ -4404,6 +4404,85 @@ int32x2_t test_pmaccsu_h11_i32x2(int32x2_t rd, int16x4_t a, uint16x4_t b) { return __riscv_pmaccsu_h11_i32x2(rd, a, b); } +// Packed Multiply High Accumulate with Byte Index (32-bit) +// CHECK-LABEL: test_pmhacc_b0_i16x2: +// CHECK: pmhacc.h.b0 +int16x2_t test_pmhacc_b0_i16x2(int16x2_t rd, int16x2_t a, int8x4_t b) { + return __riscv_pmhacc_b0_i16x2(rd, a, b); +} + +// CHECK-LABEL: test_pmhacc_b1_i16x2: +// CHECK: pmhacc.h.b1 +int16x2_t test_pmhacc_b1_i16x2(int16x2_t rd, int16x2_t a, int8x4_t b) { + return __riscv_pmhacc_b1_i16x2(rd, a, b); +} + +// CHECK-LABEL: test_pmhaccsu_b0_i16x2: +// CHECK: pmhaccsu.h.b0 +int16x2_t test_pmhaccsu_b0_i16x2(int16x2_t rd, int16x2_t a, uint8x4_t b) { + return __riscv_pmhaccsu_b0_i16x2(rd, a, b); +} + +// CHECK-LABEL: test_pmhaccsu_b1_i16x2: +// CHECK: pmhaccsu.h.b1 +int16x2_t test_pmhaccsu_b1_i16x2(int16x2_t rd, int16x2_t a, uint8x4_t b) { + return __riscv_pmhaccsu_b1_i16x2(rd, a, b); +} + +// Packed Multiply High Accumulate with Byte Index (64-bit) +// CHECK-LABEL: test_pmhacc_b0_i16x4: +// CHECK: pmhacc.h.b0 +int16x4_t test_pmhacc_b0_i16x4(int16x4_t rd, int16x4_t a, int8x8_t b) { + return __riscv_pmhacc_b0_i16x4(rd, a, b); +} + +// CHECK-LABEL: test_pmhacc_b1_i16x4: +// CHECK: pmhacc.h.b1 +int16x4_t test_pmhacc_b1_i16x4(int16x4_t rd, int16x4_t a, int8x8_t b) { + return __riscv_pmhacc_b1_i16x4(rd, a, b); +} + +// CHECK-LABEL: test_pmhaccsu_b0_i16x4: +// CHECK: pmhaccsu.h.b0 +int16x4_t test_pmhaccsu_b0_i16x4(int16x4_t rd, int16x4_t a, uint8x8_t b) { + return __riscv_pmhaccsu_b0_i16x4(rd, a, b); +} + +// CHECK-LABEL: test_pmhaccsu_b1_i16x4: +// CHECK: pmhaccsu.h.b1 +int16x4_t test_pmhaccsu_b1_i16x4(int16x4_t rd, int16x4_t a, uint8x8_t b) { + return __riscv_pmhaccsu_b1_i16x4(rd, a, b); +} + +// Packed Multiply High Accumulate with Halfword Index (64-bit) +// CHECK-LABEL: test_pmhacc_h0_i32x2: +// RV32-COUNT-2: mhacc.h0 +// RV64: pmhacc.w.h0 +int32x2_t test_pmhacc_h0_i32x2(int32x2_t rd, int32x2_t a, int16x4_t b) { + return __riscv_pmhacc_h0_i32x2(rd, a, b); +} + +// CHECK-LABEL: test_pmhacc_h1_i32x2: +// RV32-COUNT-2: mhacc.h1 +// RV64: pmhacc.w.h1 +int32x2_t test_pmhacc_h1_i32x2(int32x2_t rd, int32x2_t a, int16x4_t b) { + return __riscv_pmhacc_h1_i32x2(rd, a, b); +} + +// CHECK-LABEL: test_pmhaccsu_h0_i32x2: +// RV32-COUNT-2: mhaccsu.h0 +// RV64: pmhaccsu.w.h0 +int32x2_t test_pmhaccsu_h0_i32x2(int32x2_t rd, int32x2_t a, uint16x4_t b) { + return __riscv_pmhaccsu_h0_i32x2(rd, a, b); +} + +// CHECK-LABEL: test_pmhaccsu_h1_i32x2: +// RV32-COUNT-2: mhaccsu.h1 +// RV64: pmhaccsu.w.h1 +int32x2_t test_pmhaccsu_h1_i32x2(int32x2_t rd, int32x2_t a, uint16x4_t b) { + return __riscv_pmhaccsu_h1_i32x2(rd, a, b); +} + // CHECK-LABEL: test_macc_w00_i64: // RV32: wmacc // RV64: macc.w00 diff --git a/llvm/include/llvm/IR/IntrinsicsRISCV.td b/llvm/include/llvm/IR/IntrinsicsRISCV.td index 09399b0ea3f36..81efdb0ee29f9 100644 --- a/llvm/include/llvm/IR/IntrinsicsRISCV.td +++ b/llvm/include/llvm/IR/IntrinsicsRISCV.td @@ -2126,6 +2126,51 @@ class RVPBinaryIntrinsic def int_riscv_pmhaccsu : RVPTernaryIntrinsic; def int_riscv_pmhraccsu : RVPTernaryIntrinsic; + // Packed Multiply High Accumulate with Byte/Halfword Index. + // The result and first two operands have the same vector type; the third + // operand's elements are half as wide (byte index for .b forms, halfword + // index for .w forms), with twice the element count. + def int_riscv_pmhacc_b0 + : DefaultAttrsIntrinsic<[llvm_anyvector_ty], + [LLVMMatchType<0>, LLVMMatchType<0>, + LLVMSubdivide2VectorType<0>], + [IntrNoMem, IntrSpeculatable]>; + def int_riscv_pmhacc_b1 + : DefaultAttrsIntrinsic<[llvm_anyvector_ty], + [LLVMMatchType<0>, LLVMMatchType<0>, + LLVMSubdivide2VectorType<0>], + [IntrNoMem, IntrSpeculatable]>; + def int_riscv_pmhaccsu_b0 + : DefaultAttrsIntrinsic<[llvm_anyvector_ty], + [LLVMMatchType<0>, LLVMMatchType<0>, + LLVMSubdivide2VectorType<0>], + [IntrNoMem, IntrSpeculatable]>; + def int_riscv_pmhaccsu_b1 + : DefaultAttrsIntrinsic<[llvm_anyvector_ty], + [LLVMMatchType<0>, LLVMMatchType<0>, + LLVMSubdivide2VectorType<0>], + [IntrNoMem, IntrSpeculatable]>; + def int_riscv_pmhacc_h0 + : DefaultAttrsIntrinsic<[llvm_anyvector_ty], + [LLVMMatchType<0>, LLVMMatchType<0>, + LLVMSubdivide2VectorType<0>], + [IntrNoMem, IntrSpeculatable]>; + def int_riscv_pmhacc_h1 + : DefaultAttrsIntrinsic<[llvm_anyvector_ty], + [LLVMMatchType<0>, LLVMMatchType<0>, + LLVMSubdivide2VectorType<0>], + [IntrNoMem, IntrSpeculatable]>; + def int_riscv_pmhaccsu_h0 + : DefaultAttrsIntrinsic<[llvm_anyvector_ty], + [LLVMMatchType<0>, LLVMMatchType<0>, + LLVMSubdivide2VectorType<0>], + [IntrNoMem, IntrSpeculatable]>; + def int_riscv_pmhaccsu_h1 + : DefaultAttrsIntrinsic<[llvm_anyvector_ty], + [LLVMMatchType<0>, LLVMMatchType<0>, + LLVMSubdivide2VectorType<0>], + [IntrNoMem, IntrSpeculatable]>; + // Packed Multiplication with Horizontal Addition. class RVPHorizontalMulIntrinsic : DefaultAttrsIntrinsic<[llvm_any_ty], diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index 69d813fbce12d..d2f059f112b0e 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -12369,6 +12369,31 @@ static unsigned getRVPMulHighAccumulateOpcode(unsigned IntNo) { } } +/// Return the multiply high accumulate by-halves node for \p IntNo. +static unsigned getRVPMulHighAccumulateByHalvesOpcode(unsigned IntNo) { + switch (IntNo) { + default: + llvm_unreachable( + "Unexpected RISC-V packed multiply high accumulate by halves intrinsic"); + case Intrinsic::riscv_pmhacc_b0: + return RISCVISD::MHACC_H_B0; + case Intrinsic::riscv_pmhacc_b1: + return RISCVISD::MHACC_H_B1; + case Intrinsic::riscv_pmhaccsu_b0: + return RISCVISD::MHACCSU_H_B0; + case Intrinsic::riscv_pmhaccsu_b1: + return RISCVISD::MHACCSU_H_B1; + case Intrinsic::riscv_pmhacc_h0: + return RISCVISD::MHACC_W_H0; + case Intrinsic::riscv_pmhacc_h1: + return RISCVISD::MHACC_W_H1; + case Intrinsic::riscv_pmhaccsu_h0: + return RISCVISD::MHACCSU_W_H0; + case Intrinsic::riscv_pmhaccsu_h1: + return RISCVISD::MHACCSU_W_H1; + } +} + static unsigned getRVPQFormatAccScalarOpcode(Intrinsic::ID IntNo) { switch (IntNo) { default: @@ -13211,6 +13236,54 @@ SDValue RISCVTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op, return DAG.getNode(MulOpc, DL, VT, Rd, Rs1, Rs2); } + case Intrinsic::riscv_pmhacc_b0: + case Intrinsic::riscv_pmhacc_b1: + case Intrinsic::riscv_pmhaccsu_b0: + case Intrinsic::riscv_pmhaccsu_b1: { + EVT VT = Op.getValueType(); + unsigned Opc = getRVPMulHighAccumulateByHalvesOpcode(IntNo); + SDValue Rd = Op.getOperand(1); + SDValue Rs1 = Op.getOperand(2); + SDValue Rs2 = Op.getOperand(3); + + // RV32: split v4i16 into two v2i16 operations + if (!Subtarget.is64Bit() && VT == MVT::v4i16) { + auto [RdLo, RdHi] = DAG.SplitVector(Rd, DL); + auto [Rs1Lo, Rs1Hi] = DAG.SplitVector(Rs1, DL); + auto [Rs2Lo, Rs2Hi] = DAG.SplitVector(Rs2, DL); + SDValue Lo = DAG.getNode(Opc, DL, MVT::v2i16, RdLo, Rs1Lo, Rs2Lo); + SDValue Hi = DAG.getNode(Opc, DL, MVT::v2i16, RdHi, Rs1Hi, Rs2Hi); + return DAG.getNode(ISD::CONCAT_VECTORS, DL, VT, Lo, Hi); + } + + return DAG.getNode(Opc, DL, VT, Rd, Rs1, Rs2); + } + case Intrinsic::riscv_pmhacc_h0: + case Intrinsic::riscv_pmhacc_h1: + case Intrinsic::riscv_pmhaccsu_h0: + case Intrinsic::riscv_pmhaccsu_h1: { + EVT VT = Op.getValueType(); + unsigned Opc = getRVPMulHighAccumulateByHalvesOpcode(IntNo); + SDValue Rd = Op.getOperand(1); + SDValue Rs1 = Op.getOperand(2); + SDValue Rs2 = Op.getOperand(3); + + // RV32 has no 64-bit packed form: split into two scalar operations, each + // accumulating one word of the result. + if (!Subtarget.is64Bit() && VT == MVT::v2i32) { + auto Extract = [&](SDValue V, unsigned Idx) { + return DAG.getExtractVectorElt(DL, MVT::i32, V, Idx); + }; + auto [Rs2Lo, Rs2Hi] = DAG.SplitVector(Rs2, DL); + SDValue Lo = DAG.getNode(Opc, DL, MVT::i32, Extract(Rd, 0), + Extract(Rs1, 0), Rs2Lo); + SDValue Hi = DAG.getNode(Opc, DL, MVT::i32, Extract(Rd, 1), + Extract(Rs1, 1), Rs2Hi); + return DAG.getNode(ISD::BUILD_VECTOR, DL, VT, Lo, Hi); + } + + return DAG.getNode(Opc, DL, VT, Rd, Rs1, Rs2); + } case Intrinsic::riscv_pm4add: case Intrinsic::riscv_pm2add: case Intrinsic::riscv_pm2add_x: @@ -17357,6 +17430,30 @@ void RISCVTargetLowering::ReplaceNodeResults(SDNode *N, Results.push_back(DAG.getExtractSubvector(DL, VT, Res, 0)); return; } + case Intrinsic::riscv_pmhacc_b0: + case Intrinsic::riscv_pmhacc_b1: + case Intrinsic::riscv_pmhaccsu_b0: + case Intrinsic::riscv_pmhaccsu_b1: { + // pmhacc.h.bXX exists only on RV32; on RV64 the v2i16 result has to + // widen to the packed v4i16 form and extract the low half. + EVT VT = N->getValueType(0); + if (!Subtarget.is64Bit() || VT != MVT::v2i16) + return; + + EVT WideVT = MVT::v4i16; + SDValue Undef = DAG.getUNDEF(VT); + SDValue Rd = + DAG.getNode(ISD::CONCAT_VECTORS, DL, WideVT, N->getOperand(1), Undef); + SDValue Rs1 = + DAG.getNode(ISD::CONCAT_VECTORS, DL, WideVT, N->getOperand(2), Undef); + // Third operand is v4i8 - expand to v8i8 + SDValue Rs2 = DAG.getNode(ISD::CONCAT_VECTORS, DL, MVT::v8i8, + N->getOperand(3), DAG.getUNDEF(MVT::v4i8)); + SDValue Res = DAG.getNode(getRVPMulHighAccumulateByHalvesOpcode(IntNo), + DL, WideVT, Rd, Rs1, Rs2); + Results.push_back(DAG.getExtractSubvector(DL, VT, Res, 0)); + return; + } case Intrinsic::riscv_pm4add: case Intrinsic::riscv_pm2add: case Intrinsic::riscv_pm2add_x: diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoP.td b/llvm/lib/Target/RISCV/RISCVInstrInfoP.td index 831a591cf6283..81ffe74cb7bb3 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoP.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoP.td @@ -2012,6 +2012,21 @@ def riscv_mhraccu : RVSDNode<"MHRACCU", SDT_RISCVSameTernary>; def riscv_mhaccsu : RVSDNode<"MHACCSU", SDT_RISCVSameTernary>; def riscv_mhraccsu : RVSDNode<"MHRACCSU", SDT_RISCVSameTernary>; +// Multiply high accumulate with byte/halfword index operations. The packed +// form's third operand has smaller elements than the result; the scalar form +// (RV32) accumulates one word of the result. +def SDT_RISCVMulHighAccumulateByHalves + : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, + SDTCisSameAs<0, 2>]>; +def riscv_mhacc_h_b0 : RVSDNode<"MHACC_H_B0", SDT_RISCVMulHighAccumulateByHalves>; +def riscv_mhacc_h_b1 : RVSDNode<"MHACC_H_B1", SDT_RISCVMulHighAccumulateByHalves>; +def riscv_mhaccsu_h_b0 : RVSDNode<"MHACCSU_H_B0", SDT_RISCVMulHighAccumulateByHalves>; +def riscv_mhaccsu_h_b1 : RVSDNode<"MHACCSU_H_B1", SDT_RISCVMulHighAccumulateByHalves>; +def riscv_mhacc_w_h0 : RVSDNode<"MHACC_W_H0", SDT_RISCVMulHighAccumulateByHalves>; +def riscv_mhacc_w_h1 : RVSDNode<"MHACC_W_H1", SDT_RISCVMulHighAccumulateByHalves>; +def riscv_mhaccsu_w_h0 : RVSDNode<"MHACCSU_W_H0", SDT_RISCVMulHighAccumulateByHalves>; +def riscv_mhaccsu_w_h1 : RVSDNode<"MHACCSU_W_H1", SDT_RISCVMulHighAccumulateByHalves>; + // Multiply packed elements and horizontally combine each adjacent group. def SDT_RISCVHorizontalMul : SDTypeProfile<1, 2, [SDTCisVec<1>, SDTCisSameAs<1, 2>]>; @@ -2980,6 +2995,40 @@ let append Predicates = [IsRV32] in { def : Pat<(XLenVT (riscv_nclipu XLenVT:$lo, XLenVT:$hi, timm:$imm)), (NCLIPIU (BuildGPRPair GPR:$lo, GPR:$hi), timm:$imm)>; + // 16-bit multiply high accumulate with byte index patterns + def : Pat<(XLenVecI16VT (riscv_mhacc_h_b0 (XLenVecI16VT GPR:$rd), + (XLenVecI16VT GPR:$rs1), + (XLenVecI8VT GPR:$rs2))), + (PMHACC_H_B0 GPR:$rd, GPR:$rs1, GPR:$rs2)>; + def : Pat<(XLenVecI16VT (riscv_mhacc_h_b1 (XLenVecI16VT GPR:$rd), + (XLenVecI16VT GPR:$rs1), + (XLenVecI8VT GPR:$rs2))), + (PMHACC_H_B1 GPR:$rd, GPR:$rs1, GPR:$rs2)>; + def : Pat<(XLenVecI16VT (riscv_mhaccsu_h_b0 (XLenVecI16VT GPR:$rd), + (XLenVecI16VT GPR:$rs1), + (XLenVecI8VT GPR:$rs2))), + (PMHACCSU_H_B0 GPR:$rd, GPR:$rs1, GPR:$rs2)>; + def : Pat<(XLenVecI16VT (riscv_mhaccsu_h_b1 (XLenVecI16VT GPR:$rd), + (XLenVecI16VT GPR:$rs1), + (XLenVecI8VT GPR:$rs2))), + (PMHACCSU_H_B1 GPR:$rd, GPR:$rs1, GPR:$rs2)>; + + // Packed multiply high accumulate with halfword index, scalar halfword + // (RV32). The packed intrinsic expands to a pair of these, one per result + // word. + def : Pat<(XLenVT (riscv_mhacc_w_h0 (XLenVT GPR:$rd), (XLenVT GPR:$rs1), + (v2i16 GPR:$rs2))), + (MHACC_H0 GPR:$rd, GPR:$rs1, GPR:$rs2)>; + def : Pat<(XLenVT (riscv_mhacc_w_h1 (XLenVT GPR:$rd), (XLenVT GPR:$rs1), + (v2i16 GPR:$rs2))), + (MHACC_H1 GPR:$rd, GPR:$rs1, GPR:$rs2)>; + def : Pat<(XLenVT (riscv_mhaccsu_w_h0 (XLenVT GPR:$rd), (XLenVT GPR:$rs1), + (v2i16 GPR:$rs2))), + (MHACCSU_H0 GPR:$rd, GPR:$rs1, GPR:$rs2)>; + def : Pat<(XLenVT (riscv_mhaccsu_w_h1 (XLenVT GPR:$rd), (XLenVT GPR:$rs1), + (v2i16 GPR:$rs2))), + (MHACCSU_H1 GPR:$rd, GPR:$rs1, GPR:$rs2)>; + // Packed "Q-format" multiply parts accumulate, scalar halfword (RV32). def : Pat<(XLenVT (riscv_mqacc_00 (XLenVT GPR:$rd), (v2i16 GPR:$rs1), (v2i16 GPR:$rs2))), @@ -3146,6 +3195,42 @@ let append Predicates = [IsRV64] in { def : PatMulPartsAcc<riscv_pmaccsu_halves_00, PMACCSU_W_H00, v2i32, v4i16>; def : PatMulPartsAcc<riscv_pmaccsu_halves_11, PMACCSU_W_H11, v2i32, v4i16>; + // Packed multiply high accumulate with byte index patterns (v4i16 form) + def : Pat<(v4i16 (riscv_mhacc_h_b0 (v4i16 GPR:$rd), + (v4i16 GPR:$rs1), + (v8i8 GPR:$rs2))), + (PMHACC_H_B0 GPR:$rd, GPR:$rs1, GPR:$rs2)>; + def : Pat<(v4i16 (riscv_mhacc_h_b1 (v4i16 GPR:$rd), + (v4i16 GPR:$rs1), + (v8i8 GPR:$rs2))), + (PMHACC_H_B1 GPR:$rd, GPR:$rs1, GPR:$rs2)>; + def : Pat<(v4i16 (riscv_mhaccsu_h_b0 (v4i16 GPR:$rd), + (v4i16 GPR:$rs1), + (v8i8 GPR:$rs2))), + (PMHACCSU_H_B0 GPR:$rd, GPR:$rs1, GPR:$rs2)>; + def : Pat<(v4i16 (riscv_mhaccsu_h_b1 (v4i16 GPR:$rd), + (v4i16 GPR:$rs1), + (v8i8 GPR:$rs2))), + (PMHACCSU_H_B1 GPR:$rd, GPR:$rs1, GPR:$rs2)>; + + // Packed multiply high accumulate with halfword index patterns + def : Pat<(v2i32 (riscv_mhacc_w_h0 (v2i32 GPR:$rd), + (v2i32 GPR:$rs1), + (v4i16 GPR:$rs2))), + (PMHACC_W_H0 GPR:$rd, GPR:$rs1, GPR:$rs2)>; + def : Pat<(v2i32 (riscv_mhacc_w_h1 (v2i32 GPR:$rd), + (v2i32 GPR:$rs1), + (v4i16 GPR:$rs2))), + (PMHACC_W_H1 GPR:$rd, GPR:$rs1, GPR:$rs2)>; + def : Pat<(v2i32 (riscv_mhaccsu_w_h0 (v2i32 GPR:$rd), + (v2i32 GPR:$rs1), + (v4i16 GPR:$rs2))), + (PMHACCSU_W_H0 GPR:$rd, GPR:$rs1, GPR:$rs2)>; + def : Pat<(v2i32 (riscv_mhaccsu_w_h1 (v2i32 GPR:$rd), + (v2i32 GPR:$rs1), + (v4i16 GPR:$rs2))), + (PMHACCSU_W_H1 GPR:$rd, GPR:$rs1, GPR:$rs2)>; + // Scalar word multiply-parts accumulate patterns. def : PatMulPartsAcc<riscv_pmacc_halves_00, MACC_W00, i64, v2i32>; def : PatMulPartsAcc<riscv_pmacc_halves_01, MACC_W01, i64, v2i32>; diff --git a/llvm/test/CodeGen/RISCV/rvp-simd-32.ll b/llvm/test/CodeGen/RISCV/rvp-simd-32.ll index e9e04eb6b5ebe..92ace541385cc 100644 --- a/llvm/test/CodeGen/RISCV/rvp-simd-32.ll +++ b/llvm/test/CodeGen/RISCV/rvp-simd-32.ll @@ -3827,3 +3827,40 @@ define i32 @test_maccsu_h11_i32(i32 %rd, <2 x i16> %a, <2 x i16> %b) { %r = call i32 @llvm.riscv.maccsu.11.i32.v2i16(i32 %rd, <2 x i16> %a, <2 x i16> %b) ret i32 %r } + +; Packed multiply high accumulate with byte index (RV32 only form) +define <2 x i16> @test_pmhacc_b0_v2i16(<2 x i16> %rd, <2 x i16> %rs1, <4 x i8> %rs2) { +; CHECK-LABEL: test_pmhacc_b0_v2i16: +; CHECK: # %bb.0: +; CHECK-NEXT: pmhacc.h.b0 a0, a1, a2 +; CHECK-NEXT: ret + %res = call <2 x i16> @llvm.riscv.pmhacc.b0.v2i16(<2 x i16> %rd, <2 x i16> %rs1, <4 x i8> %rs2) + ret <2 x i16> %res +} + +define <2 x i16> @test_pmhacc_b1_v2i16(<2 x i16> %rd, <2 x i16> %rs1, <4 x i8> %rs2) { +; CHECK-LABEL: test_pmhacc_b1_v2i16: +; CHECK: # %bb.0: +; CHECK-NEXT: pmhacc.h.b1 a0, a1, a2 +; CHECK-NEXT: ret + %res = call <2 x i16> @llvm.riscv.pmhacc.b1.v2i16(<2 x i16> %rd, <2 x i16> %rs1, <4 x i8> %rs2) + ret <2 x i16> %res +} + +define <2 x i16> @test_pmhaccsu_b0_v2i16(<2 x i16> %rd, <2 x i16> %rs1, <4 x i8> %rs2) { +; CHECK-LABEL: test_pmhaccsu_b0_v2i16: +; CHECK: # %bb.0: +; CHECK-NEXT: pmhaccsu.h.b0 a0, a1, a2 +; CHECK-NEXT: ret + %res = call <2 x i16> @llvm.riscv.pmhaccsu.b0.v2i16(<2 x i16> %rd, <2 x i16> %rs1, <4 x i8> %rs2) + ret <2 x i16> %res +} + +define <2 x i16> @test_pmhaccsu_b1_v2i16(<2 x i16> %rd, <2 x i16> %rs1, <4 x i8> %rs2) { +; CHECK-LABEL: test_pmhaccsu_b1_v2i16: +; CHECK: # %bb.0: +; CHECK-NEXT: pmhaccsu.h.b1 a0, a1, a2 +; CHECK-NEXT: ret + %res = call <2 x i16> @llvm.riscv.pmhaccsu.b1.v2i16(<2 x i16> %rd, <2 x i16> %rs1, <4 x i8> %rs2) + 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 43107137fe1fa..aeba15b3be406 100644 --- a/llvm/test/CodeGen/RISCV/rvp-simd-64.ll +++ b/llvm/test/CodeGen/RISCV/rvp-simd-64.ll @@ -7884,6 +7884,18 @@ declare i64 @llvm.riscv.maccu.01.i64.v2i32(i64, <2 x i32>, <2 x i32>) declare i64 @llvm.riscv.maccu.11.i64.v2i32(i64, <2 x i32>, <2 x i32>) declare i64 @llvm.riscv.maccsu.00.i64.v2i32(i64, <2 x i32>, <2 x i32>) declare i64 @llvm.riscv.maccsu.11.i64.v2i32(i64, <2 x i32>, <2 x i32>) +declare <2 x i16> @llvm.riscv.pmhacc.b0.v2i16(<2 x i16>, <2 x i16>, <4 x i8>) +declare <2 x i16> @llvm.riscv.pmhacc.b1.v2i16(<2 x i16>, <2 x i16>, <4 x i8>) +declare <2 x i16> @llvm.riscv.pmhaccsu.b0.v2i16(<2 x i16>, <2 x i16>, <4 x i8>) +declare <2 x i16> @llvm.riscv.pmhaccsu.b1.v2i16(<2 x i16>, <2 x i16>, <4 x i8>) +declare <4 x i16> @llvm.riscv.pmhacc.b0.v4i16(<4 x i16>, <4 x i16>, <8 x i8>) +declare <4 x i16> @llvm.riscv.pmhacc.b1.v4i16(<4 x i16>, <4 x i16>, <8 x i8>) +declare <4 x i16> @llvm.riscv.pmhaccsu.b0.v4i16(<4 x i16>, <4 x i16>, <8 x i8>) +declare <4 x i16> @llvm.riscv.pmhaccsu.b1.v4i16(<4 x i16>, <4 x i16>, <8 x i8>) +declare <2 x i32> @llvm.riscv.pmhacc.h0.v2i32(<2 x i32>, <2 x i32>, <4 x i16>) +declare <2 x i32> @llvm.riscv.pmhacc.h1.v2i32(<2 x i32>, <2 x i32>, <4 x i16>) +declare <2 x i32> @llvm.riscv.pmhaccsu.h0.v2i32(<2 x i32>, <2 x i32>, <4 x i16>) +declare <2 x i32> @llvm.riscv.pmhaccsu.h1.v2i32(<2 x i32>, <2 x i32>, <4 x i16>) define <2 x i32> @test_pmacc_h00_v2i32(<2 x i32> %rd, <4 x i16> %a, <4 x i16> %b) { ; RV32-LABEL: test_pmacc_h00_v2i32: @@ -8116,3 +8128,162 @@ define i64 @test_maccsu_w11_i64(i64 %rd, <2 x i32> %a, <2 x i32> %b) { %r = call i64 @llvm.riscv.maccsu.11.i64.v2i32(i64 %rd, <2 x i32> %a, <2 x i32> %b) ret i64 %r } + +; Packed multiply high accumulate with byte index (RV32 only form) +define <2 x i16> @test_pmhacc_b0_v2i16(<2 x i16> %rd, <2 x i16> %rs1, <4 x i8> %rs2) { +; CHECK-LABEL: test_pmhacc_b0_v2i16: +; CHECK: # %bb.0: +; CHECK-NEXT: pmhacc.h.b0 a0, a1, a2 +; CHECK-NEXT: ret + %res = call <2 x i16> @llvm.riscv.pmhacc.b0.v2i16(<2 x i16> %rd, <2 x i16> %rs1, <4 x i8> %rs2) + ret <2 x i16> %res +} + +define <2 x i16> @test_pmhacc_b1_v2i16(<2 x i16> %rd, <2 x i16> %rs1, <4 x i8> %rs2) { +; CHECK-LABEL: test_pmhacc_b1_v2i16: +; CHECK: # %bb.0: +; CHECK-NEXT: pmhacc.h.b1 a0, a1, a2 +; CHECK-NEXT: ret + %res = call <2 x i16> @llvm.riscv.pmhacc.b1.v2i16(<2 x i16> %rd, <2 x i16> %rs1, <4 x i8> %rs2) + ret <2 x i16> %res +} + +define <2 x i16> @test_pmhaccsu_b0_v2i16(<2 x i16> %rd, <2 x i16> %rs1, <4 x i8> %rs2) { +; CHECK-LABEL: test_pmhaccsu_b0_v2i16: +; CHECK: # %bb.0: +; CHECK-NEXT: pmhaccsu.h.b0 a0, a1, a2 +; CHECK-NEXT: ret + %res = call <2 x i16> @llvm.riscv.pmhaccsu.b0.v2i16(<2 x i16> %rd, <2 x i16> %rs1, <4 x i8> %rs2) + ret <2 x i16> %res +} + +define <2 x i16> @test_pmhaccsu_b1_v2i16(<2 x i16> %rd, <2 x i16> %rs1, <4 x i8> %rs2) { +; CHECK-LABEL: test_pmhaccsu_b1_v2i16: +; CHECK: # %bb.0: +; CHECK-NEXT: pmhaccsu.h.b1 a0, a1, a2 +; CHECK-NEXT: ret + %res = call <2 x i16> @llvm.riscv.pmhaccsu.b1.v2i16(<2 x i16> %rd, <2 x i16> %rs1, <4 x i8> %rs2) + ret <2 x i16> %res +} + +; Packed multiply high accumulate with byte index (packed form) +define <4 x i16> @test_pmhacc_b0_v4i16(<4 x i16> %rd, <4 x i16> %rs1, <8 x i8> %rs2) { +; RV32-LABEL: test_pmhacc_b0_v4i16: +; RV32: # %bb.0: +; RV32-NEXT: pmhacc.h.b0 a1, a3, a5 +; RV32-NEXT: pmhacc.h.b0 a0, a2, a4 +; RV32-NEXT: ret +; +; RV64-LABEL: test_pmhacc_b0_v4i16: +; RV64: # %bb.0: +; RV64-NEXT: pmhacc.h.b0 a0, a1, a2 +; RV64-NEXT: ret + %res = call <4 x i16> @llvm.riscv.pmhacc.b0.v4i16(<4 x i16> %rd, <4 x i16> %rs1, <8 x i8> %rs2) + ret <4 x i16> %res +} + +define <4 x i16> @test_pmhacc_b1_v4i16(<4 x i16> %rd, <4 x i16> %rs1, <8 x i8> %rs2) { +; RV32-LABEL: test_pmhacc_b1_v4i16: +; RV32: # %bb.0: +; RV32-NEXT: pmhacc.h.b1 a1, a3, a5 +; RV32-NEXT: pmhacc.h.b1 a0, a2, a4 +; RV32-NEXT: ret +; +; RV64-LABEL: test_pmhacc_b1_v4i16: +; RV64: # %bb.0: +; RV64-NEXT: pmhacc.h.b1 a0, a1, a2 +; RV64-NEXT: ret + %res = call <4 x i16> @llvm.riscv.pmhacc.b1.v4i16(<4 x i16> %rd, <4 x i16> %rs1, <8 x i8> %rs2) + ret <4 x i16> %res +} + +define <4 x i16> @test_pmhaccsu_b0_v4i16(<4 x i16> %rd, <4 x i16> %rs1, <8 x i8> %rs2) { +; RV32-LABEL: test_pmhaccsu_b0_v4i16: +; RV32: # %bb.0: +; RV32-NEXT: pmhaccsu.h.b0 a1, a3, a5 +; RV32-NEXT: pmhaccsu.h.b0 a0, a2, a4 +; RV32-NEXT: ret +; +; RV64-LABEL: test_pmhaccsu_b0_v4i16: +; RV64: # %bb.0: +; RV64-NEXT: pmhaccsu.h.b0 a0, a1, a2 +; RV64-NEXT: ret + %res = call <4 x i16> @llvm.riscv.pmhaccsu.b0.v4i16(<4 x i16> %rd, <4 x i16> %rs1, <8 x i8> %rs2) + ret <4 x i16> %res +} + +define <4 x i16> @test_pmhaccsu_b1_v4i16(<4 x i16> %rd, <4 x i16> %rs1, <8 x i8> %rs2) { +; RV32-LABEL: test_pmhaccsu_b1_v4i16: +; RV32: # %bb.0: +; RV32-NEXT: pmhaccsu.h.b1 a1, a3, a5 +; RV32-NEXT: pmhaccsu.h.b1 a0, a2, a4 +; RV32-NEXT: ret +; +; RV64-LABEL: test_pmhaccsu_b1_v4i16: +; RV64: # %bb.0: +; RV64-NEXT: pmhaccsu.h.b1 a0, a1, a2 +; RV64-NEXT: ret + %res = call <4 x i16> @llvm.riscv.pmhaccsu.b1.v4i16(<4 x i16> %rd, <4 x i16> %rs1, <8 x i8> %rs2) + ret <4 x i16> %res +} + +; Packed multiply high accumulate with halfword index +define <2 x i32> @test_pmhacc_h0_v2i32(<2 x i32> %rd, <2 x i32> %rs1, <4 x i16> %rs2) { +; RV32-LABEL: test_pmhacc_h0_v2i32: +; RV32: # %bb.0: +; RV32-NEXT: mhacc.h0 a1, a3, a5 +; RV32-NEXT: mhacc.h0 a0, a2, a4 +; RV32-NEXT: ret +; +; RV64-LABEL: test_pmhacc_h0_v2i32: +; RV64: # %bb.0: +; RV64-NEXT: pmhacc.w.h0 a0, a1, a2 +; RV64-NEXT: ret + %res = call <2 x i32> @llvm.riscv.pmhacc.h0.v2i32(<2 x i32> %rd, <2 x i32> %rs1, <4 x i16> %rs2) + ret <2 x i32> %res +} + +define <2 x i32> @test_pmhacc_h1_v2i32(<2 x i32> %rd, <2 x i32> %rs1, <4 x i16> %rs2) { +; RV32-LABEL: test_pmhacc_h1_v2i32: +; RV32: # %bb.0: +; RV32-NEXT: mhacc.h1 a1, a3, a5 +; RV32-NEXT: mhacc.h1 a0, a2, a4 +; RV32-NEXT: ret +; +; RV64-LABEL: test_pmhacc_h1_v2i32: +; RV64: # %bb.0: +; RV64-NEXT: pmhacc.w.h1 a0, a1, a2 +; RV64-NEXT: ret + %res = call <2 x i32> @llvm.riscv.pmhacc.h1.v2i32(<2 x i32> %rd, <2 x i32> %rs1, <4 x i16> %rs2) + ret <2 x i32> %res +} + +define <2 x i32> @test_pmhaccsu_h0_v2i32(<2 x i32> %rd, <2 x i32> %rs1, <4 x i16> %rs2) { +; RV32-LABEL: test_pmhaccsu_h0_v2i32: +; RV32: # %bb.0: +; RV32-NEXT: mhaccsu.h0 a1, a3, a5 +; RV32-NEXT: mhaccsu.h0 a0, a2, a4 +; RV32-NEXT: ret +; +; RV64-LABEL: test_pmhaccsu_h0_v2i32: +; RV64: # %bb.0: +; RV64-NEXT: pmhaccsu.w.h0 a0, a1, a2 +; RV64-NEXT: ret + %res = call <2 x i32> @llvm.riscv.pmhaccsu.h0.v2i32(<2 x i32> %rd, <2 x i32> %rs1, <4 x i16> %rs2) + ret <2 x i32> %res +} + +define <2 x i32> @test_pmhaccsu_h1_v2i32(<2 x i32> %rd, <2 x i32> %rs1, <4 x i16> %rs2) { +; RV32-LABEL: test_pmhaccsu_h1_v2i32: +; RV32: # %bb.0: +; RV32-NEXT: mhaccsu.h1 a1, a3, a5 +; RV32-NEXT: mhaccsu.h1 a0, a2, a4 +; RV32-NEXT: ret +; +; RV64-LABEL: test_pmhaccsu_h1_v2i32: +; RV64: # %bb.0: +; RV64-NEXT: pmhaccsu.w.h1 a0, a1, a2 +; RV64-NEXT: ret + %res = call <2 x i32> @llvm.riscv.pmhaccsu.h1.v2i32(<2 x i32> %rd, <2 x i32> %rs1, <4 x i16> %rs2) + ret <2 x i32> %res +} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
