[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