[clang] [llvm] [RISCV][P-ext] Support Packed Multiply High Parts (PR #225015)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 22 00:54:41 PDT 2026
================
@@ -13214,6 +13289,77 @@ SDValue RISCVTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op,
return DAG.getNode(MulOpc, DL, VT, Rd, Rs1, Rs2);
}
+ case Intrinsic::riscv_pmulh_b0:
+ case Intrinsic::riscv_pmulh_b1:
+ case Intrinsic::riscv_pmulhsu_b0:
+ case Intrinsic::riscv_pmulhsu_b1: {
+ EVT VT = Op.getValueType();
+ SDValue Rs1 = Op.getOperand(1);
+ SDValue Rs2 = Op.getOperand(2);
+ unsigned Opc = getRVPMulHighPartsOpcode(IntNo);
+
+ // RV32 has no single instruction for a 64-bit packed multiply-high parts.
+ // Split v4i16 into two v2i16 packed operations.
+ if (!Subtarget.is64Bit() && VT == MVT::v4i16) {
+ auto [Rs1Lo, Rs1Hi] = DAG.SplitVector(Rs1, DL);
+ auto [Rs2Lo, Rs2Hi] = DAG.SplitVector(Rs2, DL);
+ SDValue Lo = DAG.getNode(Opc, DL, MVT::v2i16, Rs1Lo, Rs2Lo);
+ SDValue Hi = DAG.getNode(Opc, DL, MVT::v2i16, Rs1Hi, Rs2Hi);
+ return DAG.getNode(ISD::CONCAT_VECTORS, DL, VT, Lo, Hi);
+ }
+
+ return DAG.getNode(Opc, DL, VT, Rs1, Rs2);
+ }
+ case Intrinsic::riscv_pmulh_h0:
+ case Intrinsic::riscv_pmulh_h1:
+ case Intrinsic::riscv_pmulhsu_h0:
+ case Intrinsic::riscv_pmulhsu_h1: {
+ EVT VT = Op.getValueType();
+ SDValue Rs1 = Op.getOperand(1);
+ SDValue Rs2 = Op.getOperand(2);
+ unsigned Opc = getRVPMulHighPartsWOpcode(IntNo);
+
+ // RV32 has no single instruction for a 64-bit packed word multiply-high
+ // parts. Split v2i32 into two scalar i32 operations described by the
+ // scalar intrinsic so isel can use MULH_H0/H1.
+ 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);
+ auto ToPair = [&](SDValue V) {
+ return DAG.getBitcast(XLenVT, V);
+ };
+ SDValue Id = DAG.getTargetConstant(
+ getRVPScalarMulHighPartsIntrinsic(IntNo), DL, MVT::i32);
+ SDValue Lo = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, DL, MVT::i32, Id,
+ Extract(Rs1, 0), ToPair(Rs2Lo));
----------------
TelGome wrote:
Done. The bitcast was a leftover from an earlier version where the scalar node's rs2 operand was XLenVT. With the shared profile the v2i16 half is now passed directly to the node.
https://github.com/llvm/llvm-project/pull/225015
More information about the llvm-commits
mailing list