[llvm] [RISCV][CodeGen] Add initial CodeGen support of vunzip{e,o} (PR #196024)

via llvm-commits llvm-commits at lists.llvm.org
Wed May 6 01:31:24 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-risc-v

Author: Boyao Wang (BoyaoWang430)

<details>
<summary>Changes</summary>

Add initial support for vunzip{e,o} instructions, which are included in zvzip extension.

---

Patch is 46.95 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/196024.diff


5 Files Affected:

- (modified) llvm/lib/Target/RISCV/RISCVISelLowering.cpp (+122-33) 
- (modified) llvm/lib/Target/RISCV/RISCVInstrInfoZvzip.td (+33) 
- (modified) llvm/test/CodeGen/RISCV/rvv/fixed-vectors-shuffle-deinterleave2.ll (+41-102) 
- (modified) llvm/test/CodeGen/RISCV/rvv/vector-deinterleave-fixed.ll (+22-80) 
- (modified) llvm/test/CodeGen/RISCV/rvv/vector-deinterleave.ll (+93-183) 


``````````diff
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index d126616312748..032f7ef1b1214 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -5684,6 +5684,44 @@ static SDValue lowerZvzipVZIP(SDValue Op0, SDValue Op1, const SDLoc &DL,
   return Res;
 }
 
+static SDValue lowerZvzipVUNZIP(unsigned Opc, SDValue Op, const SDLoc &DL,
+                                SelectionDAG &DAG,
+                                const RISCVSubtarget &Subtarget) {
+  assert(RISCVISD::VUNZIPE_VL == Opc || RISCVISD::VUNZIPO_VL == Opc);
+  MVT VT = Op.getSimpleValueType();
+  if (VT.getVectorMinNumElements() < 2)
+    return SDValue();
+
+  MVT IntVT = VT.changeVectorElementTypeToInteger();
+  Op = DAG.getBitcast(IntVT, Op);
+  MVT ContainerVT = IntVT;
+  if (VT.isFixedLengthVector()) {
+    ContainerVT = getContainerForFixedLengthVector(DAG, IntVT, Subtarget);
+    // For E64 with LMUL <= 1, we can't represent a smaller fractional LMUL for
+    // the result (LMUL <= 1/2 is not valid for E64). We must widen the input
+    // container to at least LMUL=2 so the result can be LMUL=1.
+    if (ContainerVT.getVectorElementType() == MVT::i64 &&
+        RISCVTargetLowering::getLMUL(ContainerVT) == RISCVVType::LMUL_1) {
+      ContainerVT = MVT::getScalableVectorVT(MVT::i64, 2);
+    }
+    Op = convertToScalableVector(ContainerVT, Op, DAG, Subtarget);
+  }
+
+  MVT ResVT = ContainerVT.getHalfNumVectorElementsVT();
+  MVT HalfVT = VT.getHalfNumVectorElementsVT();
+  MVT HalfIntVT = IntVT.getHalfNumVectorElementsVT();
+  auto [Mask, VL] = getDefaultVLOps(ResVT, ResVT, DL, DAG, Subtarget);
+  if (VT.isFixedLengthVector())
+    VL = DAG.getConstant(VT.getVectorNumElements() / 2, DL,
+                         Subtarget.getXLenVT());
+  SDValue Passthru = DAG.getUNDEF(ResVT);
+  SDValue Res = DAG.getNode(Opc, DL, ResVT, Op, Passthru, Mask, VL);
+  if (HalfIntVT.isFixedLengthVector())
+    Res = convertFromScalableVector(HalfIntVT, Res, DAG, Subtarget);
+  Res = DAG.getBitcast(HalfVT, Res);
+  return Res;
+}
+
 // Given a vector a, b, c, d return a vector Factor times longer
 // with Factor-1 undef's between elements. Ex:
 //   a, undef, b, undef, c, undef, d, undef (Factor=2, Index=0)
@@ -6373,50 +6411,82 @@ SDValue RISCVTargetLowering::lowerVECTOR_SHUFFLE(SDValue Op,
     }
   }
 
-  // If this is a deinterleave(2), try using vunzip{a,b}.  This mostly catches
-  // e64 which can't match above.
+  // If this is a deinterleave(2), try using vunzip{a,b} or vunzip{e,o}.  This
+  // mostly catches e64 which can't match above.
   unsigned Index = 0;
-  if (Subtarget.hasVendorXRivosVizip() &&
+  if ((Subtarget.hasVendorXRivosVizip() || Subtarget.hasStdExtZvzip()) &&
       ShuffleVectorInst::isDeInterleaveMaskOfFactor(Mask, 2, Index) &&
       1 < count_if(Mask, [](int Idx) { return Idx != -1; })) {
-    unsigned Opc =
-        Index == 0 ? RISCVISD::RI_VUNZIP2A_VL : RISCVISD::RI_VUNZIP2B_VL;
-    if (V2.isUndef())
-      return lowerVZIP(Opc, V1, V2, DL, DAG, Subtarget);
-    if (auto VLEN = Subtarget.getRealVLen();
-        VLEN && VT.getSizeInBits().getKnownMinValue() % *VLEN == 0)
-      return lowerVZIP(Opc, V1, V2, DL, DAG, Subtarget);
-    if (SDValue Src = foldConcatVector(V1, V2)) {
-      EVT NewVT = VT.getDoubleNumVectorElementsVT();
-      Src = DAG.getExtractSubvector(DL, NewVT, Src, 0);
-      SDValue Res =
-          lowerVZIP(Opc, Src, DAG.getUNDEF(NewVT), DL, DAG, Subtarget);
-      return DAG.getExtractSubvector(DL, VT, Res, 0);
-    }
-    // Deinterleave each source and concatenate them, or concat first, then
-    // deinterleave.
-    if (1 < count_if(Mask,
+    bool UsesBothSources =
+        1 < count_if(Mask,
                      [&Mask](int Idx) { return Idx < (int)Mask.size(); }) &&
         1 < count_if(Mask,
-                     [&Mask](int Idx) { return Idx >= (int)Mask.size(); })) {
+                     [&Mask](int Idx) { return Idx >= (int)Mask.size(); });
+
+    if (Subtarget.hasStdExtZvzip() &&
+        isLegalVTForZvzipOperand(VT, Subtarget, *this)) {
+      unsigned Opc = Index == 0 ? RISCVISD::VUNZIPE_VL : RISCVISD::VUNZIPO_VL;
+      MVT NewVT = VT.getDoubleNumVectorElementsVT();
+      if (isTypeLegal(NewVT)) {
+        SDValue Op;
+        if (V2.isUndef()) {
+          Op = DAG.getNode(ISD::CONCAT_VECTORS, DL, NewVT, V1, V2);
+        } else if (auto VLEN = Subtarget.getRealVLen();
+                   VLEN && VT.getSizeInBits().getKnownMinValue() % *VLEN == 0) {
+          Op = DAG.getNode(ISD::CONCAT_VECTORS, DL, NewVT, V1, V2);
+        } else if (SDValue Src = foldConcatVector(V1, V2)) {
+          Op = DAG.getExtractSubvector(DL, NewVT, Src, 0);
+        }
+        if (Op)
+          if (SDValue Res = lowerZvzipVUNZIP(Opc, Op, DL, DAG, Subtarget))
+            return Res;
+      }
+
+      if (UsesBothSources) {
+        SDValue Lo = lowerZvzipVUNZIP(Opc, V1, DL, DAG, Subtarget);
+        SDValue Hi = lowerZvzipVUNZIP(Opc, V2, DL, DAG, Subtarget);
+        if (Lo && Hi)
+          return DAG.getNode(ISD::CONCAT_VECTORS, DL, VT, Lo, Hi);
+      }
+    }
 
-      const unsigned EltSize = VT.getScalarSizeInBits();
-      const unsigned MinVLMAX = Subtarget.getRealMinVLen() / EltSize;
-      if (NumElts < MinVLMAX) {
-        MVT ConcatVT = VT.getDoubleNumVectorElementsVT();
-        SDValue Concat = DAG.getNode(ISD::CONCAT_VECTORS, DL, ConcatVT, V1, V2);
+    if (Subtarget.hasVendorXRivosVizip()) {
+      unsigned Opc =
+          Index == 0 ? RISCVISD::RI_VUNZIP2A_VL : RISCVISD::RI_VUNZIP2B_VL;
+      if (V2.isUndef())
+        return lowerVZIP(Opc, V1, V2, DL, DAG, Subtarget);
+      if (auto VLEN = Subtarget.getRealVLen();
+          VLEN && VT.getSizeInBits().getKnownMinValue() % *VLEN == 0)
+        return lowerVZIP(Opc, V1, V2, DL, DAG, Subtarget);
+      if (SDValue Src = foldConcatVector(V1, V2)) {
+        EVT NewVT = VT.getDoubleNumVectorElementsVT();
+        Src = DAG.getExtractSubvector(DL, NewVT, Src, 0);
         SDValue Res =
-            lowerVZIP(Opc, Concat, DAG.getUNDEF(ConcatVT), DL, DAG, Subtarget);
+            lowerVZIP(Opc, Src, DAG.getUNDEF(NewVT), DL, DAG, Subtarget);
         return DAG.getExtractSubvector(DL, VT, Res, 0);
       }
+      // Deinterleave each source and concatenate them, or concat first, then
+      // deinterleave.
+      if (UsesBothSources) {
+        const unsigned EltSize = VT.getScalarSizeInBits();
+        const unsigned MinVLMAX = Subtarget.getRealMinVLen() / EltSize;
+        if (NumElts < MinVLMAX) {
+          MVT ConcatVT = VT.getDoubleNumVectorElementsVT();
+          SDValue Concat =
+              DAG.getNode(ISD::CONCAT_VECTORS, DL, ConcatVT, V1, V2);
+          SDValue Res = lowerVZIP(Opc, Concat, DAG.getUNDEF(ConcatVT), DL, DAG,
+                                  Subtarget);
+          return DAG.getExtractSubvector(DL, VT, Res, 0);
+        }
 
-      SDValue Lo = lowerVZIP(Opc, V1, DAG.getUNDEF(VT), DL, DAG, Subtarget);
-      SDValue Hi = lowerVZIP(Opc, V2, DAG.getUNDEF(VT), DL, DAG, Subtarget);
+        SDValue Lo = lowerVZIP(Opc, V1, DAG.getUNDEF(VT), DL, DAG, Subtarget);
+        SDValue Hi = lowerVZIP(Opc, V2, DAG.getUNDEF(VT), DL, DAG, Subtarget);
 
-      MVT SubVT = VT.getHalfNumVectorElementsVT();
-      return DAG.getNode(ISD::CONCAT_VECTORS, DL, VT,
-                         DAG.getExtractSubvector(DL, SubVT, Lo, 0),
-                         DAG.getExtractSubvector(DL, SubVT, Hi, 0));
+        MVT SubVT = VT.getHalfNumVectorElementsVT();
+        return DAG.getNode(ISD::CONCAT_VECTORS, DL, VT,
+                           DAG.getExtractSubvector(DL, SubVT, Lo, 0),
+                           DAG.getExtractSubvector(DL, SubVT, Hi, 0));
+      }
     }
   }
 
@@ -12746,6 +12816,25 @@ SDValue RISCVTargetLowering::lowerVECTOR_DEINTERLEAVE(SDValue Op,
     return DAG.getMergeValues(Res, DL);
   }
 
+  if (Subtarget.hasStdExtZvzip() && Factor == 2) {
+    MVT VT = Op->getSimpleValueType(0);
+    MVT NewVT = VT.getDoubleNumVectorElementsVT();
+    if (isTypeLegal(NewVT) && isLegalVTForZvzipOperand(VT, Subtarget, *this)) {
+      SDValue V1 = Op->getOperand(0);
+      SDValue V2 = Op->getOperand(1);
+      // Freeze the sources so we can increase their use count.
+      V1 = DAG.getFreeze(V1);
+      V2 = DAG.getFreeze(V2);
+      SDValue V = DAG.getNode(ISD::CONCAT_VECTORS, DL, NewVT, V1, V2);
+      SDValue Even =
+          lowerZvzipVUNZIP(RISCVISD::VUNZIPE_VL, V, DL, DAG, Subtarget);
+      SDValue Odd =
+          lowerZvzipVUNZIP(RISCVISD::VUNZIPO_VL, V, DL, DAG, Subtarget);
+      if (Even && Odd)
+        return DAG.getMergeValues({Even, Odd}, DL);
+    }
+  }
+
   if (Subtarget.hasVendorXRivosVizip() && Factor == 2) {
     MVT VT = Op->getSimpleValueType(0);
     SDValue V1 = Op->getOperand(0);
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZvzip.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZvzip.td
index 5f650f3cd06ea..70958ee6f0950 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoZvzip.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZvzip.td
@@ -148,6 +148,14 @@ def SDT_RISCVZip_VL : SDTypeProfile<1, 5, [SDTCisVec<0>, SDTCisVec<1>,
                                            SDTCisSameNumEltsAs<1, 4>,
                                            SDTCisVT<5, XLenVT>]>;
 
+// (vd (op vs2, passthru, mask, vl))
+def SDT_RISCVUnzip_VL : SDTypeProfile<1, 4, [SDTCisVec<0>, SDTCisVec<1>,
+                                             SDTCisSubVecOfVec<0, 1>,
+                                             SDTCisSameAs<0, 2>,
+                                             SDTCVecEltisVT<3, i1>,
+                                             SDTCisSameNumEltsAs<0, 3>,
+                                             SDTCisVT<4, XLenVT>]>;
+
 def SDT_RISCVVecBinOp_VL : SDTypeProfile<1, 5, [SDTCisSameAs<0, 1>,
                                                 SDTCisSameAs<0, 2>,
                                                 SDTCisVec<0>,
@@ -160,6 +168,8 @@ let HasPassthruOp = true, HasMaskOp = true in {
 def vpaire_vl  : RVSDNode<"VPAIRE_VL", SDT_RISCVVecBinOp_VL>;
 def vpairo_vl  : RVSDNode<"VPAIRO_VL", SDT_RISCVVecBinOp_VL>;
 def vzip_vl    : RVSDNode<"VZIP_VL", SDT_RISCVZip_VL>;
+def vunzipe_vl : RVSDNode<"VUNZIPE_VL", SDT_RISCVUnzip_VL>;
+def vunzipo_vl : RVSDNode<"VUNZIPO_VL", SDT_RISCVUnzip_VL>;
 } // HasPassthruOp = true, HasMaskOp = true
 
 multiclass VPatVZIP<SDPatternOperator vop, string instruction_name> {
@@ -176,7 +186,30 @@ multiclass VPatVZIP<SDPatternOperator vop, string instruction_name> {
   }
 }
 
+multiclass VPatVUNZIP<SDPatternOperator op, string instruction_name> {
+  foreach VtiToWti = AllZvzipVectors in {
+    defvar vti = VtiToWti.Vti;
+    defvar wti = VtiToWti.Wti;
+    let Predicates = !listconcat([HasStdExtZvzip],
+                                 GetVTypeMinimalPredicates<vti>.Predicates) in {
+      def : Pat<(vti.Vector (op (wti.Vector wti.RegClass:$rs2),
+                                (vti.Vector vti.RegClass:$passthru),
+                                (vti.Mask VMV0:$vm),
+                                VLOpFrag)),
+                (!cast<Instruction>(instruction_name#"_V_"#vti.LMul.MX#"_MASK")
+                  vti.RegClass:$passthru,
+                  wti.RegClass:$rs2,
+                  (vti.Mask VMV0:$vm),
+                  GPR:$vl,
+                  vti.Log2SEW,
+                  TAIL_AGNOSTIC)>;
+    }
+  }
+}
+
 defm : VPatVZIP<vzip_vl, "PseudoVZIP">;
+defm : VPatVUNZIP<vunzipe_vl, "PseudoVUNZIPE">;
+defm : VPatVUNZIP<vunzipo_vl, "PseudoVUNZIPO">;
 defm : VPatBinaryVL_VV<vpaire_vl, "PseudoVPAIRE", AllVectors,
                        ExtraPreds = [HasStdExtZvzip],
                        requireMinimal = true>;
diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-shuffle-deinterleave2.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-shuffle-deinterleave2.ll
index 6ebb2f51b4f2a..5005876de9369 100644
--- a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-shuffle-deinterleave2.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-shuffle-deinterleave2.ll
@@ -519,9 +519,8 @@ define void @vnsrl_0_i64(ptr %in, ptr %out) {
 ; ZVZIP-NEXT:    vsetivli zero, 4, e64, m1, ta, ma
 ; ZVZIP-NEXT:    vle64.v v8, (a0)
 ; ZVZIP-NEXT:    vsetivli zero, 2, e64, m1, ta, ma
-; ZVZIP-NEXT:    vslidedown.vi v9, v8, 2
-; ZVZIP-NEXT:    vslideup.vi v8, v9, 1
-; ZVZIP-NEXT:    vse64.v v8, (a1)
+; ZVZIP-NEXT:    vunzipe.v v10, v8
+; ZVZIP-NEXT:    vse64.v v10, (a1)
 ; ZVZIP-NEXT:    ret
 entry:
   %0 = load <4 x i64>, ptr %in, align 8
@@ -564,8 +563,7 @@ define void @vnsrl_64_i64(ptr %in, ptr %out) {
 ; ZVZIP-NEXT:    vsetivli zero, 4, e64, m1, ta, ma
 ; ZVZIP-NEXT:    vle64.v v8, (a0)
 ; ZVZIP-NEXT:    vsetivli zero, 2, e64, m1, ta, ma
-; ZVZIP-NEXT:    vslidedown.vi v9, v8, 2
-; ZVZIP-NEXT:    vpairo.vv v10, v8, v9
+; ZVZIP-NEXT:    vunzipo.v v10, v8
 ; ZVZIP-NEXT:    vse64.v v10, (a1)
 ; ZVZIP-NEXT:    ret
 entry:
@@ -608,9 +606,8 @@ define void @vnsrl_0_double(ptr %in, ptr %out) {
 ; ZVZIP-NEXT:    vsetivli zero, 4, e64, m1, ta, ma
 ; ZVZIP-NEXT:    vle64.v v8, (a0)
 ; ZVZIP-NEXT:    vsetivli zero, 2, e64, m1, ta, ma
-; ZVZIP-NEXT:    vslidedown.vi v9, v8, 2
-; ZVZIP-NEXT:    vslideup.vi v8, v9, 1
-; ZVZIP-NEXT:    vse64.v v8, (a1)
+; ZVZIP-NEXT:    vunzipe.v v10, v8
+; ZVZIP-NEXT:    vse64.v v10, (a1)
 ; ZVZIP-NEXT:    ret
 entry:
   %0 = load <4 x double>, ptr %in, align 8
@@ -653,8 +650,7 @@ define void @vnsrl_64_double(ptr %in, ptr %out) {
 ; ZVZIP-NEXT:    vsetivli zero, 4, e64, m1, ta, ma
 ; ZVZIP-NEXT:    vle64.v v8, (a0)
 ; ZVZIP-NEXT:    vsetivli zero, 2, e64, m1, ta, ma
-; ZVZIP-NEXT:    vslidedown.vi v9, v8, 2
-; ZVZIP-NEXT:    vpairo.vv v10, v8, v9
+; ZVZIP-NEXT:    vunzipo.v v10, v8
 ; ZVZIP-NEXT:    vse64.v v10, (a1)
 ; ZVZIP-NEXT:    ret
 entry:
@@ -1904,14 +1900,13 @@ define <4 x i64> @unzip2a_dual_v4i64(<4 x i64> %a, <4 x i64> %b) {
 ;
 ; ZVZIP-LABEL: unzip2a_dual_v4i64:
 ; ZVZIP:       # %bb.0: # %entry
-; ZVZIP-NEXT:    vsetivli zero, 4, e64, m1, ta, mu
-; ZVZIP-NEXT:    vmv.v.i v0, 8
-; ZVZIP-NEXT:    vslideup.vi v10, v9, 2
-; ZVZIP-NEXT:    vslideup.vi v10, v9, 1, v0.t
-; ZVZIP-NEXT:    vmv.v.i v0, 2
-; ZVZIP-NEXT:    vslidedown.vi v8, v8, 1, v0.t
-; ZVZIP-NEXT:    vmv.v.i v0, 12
-; ZVZIP-NEXT:    vmerge.vvm v8, v8, v10, v0
+; ZVZIP-NEXT:    vsetivli zero, 2, e64, m1, ta, ma
+; ZVZIP-NEXT:    vmv1r.v v10, v9
+; ZVZIP-NEXT:    vunzipe.v v12, v10
+; ZVZIP-NEXT:    vunzipe.v v10, v8
+; ZVZIP-NEXT:    vsetivli zero, 4, e64, m1, ta, ma
+; ZVZIP-NEXT:    vslideup.vi v10, v12, 2
+; ZVZIP-NEXT:    vmv.v.v v8, v10
 ; ZVZIP-NEXT:    ret
 entry:
   %c = shufflevector <4 x i64> %a, <4 x i64> %b, <4 x i32> <i32 0, i32 2, i32 4, i32 6>
@@ -2052,21 +2047,12 @@ define <16 x i64> @unzip2a_dual_v16i64(<16 x i64> %a, <16 x i64> %b) {
 ;
 ; ZVZIP-LABEL: unzip2a_dual_v16i64:
 ; ZVZIP:       # %bb.0: # %entry
-; ZVZIP-NEXT:    vsetivli zero, 16, e16, m1, ta, ma
-; ZVZIP-NEXT:    vid.v v16
-; ZVZIP-NEXT:    lui a0, 5
-; ZVZIP-NEXT:    addi a0, a0, 1365
-; ZVZIP-NEXT:    vmv.s.x v20, a0
-; ZVZIP-NEXT:    li a0, -256
-; ZVZIP-NEXT:    vadd.vv v21, v16, v16
-; ZVZIP-NEXT:    vsetvli zero, zero, e64, m4, ta, ma
-; ZVZIP-NEXT:    vcompress.vm v16, v8, v20
-; ZVZIP-NEXT:    vmv.s.x v0, a0
-; ZVZIP-NEXT:    vsetvli zero, zero, e16, m1, ta, ma
-; ZVZIP-NEXT:    vadd.vi v8, v21, -16
-; ZVZIP-NEXT:    vsetvli zero, zero, e64, m4, ta, mu
-; ZVZIP-NEXT:    vrgatherei16.vv v16, v12, v8, v0.t
-; ZVZIP-NEXT:    vmv.v.v v8, v16
+; ZVZIP-NEXT:    vsetivli zero, 8, e64, m2, ta, ma
+; ZVZIP-NEXT:    vunzipe.v v16, v12
+; ZVZIP-NEXT:    vunzipe.v v12, v8
+; ZVZIP-NEXT:    vsetivli zero, 16, e64, m4, ta, ma
+; ZVZIP-NEXT:    vslideup.vi v12, v16, 8
+; ZVZIP-NEXT:    vmv.v.v v8, v12
 ; ZVZIP-NEXT:    ret
 entry:
   %c = shufflevector <16 x i64> %a, <16 x i64> %b, <16 x i32> <i32 0, i32 2, i32 4, i32 6, i32 8, i32 10, i32 12, i32 14, i32 16, i32 18, i32 20, i32 22, i32 24, i32 26, i32 28, i32 30>
@@ -2119,14 +2105,9 @@ define <4 x i64> @unzip2a_dual_v4i64_exact(<4 x i64> %a, <4 x i64> %b) vscale_ra
 ;
 ; ZVZIP-LABEL: unzip2a_dual_v4i64_exact:
 ; ZVZIP:       # %bb.0: # %entry
-; ZVZIP-NEXT:    vsetivli zero, 4, e64, m1, ta, mu
-; ZVZIP-NEXT:    vmv.v.i v0, 8
-; ZVZIP-NEXT:    vslideup.vi v10, v9, 2
-; ZVZIP-NEXT:    vslideup.vi v10, v9, 1, v0.t
-; ZVZIP-NEXT:    vmv.v.i v0, 2
-; ZVZIP-NEXT:    vslidedown.vi v8, v8, 1, v0.t
-; ZVZIP-NEXT:    vmv.v.i v0, 12
-; ZVZIP-NEXT:    vmerge.vvm v8, v8, v10, v0
+; ZVZIP-NEXT:    vsetivli zero, 4, e64, m1, ta, ma
+; ZVZIP-NEXT:    vunzipe.v v10, v8
+; ZVZIP-NEXT:    vmv.v.v v8, v10
 ; ZVZIP-NEXT:    ret
 entry:
   %c = shufflevector <4 x i64> %a, <4 x i64> %b, <4 x i32> <i32 0, i32 2, i32 4, i32 6>
@@ -2180,14 +2161,13 @@ define <4 x i64> @unzip2a_dual_v4i64_exact_nf2(<4 x i64> %a, <4 x i64> %b) vscal
 ;
 ; ZVZIP-LABEL: unzip2a_dual_v4i64_exact_nf2:
 ; ZVZIP:       # %bb.0: # %entry
-; ZVZIP-NEXT:    vsetivli zero, 4, e64, m1, ta, mu
-; ZVZIP-NEXT:    vmv.v.i v0, 8
-; ZVZIP-NEXT:    vslideup.vi v10, v9, 2
-; ZVZIP-NEXT:    vslideup.vi v10, v9, 1, v0.t
-; ZVZIP-NEXT:    vmv.v.i v0, 2
-; ZVZIP-NEXT:    vslidedown.vi v8, v8, 1, v0.t
-; ZVZIP-NEXT:    vmv.v.i v0, 12
-; ZVZIP-NEXT:    vmerge.vvm v8, v8, v10, v0
+; ZVZIP-NEXT:    vsetivli zero, 2, e64, m1, ta, ma
+; ZVZIP-NEXT:    vmv1r.v v10, v9
+; ZVZIP-NEXT:    vunzipe.v v12, v10
+; ZVZIP-NEXT:    vunzipe.v v10, v8
+; ZVZIP-NEXT:    vsetivli zero, 4, e64, m1, tu, ma
+; ZVZIP-NEXT:    vslideup.vi v10, v12, 2
+; ZVZIP-NEXT:    vmv1r.v v8, v10
 ; ZVZIP-NEXT:    ret
 entry:
   %c = shufflevector <4 x i64> %a, <4 x i64> %b, <4 x i32> <i32 0, i32 2, i32 4, i32 6>
@@ -2319,42 +2299,9 @@ define <16 x i64> @unzip2a_dual_v16i64_exact(<16 x i64> %a, <16 x i64> %b) vscal
 ;
 ; ZVZIP-LABEL: unzip2a_dual_v16i64_exact:
 ; ZVZIP:       # %bb.0: # %entry
-; ZVZIP-NEXT:    vsetivli zero, 4, e64, m1, ta, mu
-; ZVZIP-NEXT:    vslideup.vi v19, v15, 2
-; ZVZIP-NEXT:    vmv.v.i v16, 8
-; ZVZIP-NEXT:    vmv.v.i v17, 2
-; ZVZIP-NEXT:    vmv.v.i v18, 12
-; ZVZIP-NEXT:    vmv.v.v v0, v16
-; ZVZIP-NEXT:    vslideup.vi v19, v15, 1, v0.t
-; ZVZIP-NEXT:    vmv.v.v v0, v17
-; ZVZIP-NEXT:    vslidedown.vi v14, v14, 1, v0.t
-; ZVZIP-NEXT:    vmv.v.v v0, v18
-; ZVZIP-NEXT:    vmerge.vvm v15, v14, v19, v0
-; ZVZIP-NEXT:    vslideup.vi v14, v13, 2
-; ZVZIP-NEXT:    vmv.v.v v0, v16
-; ZVZIP-NEXT:    vslideup.vi v14, v13, 1, v0.t
-; ZVZIP-NEXT:    vmv.v.v v0, v17
-; ZVZIP-NEXT:    vslidedown.vi v12, v12, 1, v0.t
-; ZVZIP-NEXT:    vmv.v.v v0, v18
-; ZVZIP-NEXT:    vmerge.vvm v14, v12, v14, v0
-; ZVZIP-NEXT:    vslideup.vi v12, v11, 2
-; ZVZIP-NEXT:    li a0, -256
-; ZVZIP-NEXT:    vmv.v.v v0, v16
-; ZVZIP-NEXT:    vslideup.vi v12, v11, 1, v0.t
-; ZVZIP-NEXT:    vmv.v.v v0, v17
-; ZVZIP-NEXT:    vslidedown.vi v10, v10, 1, v0.t
-; ZVZIP-NEXT:    vmv.v.v v0, v18
-; ZVZIP-NEXT:    vmerge.vvm v13, v10, v12, v0
-; ZVZIP-NEXT:    vslideup.vi v10, v9, 2
-; ZVZIP-NEXT:    vmv.v.v v0, v16
-; ZVZIP-NEXT:    vslideup.vi v10, v9, 1, v0.t
-; ZVZIP-NEXT:    vmv.v.v v0, v17
-; ZVZIP-NEXT:    vslidedown.vi v8, v8, 1, v0.t
-; ZVZIP-NEXT:    vmv.v.v v0, v18
-; ZVZIP-NEXT:    vmerge.vvm v12, v8, v10, v0
-; ZVZIP-NEXT:    vmv.s.x v0, a0
 ; ZVZIP-NEXT:    vsetivli zero, 16, e64, m4, ta, ma
-; ZVZIP-NEXT:    vmerge.vvm v8, v12, v12, v0
+; ZVZIP-NEXT:    vunzipe.v v16, v8
+; ZVZIP-NEXT:    vmv.v.v v8, v16
 ; ZVZIP-NEXT:    ret
 entry:
   %c = shufflevector <16 x i64> %a, <16 x i64> %b, <16 x i32> <i32 0, i32 2, i32 4, i32 6, i32 8, i32 10, i32 12, i32 14, i32 16, i32 18, i32 20, i32 22, i32 24, i32 26, i32 28, i32 30>
@@ -2410,15 +2357,13 @@ define <4 x i64> @unzip2b_dual_v4i64(<4 x i64> %a, <4 x i64> %b) {
 ;
 ; ZVZIP-LABEL: unzip2b_dual_v4i64:
 ; ZVZIP:       # %bb.0: # %entry
-; ZVZIP-NEXT:    vsetivli zero, 4, e64, m1, ta, mu
-; ZVZIP-NEXT:    vmv.v.i v0, 2
-; ZVZIP-NEXT:    vslidedown.vi v10, v8, 1
-; ZVZIP-NEXT:    vslidedown.vi v10, v8, 2, v0.t
-; ZVZIP-NEXT:    vmv.v.i v0, 4
-; ZVZIP-NEXT:    vmv1r.v v8, v9
-; ZVZIP-NEXT:    vslideup.vi v8, v9, 1, v0.t
-; ZVZIP-NEXT:    vmv.v.i v0, 12
-; ZVZIP-NEXT:    vmerge.vvm v8, v10, v8, v0
+; ZVZIP-NEXT:    vsetivli zero, 2, e64, m1, ta, ma
+; ZVZIP-NEXT:    vmv1r.v v10, v9
+; ZVZIP-NEXT:    vunzipo.v v12, v10
+; ZVZIP-NEXT:    vunzipo.v v10, v8
+; ZVZIP-NEXT:    vsetivli zero, 4, e64, m1, ta, ma
+; ZVZIP-NEXT:    vslideup.vi v10, v12, 2
+; ZVZIP-NEXT:    vmv.v.v v8, v10
 ; ZVZIP-NEXT:    ret
 entry:
   %c = shufflevector <4 x i64> %a, <4 x i64> %b, <4 x i3...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/196024


More information about the llvm-commits mailing list