================
@@ -6352,11 +6352,69 @@ SDValue 
RISCVTargetLowering::lowerVECTOR_SHUFFLE(SDValue Op,
   unsigned NumElts = VT.getVectorNumElements();
   ShuffleVectorSDNode *SVN = cast<ShuffleVectorSDNode>(Op.getNode());
 
-  // Select an element reverse shuffle to VECTOR_REVERSE 
(rev8/rev16/ppairoe.*).
+  // Select RVP-specific packed shuffles before falling back to the generic
+  // fixed/scalable-vector lowering below.
   if (Subtarget.hasStdExtP() && !Subtarget.hasVInstructions()) {
+    ArrayRef<int> Mask = SVN->getMask();
+
+    // Match the IR produced by the packed widening high-half convert header
+    // intrinsics:
+    //   shufflevector zeroinitializer, src, <0, N, 1, N+1, ...>
+    //   bitcast to the widened vector type
+    // This places each source element in the high half of the widened element.
+    // Lower it to PZIP with a zero first operand and let tablegen select
+    // pwcvth.* via zip*p/wzip*p.
+    auto IsBuildVectorAllZeros = [](SDValue V) {
+      if (V.getOpcode() == ISD::BUILD_VECTOR)
+        return ISD::isBuildVectorAllZeros(V.getNode());
+      return V.getOpcode() == ISD::SPLAT_VECTOR &&
+             isNullConstant(V.getOperand(0));
+    };
+
+    auto IsWidenHighMask = [&](unsigned SrcNumElts) {
+      for (unsigned I = 0; I != SrcNumElts; ++I)
+        if (Mask[2 * I] != (int)I || Mask[2 * I + 1] != (int)(NumElts + I))
+          return false;
+      return true;
+    };
+    auto GetZeroVector = [&]() { return DAG.getConstant(0, DL, VT); };
+
+    SDValue Src = V2;
+    if (V2.getOpcode() == ISD::CONCAT_VECTORS && V2.getOperand(1).isUndef())
+      Src = V2.getOperand(0);
+    MVT SrcVT = Src.getSimpleValueType();
+    if (IsBuildVectorAllZeros(V1) && SrcVT.isFixedLengthVector() &&
+        SrcVT.getVectorNumElements() * 2 == NumElts &&
+        V2.getSimpleValueType().getVectorNumElements() == NumElts) {
+      unsigned SrcNumElts = SrcVT.getVectorNumElements();
+      if (IsWidenHighMask(SrcNumElts) &&
+          (SrcVT == MVT::v4i8 || SrcVT == MVT::v2i16)) {
+        if (Subtarget.is64Bit()) {
+          MVT WideSrcVT = SrcVT == MVT::v4i8 ? MVT::v8i8 : MVT::v4i16;
+          SDValue WideSrc = DAG.getNode(ISD::ZERO_EXTEND, DL, MVT::i64,
+                                        DAG.getBitcast(MVT::i32, Src));
----------------
Michael-Chen-NJU wrote:

I removed the RV64 path that used MVT::i32. The v4i8/v2i16 source form is now 
handled only for RV32; RV64 uses the already-legal v8i8/v4i16 form and lowers 
that to PZIP(zero, src). 

https://github.com/llvm/llvm-project/pull/208394
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to