[clang] [llvm] [RISCV][P-ext] Add packed multiply high accumulate with byte/halfword index intrinsics (PR #224261)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 17 04:04:35 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang-codegen
@llvm/pr-subscribers-backend-risc-v
@llvm/pr-subscribers-llvm-ir
Author: Q (StarryCSF)
<details>
<summary>Changes</summary>
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.
---
Patch is 33.41 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/224261.diff
9 Files Affected:
- (modified) clang/include/clang/Basic/BuiltinsRISCV.td (+16)
- (modified) clang/lib/CodeGen/TargetBuiltins/RISCV.cpp (+41)
- (modified) clang/lib/Headers/riscv_packed_simd.h (+16)
- (modified) cross-project-tests/intrinsic-header-tests/riscv_packed_simd.c (+79)
- (modified) llvm/include/llvm/IR/IntrinsicsRISCV.td (+45)
- (modified) llvm/lib/Target/RISCV/RISCVISelLowering.cpp (+97)
- (modified) llvm/lib/Target/RISCV/RISCVInstrInfoP.td (+85)
- (modified) llvm/test/CodeGen/RISCV/rvp-simd-32.ll (+37)
- (modified) llvm/test/CodeGen/RISCV/rvp-simd-64.ll (+171)
``````````diff
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 acc...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/224261
More information about the llvm-commits
mailing list