[llvm] d7b96ba - [RISCV] Use vunzip instead of shift and truncate in the presence of Zvzip (#228298)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Oct 5 11:53:14 PDT 2026
Author: Min-Yih Hsu
Date: 2026-10-05T18:53:07Z
New Revision: d7b96ba1929d874e935546b88c78c7ed2450fb73
URL: https://github.com/llvm/llvm-project/commit/d7b96ba1929d874e935546b88c78c7ed2450fb73
DIFF: https://github.com/llvm/llvm-project/commit/d7b96ba1929d874e935546b88c78c7ed2450fb73.diff
LOG: [RISCV] Use vunzip instead of shift and truncate in the presence of Zvzip (#228298)
This patch simply hoists the vunzip generation logics inside
lowerVECTOR_SHUFFLE before the one that lowers deinterleave2 into VNSRL
(i.e. shift and truncate). The rationale behind this is that
extension-specific logics should generally happen before the generic
(RVV) cases. Plus, both of the options emit a single instruction and
it's unlikely vunzip will be slower than VNSRL.
I found this when I'm writing a DAG combine for Zvzip, so this patch
could potentially enable more Zvzip patterns in the future as well.
Added:
Modified:
llvm/lib/Target/RISCV/RISCVISelLowering.cpp
llvm/test/CodeGen/RISCV/rvv/fixed-vectors-shuffle-deinterleave2.ll
llvm/test/CodeGen/RISCV/rvv/fixed-vectors-shuffle-zvzip-zve32f.ll
llvm/test/CodeGen/RISCV/rvv/vector-deinterleave-fixed.ll
llvm/test/CodeGen/RISCV/rvv/vector-deinterleave.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 337098eae6b6d..b30cb41ef1bac 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -6928,6 +6928,46 @@ SDValue RISCVTargetLowering::lowerVECTOR_SHUFFLE(SDValue Op,
NumElts != 2)
return DAG.getNode(ISD::VECTOR_REVERSE, DL, VT, V1);
+ // Try using vunzip{e,o} from Zvzip to lower deinterleave2.
+ unsigned Index = 0;
+ if (Subtarget.hasStdExtZvzip() &&
+ ShuffleVectorInst::isDeInterleaveMaskOfFactor(Mask, 2, Index) &&
+ 1 < count_if(Mask, [](int Idx) { return Idx != -1; })) {
+ 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(); });
+
+ unsigned Opc = Index == 0 ? RISCVISD::VUNZIPE_VL : RISCVISD::VUNZIPO_VL;
+ if (isLegalVTForZvzipDeinterleavedOperand(VT, Subtarget)) {
+ 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)
+ return lowerZvzipVUNZIP(Opc, Op, DL, DAG, Subtarget);
+ }
+ }
+
+ MVT HalfVT = VT.getHalfNumVectorElementsVT();
+ if (UsesBothSources &&
+ isLegalVTForZvzipDeinterleavedOperand(HalfVT, Subtarget) &&
+ V1.getSimpleValueType().getVectorMinNumElements() >= 2 &&
+ V2.getSimpleValueType().getVectorMinNumElements() >= 2) {
+ SDValue Lo = lowerZvzipVUNZIP(Opc, V1, DL, DAG, Subtarget);
+ SDValue Hi = lowerZvzipVUNZIP(Opc, V2, DL, DAG, Subtarget);
+ return DAG.getNode(ISD::CONCAT_VECTORS, DL, VT, Lo, Hi);
+ }
+ }
+
// If this is a deinterleave(2,4,8) and we can widen the vector, then we can
// use shift and truncate to perform the shuffle.
// TODO: For Factor=6, we can perform the first step of the deinterleave via
@@ -6973,47 +7013,6 @@ SDValue RISCVTargetLowering::lowerVECTOR_SHUFFLE(SDValue Op,
}
}
- // If this is a deinterleave(2), try using vunzip{e,o}. This mostly catches
- // e64 which can't match above.
- unsigned Index = 0;
- if (Subtarget.hasStdExtZvzip() &&
- ShuffleVectorInst::isDeInterleaveMaskOfFactor(Mask, 2, Index) &&
- 1 < count_if(Mask, [](int Idx) { return Idx != -1; })) {
- 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(); });
-
- unsigned Opc = Index == 0 ? RISCVISD::VUNZIPE_VL : RISCVISD::VUNZIPO_VL;
- if (isLegalVTForZvzipDeinterleavedOperand(VT, Subtarget)) {
- 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)
- return lowerZvzipVUNZIP(Opc, Op, DL, DAG, Subtarget);
- }
- }
-
- MVT HalfVT = VT.getHalfNumVectorElementsVT();
- if (UsesBothSources &&
- isLegalVTForZvzipDeinterleavedOperand(HalfVT, Subtarget) &&
- V1.getSimpleValueType().getVectorMinNumElements() >= 2 &&
- V2.getSimpleValueType().getVectorMinNumElements() >= 2) {
- SDValue Lo = lowerZvzipVUNZIP(Opc, V1, DL, DAG, Subtarget);
- SDValue Hi = lowerZvzipVUNZIP(Opc, V2, DL, DAG, Subtarget);
- return DAG.getNode(ISD::CONCAT_VECTORS, DL, VT, Lo, Hi);
- }
- }
-
if (SDValue V =
lowerVECTOR_SHUFFLEAsVSlideup(DL, VT, V1, V2, Mask, Subtarget, DAG))
return V;
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 4678c2b07b2ca..f63237151c94e 100644
--- a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-shuffle-deinterleave2.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-shuffle-deinterleave2.ll
@@ -10,14 +10,32 @@
; RUN: | FileCheck %s --check-prefixes=CHECK,ZVZIP
define void @vnsrl_0_i8(ptr %in, ptr %out) {
-; CHECK-LABEL: vnsrl_0_i8:
-; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: vsetivli zero, 16, e8, mf2, ta, ma
-; CHECK-NEXT: vle8.v v8, (a0)
-; CHECK-NEXT: vsetivli zero, 8, e8, mf4, ta, ma
-; CHECK-NEXT: vnsrl.wi v8, v8, 0
-; CHECK-NEXT: vse8.v v8, (a1)
-; CHECK-NEXT: ret
+; V-LABEL: vnsrl_0_i8:
+; V: # %bb.0: # %entry
+; V-NEXT: vsetivli zero, 16, e8, mf2, ta, ma
+; V-NEXT: vle8.v v8, (a0)
+; V-NEXT: vsetivli zero, 8, e8, mf4, ta, ma
+; V-NEXT: vnsrl.wi v8, v8, 0
+; V-NEXT: vse8.v v8, (a1)
+; V-NEXT: ret
+;
+; ZVE32F-LABEL: vnsrl_0_i8:
+; ZVE32F: # %bb.0: # %entry
+; ZVE32F-NEXT: vsetivli zero, 16, e8, mf2, ta, ma
+; ZVE32F-NEXT: vle8.v v8, (a0)
+; ZVE32F-NEXT: vsetivli zero, 8, e8, mf4, ta, ma
+; ZVE32F-NEXT: vnsrl.wi v8, v8, 0
+; ZVE32F-NEXT: vse8.v v8, (a1)
+; ZVE32F-NEXT: ret
+;
+; ZVZIP-LABEL: vnsrl_0_i8:
+; ZVZIP: # %bb.0: # %entry
+; ZVZIP-NEXT: vsetivli zero, 16, e8, mf2, ta, ma
+; ZVZIP-NEXT: vle8.v v8, (a0)
+; ZVZIP-NEXT: vsetivli zero, 8, e8, mf4, ta, ma
+; ZVZIP-NEXT: vunzipe.v v8, v8
+; ZVZIP-NEXT: vse8.v v8, (a1)
+; ZVZIP-NEXT: ret
entry:
%0 = load <16 x i8>, ptr %in, align 1
%shuffle.i5 = shufflevector <16 x i8> %0, <16 x i8> poison, <8 x i32> <i32 0, i32 2, i32 4, i32 6, i32 8, i32 10, i32 12, i32 14>
@@ -26,14 +44,32 @@ entry:
}
define void @vnsrl_8_i8(ptr %in, ptr %out) {
-; CHECK-LABEL: vnsrl_8_i8:
-; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: vsetivli zero, 16, e8, mf2, ta, ma
-; CHECK-NEXT: vle8.v v8, (a0)
-; CHECK-NEXT: vsetivli zero, 8, e8, mf4, ta, ma
-; CHECK-NEXT: vnsrl.wi v8, v8, 8
-; CHECK-NEXT: vse8.v v8, (a1)
-; CHECK-NEXT: ret
+; V-LABEL: vnsrl_8_i8:
+; V: # %bb.0: # %entry
+; V-NEXT: vsetivli zero, 16, e8, mf2, ta, ma
+; V-NEXT: vle8.v v8, (a0)
+; V-NEXT: vsetivli zero, 8, e8, mf4, ta, ma
+; V-NEXT: vnsrl.wi v8, v8, 8
+; V-NEXT: vse8.v v8, (a1)
+; V-NEXT: ret
+;
+; ZVE32F-LABEL: vnsrl_8_i8:
+; ZVE32F: # %bb.0: # %entry
+; ZVE32F-NEXT: vsetivli zero, 16, e8, mf2, ta, ma
+; ZVE32F-NEXT: vle8.v v8, (a0)
+; ZVE32F-NEXT: vsetivli zero, 8, e8, mf4, ta, ma
+; ZVE32F-NEXT: vnsrl.wi v8, v8, 8
+; ZVE32F-NEXT: vse8.v v8, (a1)
+; ZVE32F-NEXT: ret
+;
+; ZVZIP-LABEL: vnsrl_8_i8:
+; ZVZIP: # %bb.0: # %entry
+; ZVZIP-NEXT: vsetivli zero, 16, e8, mf2, ta, ma
+; ZVZIP-NEXT: vle8.v v8, (a0)
+; ZVZIP-NEXT: vsetivli zero, 8, e8, mf4, ta, ma
+; ZVZIP-NEXT: vunzipo.v v8, v8
+; ZVZIP-NEXT: vse8.v v8, (a1)
+; ZVZIP-NEXT: ret
entry:
%0 = load <16 x i8>, ptr %in, align 1
%shuffle.i5 = shufflevector <16 x i8> %0, <16 x i8> poison, <8 x i32> <i32 1, i32 3, i32 5, i32 7, i32 9, i32 11, i32 13, i32 15>
@@ -65,7 +101,7 @@ define void @vnsrl_0_i16(ptr %in, ptr %out) {
; ZVZIP-NEXT: vsetivli zero, 8, e16, mf2, ta, ma
; ZVZIP-NEXT: vle16.v v8, (a0)
; ZVZIP-NEXT: vsetivli zero, 4, e16, mf4, ta, ma
-; ZVZIP-NEXT: vnsrl.wi v8, v8, 0
+; ZVZIP-NEXT: vunzipe.v v8, v8
; ZVZIP-NEXT: vse16.v v8, (a1)
; ZVZIP-NEXT: ret
entry:
@@ -99,7 +135,7 @@ define void @vnsrl_16_i16(ptr %in, ptr %out) {
; ZVZIP-NEXT: vsetivli zero, 8, e16, mf2, ta, ma
; ZVZIP-NEXT: vle16.v v8, (a0)
; ZVZIP-NEXT: vsetivli zero, 4, e16, mf4, ta, ma
-; ZVZIP-NEXT: vnsrl.wi v8, v8, 16
+; ZVZIP-NEXT: vunzipo.v v8, v8
; ZVZIP-NEXT: vse16.v v8, (a1)
; ZVZIP-NEXT: ret
entry:
@@ -133,7 +169,7 @@ define void @vnsrl_0_half(ptr %in, ptr %out) {
; ZVZIP-NEXT: vsetivli zero, 8, e16, mf2, ta, ma
; ZVZIP-NEXT: vle16.v v8, (a0)
; ZVZIP-NEXT: vsetivli zero, 4, e16, mf4, ta, ma
-; ZVZIP-NEXT: vnsrl.wi v8, v8, 0
+; ZVZIP-NEXT: vunzipe.v v8, v8
; ZVZIP-NEXT: vse16.v v8, (a1)
; ZVZIP-NEXT: ret
entry:
@@ -167,7 +203,7 @@ define void @vnsrl_0_bfloat(ptr %in, ptr %out) {
; ZVZIP-NEXT: vsetivli zero, 8, e16, mf2, ta, ma
; ZVZIP-NEXT: vle16.v v8, (a0)
; ZVZIP-NEXT: vsetivli zero, 4, e16, mf4, ta, ma
-; ZVZIP-NEXT: vnsrl.wi v8, v8, 0
+; ZVZIP-NEXT: vunzipe.v v8, v8
; ZVZIP-NEXT: vse16.v v8, (a1)
; ZVZIP-NEXT: ret
entry:
@@ -201,7 +237,7 @@ define void @vnsrl_16_half(ptr %in, ptr %out) {
; ZVZIP-NEXT: vsetivli zero, 8, e16, mf2, ta, ma
; ZVZIP-NEXT: vle16.v v8, (a0)
; ZVZIP-NEXT: vsetivli zero, 4, e16, mf4, ta, ma
-; ZVZIP-NEXT: vnsrl.wi v8, v8, 16
+; ZVZIP-NEXT: vunzipo.v v8, v8
; ZVZIP-NEXT: vse16.v v8, (a1)
; ZVZIP-NEXT: ret
entry:
@@ -235,7 +271,7 @@ define void @vnsrl_16_bfloat(ptr %in, ptr %out) {
; ZVZIP-NEXT: vsetivli zero, 8, e16, mf2, ta, ma
; ZVZIP-NEXT: vle16.v v8, (a0)
; ZVZIP-NEXT: vsetivli zero, 4, e16, mf4, ta, ma
-; ZVZIP-NEXT: vnsrl.wi v8, v8, 16
+; ZVZIP-NEXT: vunzipo.v v8, v8
; ZVZIP-NEXT: vse16.v v8, (a1)
; ZVZIP-NEXT: ret
entry:
@@ -270,7 +306,7 @@ define void @vnsrl_0_i32(ptr %in, ptr %out) {
; ZVZIP-NEXT: vsetivli zero, 4, e32, mf2, ta, ma
; ZVZIP-NEXT: vle32.v v8, (a0)
; ZVZIP-NEXT: vsetivli zero, 2, e32, mf2, ta, ma
-; ZVZIP-NEXT: vnsrl.wi v8, v8, 0
+; ZVZIP-NEXT: vunzipe.v v8, v8
; ZVZIP-NEXT: vse32.v v8, (a1)
; ZVZIP-NEXT: ret
entry:
@@ -306,9 +342,8 @@ define void @vnsrl_32_i32(ptr %in, ptr %out) {
; ZVZIP: # %bb.0: # %entry
; ZVZIP-NEXT: vsetivli zero, 4, e32, mf2, ta, ma
; ZVZIP-NEXT: vle32.v v8, (a0)
-; ZVZIP-NEXT: li a0, 32
; ZVZIP-NEXT: vsetivli zero, 2, e32, mf2, ta, ma
-; ZVZIP-NEXT: vnsrl.wx v8, v8, a0
+; ZVZIP-NEXT: vunzipo.v v8, v8
; ZVZIP-NEXT: vse32.v v8, (a1)
; ZVZIP-NEXT: ret
entry:
@@ -343,7 +378,7 @@ define void @vnsrl_0_float(ptr %in, ptr %out) {
; ZVZIP-NEXT: vsetivli zero, 4, e32, mf2, ta, ma
; ZVZIP-NEXT: vle32.v v8, (a0)
; ZVZIP-NEXT: vsetivli zero, 2, e32, mf2, ta, ma
-; ZVZIP-NEXT: vnsrl.wi v8, v8, 0
+; ZVZIP-NEXT: vunzipe.v v8, v8
; ZVZIP-NEXT: vse32.v v8, (a1)
; ZVZIP-NEXT: ret
entry:
@@ -379,9 +414,8 @@ define void @vnsrl_32_float(ptr %in, ptr %out) {
; ZVZIP: # %bb.0: # %entry
; ZVZIP-NEXT: vsetivli zero, 4, e32, mf2, ta, ma
; ZVZIP-NEXT: vle32.v v8, (a0)
-; ZVZIP-NEXT: li a0, 32
; ZVZIP-NEXT: vsetivli zero, 2, e32, mf2, ta, ma
-; ZVZIP-NEXT: vnsrl.wx v8, v8, a0
+; ZVZIP-NEXT: vunzipo.v v8, v8
; ZVZIP-NEXT: vse32.v v8, (a1)
; ZVZIP-NEXT: ret
entry:
@@ -530,14 +564,32 @@ entry:
}
define void @vnsrl_0_i8_undef(ptr %in, ptr %out) {
-; CHECK-LABEL: vnsrl_0_i8_undef:
-; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: vsetivli zero, 16, e8, mf2, ta, ma
-; CHECK-NEXT: vle8.v v8, (a0)
-; CHECK-NEXT: vsetivli zero, 8, e8, mf4, ta, ma
-; CHECK-NEXT: vnsrl.wi v8, v8, 0
-; CHECK-NEXT: vse8.v v8, (a1)
-; CHECK-NEXT: ret
+; V-LABEL: vnsrl_0_i8_undef:
+; V: # %bb.0: # %entry
+; V-NEXT: vsetivli zero, 16, e8, mf2, ta, ma
+; V-NEXT: vle8.v v8, (a0)
+; V-NEXT: vsetivli zero, 8, e8, mf4, ta, ma
+; V-NEXT: vnsrl.wi v8, v8, 0
+; V-NEXT: vse8.v v8, (a1)
+; V-NEXT: ret
+;
+; ZVE32F-LABEL: vnsrl_0_i8_undef:
+; ZVE32F: # %bb.0: # %entry
+; ZVE32F-NEXT: vsetivli zero, 16, e8, mf2, ta, ma
+; ZVE32F-NEXT: vle8.v v8, (a0)
+; ZVE32F-NEXT: vsetivli zero, 8, e8, mf4, ta, ma
+; ZVE32F-NEXT: vnsrl.wi v8, v8, 0
+; ZVE32F-NEXT: vse8.v v8, (a1)
+; ZVE32F-NEXT: ret
+;
+; ZVZIP-LABEL: vnsrl_0_i8_undef:
+; ZVZIP: # %bb.0: # %entry
+; ZVZIP-NEXT: vsetivli zero, 16, e8, mf2, ta, ma
+; ZVZIP-NEXT: vle8.v v8, (a0)
+; ZVZIP-NEXT: vsetivli zero, 8, e8, mf4, ta, ma
+; ZVZIP-NEXT: vunzipe.v v8, v8
+; ZVZIP-NEXT: vse8.v v8, (a1)
+; ZVZIP-NEXT: ret
entry:
%0 = load <16 x i8>, ptr %in, align 1
%shuffle.i5 = shufflevector <16 x i8> %0, <16 x i8> poison, <8 x i32> <i32 0, i32 2, i32 4, i32 6, i32 8, i32 10, i32 poison, i32 poison>
@@ -546,14 +598,32 @@ entry:
}
define void @vnsrl_0_i8_undef2(ptr %in, ptr %out) {
-; CHECK-LABEL: vnsrl_0_i8_undef2:
-; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: vsetivli zero, 16, e8, mf2, ta, ma
-; CHECK-NEXT: vle8.v v8, (a0)
-; CHECK-NEXT: vsetivli zero, 8, e8, mf4, ta, ma
-; CHECK-NEXT: vnsrl.wi v8, v8, 0
-; CHECK-NEXT: vse8.v v8, (a1)
-; CHECK-NEXT: ret
+; V-LABEL: vnsrl_0_i8_undef2:
+; V: # %bb.0: # %entry
+; V-NEXT: vsetivli zero, 16, e8, mf2, ta, ma
+; V-NEXT: vle8.v v8, (a0)
+; V-NEXT: vsetivli zero, 8, e8, mf4, ta, ma
+; V-NEXT: vnsrl.wi v8, v8, 0
+; V-NEXT: vse8.v v8, (a1)
+; V-NEXT: ret
+;
+; ZVE32F-LABEL: vnsrl_0_i8_undef2:
+; ZVE32F: # %bb.0: # %entry
+; ZVE32F-NEXT: vsetivli zero, 16, e8, mf2, ta, ma
+; ZVE32F-NEXT: vle8.v v8, (a0)
+; ZVE32F-NEXT: vsetivli zero, 8, e8, mf4, ta, ma
+; ZVE32F-NEXT: vnsrl.wi v8, v8, 0
+; ZVE32F-NEXT: vse8.v v8, (a1)
+; ZVE32F-NEXT: ret
+;
+; ZVZIP-LABEL: vnsrl_0_i8_undef2:
+; ZVZIP: # %bb.0: # %entry
+; ZVZIP-NEXT: vsetivli zero, 16, e8, mf2, ta, ma
+; ZVZIP-NEXT: vle8.v v8, (a0)
+; ZVZIP-NEXT: vsetivli zero, 8, e8, mf4, ta, ma
+; ZVZIP-NEXT: vunzipe.v v8, v8
+; ZVZIP-NEXT: vse8.v v8, (a1)
+; ZVZIP-NEXT: ret
entry:
%0 = load <16 x i8>, ptr %in, align 1
%shuffle.i5 = shufflevector <16 x i8> %0, <16 x i8> poison, <8 x i32> <i32 0, i32 2, i32 poison, i32 6, i32 poison, i32 10, i32 12, i32 14>
@@ -562,14 +632,32 @@ entry:
}
define void @vnsrl_0_i8_undef3(ptr %in, ptr %out) {
-; CHECK-LABEL: vnsrl_0_i8_undef3:
-; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: vsetivli zero, 16, e8, mf2, ta, ma
-; CHECK-NEXT: vle8.v v8, (a0)
-; CHECK-NEXT: vsetivli zero, 8, e8, mf4, ta, ma
-; CHECK-NEXT: vnsrl.wi v8, v8, 0
-; CHECK-NEXT: vse8.v v8, (a1)
-; CHECK-NEXT: ret
+; V-LABEL: vnsrl_0_i8_undef3:
+; V: # %bb.0: # %entry
+; V-NEXT: vsetivli zero, 16, e8, mf2, ta, ma
+; V-NEXT: vle8.v v8, (a0)
+; V-NEXT: vsetivli zero, 8, e8, mf4, ta, ma
+; V-NEXT: vnsrl.wi v8, v8, 0
+; V-NEXT: vse8.v v8, (a1)
+; V-NEXT: ret
+;
+; ZVE32F-LABEL: vnsrl_0_i8_undef3:
+; ZVE32F: # %bb.0: # %entry
+; ZVE32F-NEXT: vsetivli zero, 16, e8, mf2, ta, ma
+; ZVE32F-NEXT: vle8.v v8, (a0)
+; ZVE32F-NEXT: vsetivli zero, 8, e8, mf4, ta, ma
+; ZVE32F-NEXT: vnsrl.wi v8, v8, 0
+; ZVE32F-NEXT: vse8.v v8, (a1)
+; ZVE32F-NEXT: ret
+;
+; ZVZIP-LABEL: vnsrl_0_i8_undef3:
+; ZVZIP: # %bb.0: # %entry
+; ZVZIP-NEXT: vsetivli zero, 16, e8, mf2, ta, ma
+; ZVZIP-NEXT: vle8.v v8, (a0)
+; ZVZIP-NEXT: vsetivli zero, 8, e8, mf4, ta, ma
+; ZVZIP-NEXT: vunzipe.v v8, v8
+; ZVZIP-NEXT: vse8.v v8, (a1)
+; ZVZIP-NEXT: ret
entry:
%0 = load <16 x i8>, ptr %in, align 1
%shuffle.i5 = shufflevector <16 x i8> %0, <16 x i8> poison, <8 x i32> <i32 poison, i32 poison, i32 4, i32 6, i32 8, i32 10, i32 12, i32 14>
@@ -630,7 +718,7 @@ define void @vnsrl_0_i8_single_src(ptr %in, ptr %out) {
; ZVZIP-NEXT: vsetivli zero, 8, e8, mf4, ta, ma
; ZVZIP-NEXT: vle8.v v8, (a0)
; ZVZIP-NEXT: vsetivli zero, 4, e8, mf8, ta, ma
-; ZVZIP-NEXT: vnsrl.wi v8, v8, 0
+; ZVZIP-NEXT: vunzipe.v v8, v8
; ZVZIP-NEXT: vse8.v v8, (a1)
; ZVZIP-NEXT: ret
entry:
@@ -664,7 +752,7 @@ define void @vnsrl_8_i8_single_src(ptr %in, ptr %out) {
; ZVZIP-NEXT: vsetivli zero, 8, e8, mf4, ta, ma
; ZVZIP-NEXT: vle8.v v8, (a0)
; ZVZIP-NEXT: vsetivli zero, 4, e8, mf8, ta, ma
-; ZVZIP-NEXT: vnsrl.wi v8, v8, 8
+; ZVZIP-NEXT: vunzipo.v v8, v8
; ZVZIP-NEXT: vse8.v v8, (a1)
; ZVZIP-NEXT: ret
entry:
@@ -699,9 +787,7 @@ define void @vnsrl_0_i8_single_wideuse(ptr %in, ptr %out) {
; ZVZIP: # %bb.0: # %entry
; ZVZIP-NEXT: vsetivli zero, 8, e8, mf4, ta, ma
; ZVZIP-NEXT: vle8.v v8, (a0)
-; ZVZIP-NEXT: vsetivli zero, 4, e8, mf8, ta, ma
-; ZVZIP-NEXT: vnsrl.wi v8, v8, 0
-; ZVZIP-NEXT: vsetivli zero, 8, e8, mf4, ta, ma
+; ZVZIP-NEXT: vunzipe.v v8, v8
; ZVZIP-NEXT: vse8.v v8, (a1)
; ZVZIP-NEXT: ret
entry:
@@ -836,8 +922,8 @@ define void @vnsrl_0_i8_two_source(ptr %in0, ptr %in1, ptr %out) {
; ZVZIP-NEXT: vle8.v v8, (a1)
; ZVZIP-NEXT: vle8.v v9, (a0)
; ZVZIP-NEXT: vsetivli zero, 4, e8, mf8, ta, ma
-; ZVZIP-NEXT: vnsrl.wi v8, v8, 0
-; ZVZIP-NEXT: vnsrl.wi v9, v9, 0
+; ZVZIP-NEXT: vunzipe.v v8, v8
+; ZVZIP-NEXT: vunzipe.v v9, v9
; ZVZIP-NEXT: vsetivli zero, 8, e8, mf4, ta, ma
; ZVZIP-NEXT: vslideup.vi v9, v8, 4
; ZVZIP-NEXT: vse8.v v9, (a2)
@@ -883,8 +969,8 @@ define void @vnsrl_8_8_two_source(ptr %in0, ptr %in1, ptr %out) {
; ZVZIP-NEXT: vle8.v v8, (a1)
; ZVZIP-NEXT: vle8.v v9, (a0)
; ZVZIP-NEXT: vsetivli zero, 4, e8, mf8, ta, ma
-; ZVZIP-NEXT: vnsrl.wi v8, v8, 8
-; ZVZIP-NEXT: vnsrl.wi v9, v9, 8
+; ZVZIP-NEXT: vunzipo.v v8, v8
+; ZVZIP-NEXT: vunzipo.v v9, v9
; ZVZIP-NEXT: vsetivli zero, 8, e8, mf4, ta, ma
; ZVZIP-NEXT: vslideup.vi v9, v8, 4
; ZVZIP-NEXT: vse8.v v9, (a2)
@@ -930,8 +1016,8 @@ define void @vnsrl_0_i16_two_source(ptr %in0, ptr %in1, ptr %out) {
; ZVZIP-NEXT: vle16.v v8, (a1)
; ZVZIP-NEXT: vle16.v v9, (a0)
; ZVZIP-NEXT: vsetivli zero, 2, e16, mf4, ta, ma
-; ZVZIP-NEXT: vnsrl.wi v8, v8, 0
-; ZVZIP-NEXT: vnsrl.wi v9, v9, 0
+; ZVZIP-NEXT: vunzipe.v v8, v8
+; ZVZIP-NEXT: vunzipe.v v9, v9
; ZVZIP-NEXT: vsetivli zero, 4, e16, mf4, ta, ma
; ZVZIP-NEXT: vslideup.vi v9, v8, 2
; ZVZIP-NEXT: vse16.v v9, (a2)
@@ -977,8 +1063,8 @@ define void @vnsrl_16_i16_two_source(ptr %in0, ptr %in1, ptr %out) {
; ZVZIP-NEXT: vle16.v v8, (a1)
; ZVZIP-NEXT: vle16.v v9, (a0)
; ZVZIP-NEXT: vsetivli zero, 2, e16, mf4, ta, ma
-; ZVZIP-NEXT: vnsrl.wi v8, v8, 16
-; ZVZIP-NEXT: vnsrl.wi v9, v9, 16
+; ZVZIP-NEXT: vunzipo.v v8, v8
+; ZVZIP-NEXT: vunzipo.v v9, v9
; ZVZIP-NEXT: vsetivli zero, 4, e16, mf4, ta, ma
; ZVZIP-NEXT: vslideup.vi v9, v8, 2
; ZVZIP-NEXT: vse16.v v9, (a2)
@@ -1024,8 +1110,8 @@ define void @vnsrl_0_half_two_source(ptr %in0, ptr %in1, ptr %out) {
; ZVZIP-NEXT: vle16.v v8, (a1)
; ZVZIP-NEXT: vle16.v v9, (a0)
; ZVZIP-NEXT: vsetivli zero, 2, e16, mf4, ta, ma
-; ZVZIP-NEXT: vnsrl.wi v8, v8, 0
-; ZVZIP-NEXT: vnsrl.wi v9, v9, 0
+; ZVZIP-NEXT: vunzipe.v v8, v8
+; ZVZIP-NEXT: vunzipe.v v9, v9
; ZVZIP-NEXT: vsetivli zero, 4, e16, mf4, ta, ma
; ZVZIP-NEXT: vslideup.vi v9, v8, 2
; ZVZIP-NEXT: vse16.v v9, (a2)
@@ -1071,8 +1157,8 @@ define void @vnsrl_0_bfloat_two_source(ptr %in0, ptr %in1, ptr %out) {
; ZVZIP-NEXT: vle16.v v8, (a1)
; ZVZIP-NEXT: vle16.v v9, (a0)
; ZVZIP-NEXT: vsetivli zero, 2, e16, mf4, ta, ma
-; ZVZIP-NEXT: vnsrl.wi v8, v8, 0
-; ZVZIP-NEXT: vnsrl.wi v9, v9, 0
+; ZVZIP-NEXT: vunzipe.v v8, v8
+; ZVZIP-NEXT: vunzipe.v v9, v9
; ZVZIP-NEXT: vsetivli zero, 4, e16, mf4, ta, ma
; ZVZIP-NEXT: vslideup.vi v9, v8, 2
; ZVZIP-NEXT: vse16.v v9, (a2)
@@ -1118,8 +1204,8 @@ define void @vnsrl_16_half_two_source(ptr %in0, ptr %in1, ptr %out) {
; ZVZIP-NEXT: vle16.v v8, (a1)
; ZVZIP-NEXT: vle16.v v9, (a0)
; ZVZIP-NEXT: vsetivli zero, 2, e16, mf4, ta, ma
-; ZVZIP-NEXT: vnsrl.wi v8, v8, 16
-; ZVZIP-NEXT: vnsrl.wi v9, v9, 16
+; ZVZIP-NEXT: vunzipo.v v8, v8
+; ZVZIP-NEXT: vunzipo.v v9, v9
; ZVZIP-NEXT: vsetivli zero, 4, e16, mf4, ta, ma
; ZVZIP-NEXT: vslideup.vi v9, v8, 2
; ZVZIP-NEXT: vse16.v v9, (a2)
@@ -1165,8 +1251,8 @@ define void @vnsrl_16_bfloat_two_source(ptr %in0, ptr %in1, ptr %out) {
; ZVZIP-NEXT: vle16.v v8, (a1)
; ZVZIP-NEXT: vle16.v v9, (a0)
; ZVZIP-NEXT: vsetivli zero, 2, e16, mf4, ta, ma
-; ZVZIP-NEXT: vnsrl.wi v8, v8, 16
-; ZVZIP-NEXT: vnsrl.wi v9, v9, 16
+; ZVZIP-NEXT: vunzipo.v v8, v8
+; ZVZIP-NEXT: vunzipo.v v9, v9
; ZVZIP-NEXT: vsetivli zero, 4, e16, mf4, ta, ma
; ZVZIP-NEXT: vslideup.vi v9, v8, 2
; ZVZIP-NEXT: vse16.v v9, (a2)
diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-shuffle-zvzip-zve32f.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-shuffle-zvzip-zve32f.ll
index cd5ad041219c5..be53c54eea7d8 100644
--- a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-shuffle-zvzip-zve32f.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-shuffle-zvzip-zve32f.ll
@@ -91,7 +91,7 @@ define void @deinterleave_v4i16_even(ptr %in, ptr %out) {
; ZVL64B-NEXT: vsetivli zero, 4, e16, m1, ta, ma
; ZVL64B-NEXT: vle16.v v8, (a0)
; ZVL64B-NEXT: vsetivli zero, 2, e16, mf2, ta, ma
-; ZVL64B-NEXT: vnsrl.wi v8, v8, 0
+; ZVL64B-NEXT: vunzipe.v v8, v8
; ZVL64B-NEXT: vse16.v v8, (a1)
; ZVL64B-NEXT: ret
;
@@ -100,7 +100,7 @@ define void @deinterleave_v4i16_even(ptr %in, ptr %out) {
; ZVL128B-NEXT: vsetivli zero, 4, e16, mf2, ta, ma
; ZVL128B-NEXT: vle16.v v8, (a0)
; ZVL128B-NEXT: vsetivli zero, 2, e16, mf2, ta, ma
-; ZVL128B-NEXT: vnsrl.wi v8, v8, 0
+; ZVL128B-NEXT: vunzipe.v v8, v8
; ZVL128B-NEXT: vse16.v v8, (a1)
; ZVL128B-NEXT: ret
entry:
@@ -116,7 +116,7 @@ define void @deinterleave_v4i16_odd(ptr %in, ptr %out) {
; ZVL64B-NEXT: vsetivli zero, 4, e16, m1, ta, ma
; ZVL64B-NEXT: vle16.v v8, (a0)
; ZVL64B-NEXT: vsetivli zero, 2, e16, mf2, ta, ma
-; ZVL64B-NEXT: vnsrl.wi v8, v8, 16
+; ZVL64B-NEXT: vunzipo.v v8, v8
; ZVL64B-NEXT: vse16.v v8, (a1)
; ZVL64B-NEXT: ret
;
@@ -125,7 +125,7 @@ define void @deinterleave_v4i16_odd(ptr %in, ptr %out) {
; ZVL128B-NEXT: vsetivli zero, 4, e16, mf2, ta, ma
; ZVL128B-NEXT: vle16.v v8, (a0)
; ZVL128B-NEXT: vsetivli zero, 2, e16, mf2, ta, ma
-; ZVL128B-NEXT: vnsrl.wi v8, v8, 16
+; ZVL128B-NEXT: vunzipo.v v8, v8
; ZVL128B-NEXT: vse16.v v8, (a1)
; ZVL128B-NEXT: ret
entry:
@@ -170,7 +170,7 @@ define void @deinterleave_v4i8_even(ptr %in, ptr %out) {
; ZVL64B-NEXT: vsetivli zero, 4, e8, mf2, ta, ma
; ZVL64B-NEXT: vle8.v v8, (a0)
; ZVL64B-NEXT: vsetivli zero, 2, e8, mf4, ta, ma
-; ZVL64B-NEXT: vnsrl.wi v8, v8, 0
+; ZVL64B-NEXT: vunzipe.v v8, v8
; ZVL64B-NEXT: vse8.v v8, (a1)
; ZVL64B-NEXT: ret
;
@@ -179,7 +179,7 @@ define void @deinterleave_v4i8_even(ptr %in, ptr %out) {
; ZVL128B-NEXT: vsetivli zero, 4, e8, mf4, ta, ma
; ZVL128B-NEXT: vle8.v v8, (a0)
; ZVL128B-NEXT: vsetivli zero, 2, e8, mf4, ta, ma
-; ZVL128B-NEXT: vnsrl.wi v8, v8, 0
+; ZVL128B-NEXT: vunzipe.v v8, v8
; ZVL128B-NEXT: vse8.v v8, (a1)
; ZVL128B-NEXT: ret
entry:
@@ -195,7 +195,7 @@ define void @deinterleave_v4i8_odd(ptr %in, ptr %out) {
; ZVL64B-NEXT: vsetivli zero, 4, e8, mf2, ta, ma
; ZVL64B-NEXT: vle8.v v8, (a0)
; ZVL64B-NEXT: vsetivli zero, 2, e8, mf4, ta, ma
-; ZVL64B-NEXT: vnsrl.wi v8, v8, 8
+; ZVL64B-NEXT: vunzipo.v v8, v8
; ZVL64B-NEXT: vse8.v v8, (a1)
; ZVL64B-NEXT: ret
;
@@ -204,7 +204,7 @@ define void @deinterleave_v4i8_odd(ptr %in, ptr %out) {
; ZVL128B-NEXT: vsetivli zero, 4, e8, mf4, ta, ma
; ZVL128B-NEXT: vle8.v v8, (a0)
; ZVL128B-NEXT: vsetivli zero, 2, e8, mf4, ta, ma
-; ZVL128B-NEXT: vnsrl.wi v8, v8, 8
+; ZVL128B-NEXT: vunzipo.v v8, v8
; ZVL128B-NEXT: vse8.v v8, (a1)
; ZVL128B-NEXT: ret
entry:
@@ -328,7 +328,7 @@ define void @deinterleave_v4f16_even(ptr %in, ptr %out) {
; ZVL64B-NEXT: vsetivli zero, 4, e16, m1, ta, ma
; ZVL64B-NEXT: vle16.v v8, (a0)
; ZVL64B-NEXT: vsetivli zero, 2, e16, mf2, ta, ma
-; ZVL64B-NEXT: vnsrl.wi v8, v8, 0
+; ZVL64B-NEXT: vunzipe.v v8, v8
; ZVL64B-NEXT: vse16.v v8, (a1)
; ZVL64B-NEXT: ret
;
@@ -337,7 +337,7 @@ define void @deinterleave_v4f16_even(ptr %in, ptr %out) {
; ZVL128B-NEXT: vsetivli zero, 4, e16, mf2, ta, ma
; ZVL128B-NEXT: vle16.v v8, (a0)
; ZVL128B-NEXT: vsetivli zero, 2, e16, mf2, ta, ma
-; ZVL128B-NEXT: vnsrl.wi v8, v8, 0
+; ZVL128B-NEXT: vunzipe.v v8, v8
; ZVL128B-NEXT: vse16.v v8, (a1)
; ZVL128B-NEXT: ret
entry:
@@ -353,7 +353,7 @@ define void @deinterleave_v4f16_odd(ptr %in, ptr %out) {
; ZVL64B-NEXT: vsetivli zero, 4, e16, m1, ta, ma
; ZVL64B-NEXT: vle16.v v8, (a0)
; ZVL64B-NEXT: vsetivli zero, 2, e16, mf2, ta, ma
-; ZVL64B-NEXT: vnsrl.wi v8, v8, 16
+; ZVL64B-NEXT: vunzipo.v v8, v8
; ZVL64B-NEXT: vse16.v v8, (a1)
; ZVL64B-NEXT: ret
;
@@ -362,7 +362,7 @@ define void @deinterleave_v4f16_odd(ptr %in, ptr %out) {
; ZVL128B-NEXT: vsetivli zero, 4, e16, mf2, ta, ma
; ZVL128B-NEXT: vle16.v v8, (a0)
; ZVL128B-NEXT: vsetivli zero, 2, e16, mf2, ta, ma
-; ZVL128B-NEXT: vnsrl.wi v8, v8, 16
+; ZVL128B-NEXT: vunzipo.v v8, v8
; ZVL128B-NEXT: vse16.v v8, (a1)
; ZVL128B-NEXT: ret
entry:
diff --git a/llvm/test/CodeGen/RISCV/rvv/vector-deinterleave-fixed.ll b/llvm/test/CodeGen/RISCV/rvv/vector-deinterleave-fixed.ll
index bce071e988f0e..a1bcbf60b4b8e 100644
--- a/llvm/test/CodeGen/RISCV/rvv/vector-deinterleave-fixed.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/vector-deinterleave-fixed.ll
@@ -6,67 +6,116 @@
; Integers
define {<16 x i1>, <16 x i1>} @vector_deinterleave_v16i1_v32i1(<32 x i1> %vec) {
-; CHECK-LABEL: vector_deinterleave_v16i1_v32i1:
-; CHECK: # %bb.0:
-; CHECK-NEXT: vsetivli zero, 16, e8, m1, ta, ma
-; CHECK-NEXT: vmv.v.i v8, 0
-; CHECK-NEXT: vmerge.vim v9, v8, 1, v0
-; CHECK-NEXT: vsetivli zero, 2, e8, mf4, ta, ma
-; CHECK-NEXT: vslidedown.vi v0, v0, 2
-; CHECK-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
-; CHECK-NEXT: vnsrl.wi v10, v9, 0
-; CHECK-NEXT: vsetivli zero, 16, e8, m1, ta, ma
-; CHECK-NEXT: vmerge.vim v8, v8, 1, v0
-; CHECK-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
-; CHECK-NEXT: vnsrl.wi v9, v9, 8
-; CHECK-NEXT: vnsrl.wi v11, v8, 0
-; CHECK-NEXT: vnsrl.wi v8, v8, 8
-; CHECK-NEXT: vsetivli zero, 16, e8, m1, ta, ma
-; CHECK-NEXT: vslideup.vi v10, v11, 8
-; CHECK-NEXT: vslideup.vi v9, v8, 8
-; CHECK-NEXT: vmsne.vi v0, v10, 0
-; CHECK-NEXT: vmsne.vi v8, v9, 0
-; CHECK-NEXT: ret
+; V-LABEL: vector_deinterleave_v16i1_v32i1:
+; V: # %bb.0:
+; V-NEXT: vsetivli zero, 16, e8, m1, ta, ma
+; V-NEXT: vmv.v.i v8, 0
+; V-NEXT: vmerge.vim v9, v8, 1, v0
+; V-NEXT: vsetivli zero, 2, e8, mf4, ta, ma
+; V-NEXT: vslidedown.vi v0, v0, 2
+; V-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
+; V-NEXT: vnsrl.wi v10, v9, 0
+; V-NEXT: vsetivli zero, 16, e8, m1, ta, ma
+; V-NEXT: vmerge.vim v8, v8, 1, v0
+; V-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
+; V-NEXT: vnsrl.wi v9, v9, 8
+; V-NEXT: vnsrl.wi v11, v8, 0
+; V-NEXT: vnsrl.wi v8, v8, 8
+; V-NEXT: vsetivli zero, 16, e8, m1, ta, ma
+; V-NEXT: vslideup.vi v10, v11, 8
+; V-NEXT: vslideup.vi v9, v8, 8
+; V-NEXT: vmsne.vi v0, v10, 0
+; V-NEXT: vmsne.vi v8, v9, 0
+; V-NEXT: ret
+;
+; ZVZIP-LABEL: vector_deinterleave_v16i1_v32i1:
+; ZVZIP: # %bb.0:
+; ZVZIP-NEXT: vsetivli zero, 16, e8, m1, ta, ma
+; ZVZIP-NEXT: vmv.v.i v8, 0
+; ZVZIP-NEXT: vmerge.vim v9, v8, 1, v0
+; ZVZIP-NEXT: vsetivli zero, 2, e8, mf4, ta, ma
+; ZVZIP-NEXT: vslidedown.vi v0, v0, 2
+; ZVZIP-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
+; ZVZIP-NEXT: vunzipe.v v10, v9
+; ZVZIP-NEXT: vsetivli zero, 16, e8, m1, ta, ma
+; ZVZIP-NEXT: vmerge.vim v8, v8, 1, v0
+; ZVZIP-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
+; ZVZIP-NEXT: vunzipe.v v11, v8
+; ZVZIP-NEXT: vunzipo.v v9, v9
+; ZVZIP-NEXT: vunzipo.v v8, v8
+; ZVZIP-NEXT: vsetivli zero, 16, e8, m1, ta, ma
+; ZVZIP-NEXT: vslideup.vi v10, v11, 8
+; ZVZIP-NEXT: vslideup.vi v9, v8, 8
+; ZVZIP-NEXT: vmsne.vi v0, v10, 0
+; ZVZIP-NEXT: vmsne.vi v8, v9, 0
+; ZVZIP-NEXT: ret
%retval = call {<16 x i1>, <16 x i1>} @llvm.vector.deinterleave2.v32i1(<32 x i1> %vec)
ret {<16 x i1>, <16 x i1>} %retval
}
define {<16 x i8>, <16 x i8>} @vector_deinterleave_v16i8_v32i8(<32 x i8> %vec) {
-; CHECK-LABEL: vector_deinterleave_v16i8_v32i8:
-; CHECK: # %bb.0:
-; CHECK-NEXT: vsetivli zero, 16, e8, m1, ta, ma
-; CHECK-NEXT: vnsrl.wi v10, v8, 0
-; CHECK-NEXT: vnsrl.wi v11, v8, 8
-; CHECK-NEXT: vmv.v.v v8, v10
-; CHECK-NEXT: vmv.v.v v9, v11
-; CHECK-NEXT: ret
+; V-LABEL: vector_deinterleave_v16i8_v32i8:
+; V: # %bb.0:
+; V-NEXT: vsetivli zero, 16, e8, m1, ta, ma
+; V-NEXT: vnsrl.wi v10, v8, 0
+; V-NEXT: vnsrl.wi v11, v8, 8
+; V-NEXT: vmv.v.v v8, v10
+; V-NEXT: vmv.v.v v9, v11
+; V-NEXT: ret
+;
+; ZVZIP-LABEL: vector_deinterleave_v16i8_v32i8:
+; ZVZIP: # %bb.0:
+; ZVZIP-NEXT: vsetivli zero, 16, e8, m1, ta, ma
+; ZVZIP-NEXT: vunzipe.v v10, v8
+; ZVZIP-NEXT: vunzipo.v v11, v8
+; ZVZIP-NEXT: vmv.v.v v8, v10
+; ZVZIP-NEXT: vmv.v.v v9, v11
+; ZVZIP-NEXT: ret
%retval = call {<16 x i8>, <16 x i8>} @llvm.vector.deinterleave2.v32i8(<32 x i8> %vec)
ret {<16 x i8>, <16 x i8>} %retval
}
define {<8 x i16>, <8 x i16>} @vector_deinterleave_v8i16_v16i16(<16 x i16> %vec) {
-; CHECK-LABEL: vector_deinterleave_v8i16_v16i16:
-; CHECK: # %bb.0:
-; CHECK-NEXT: vsetivli zero, 8, e16, m1, ta, ma
-; CHECK-NEXT: vnsrl.wi v10, v8, 0
-; CHECK-NEXT: vnsrl.wi v11, v8, 16
-; CHECK-NEXT: vmv.v.v v8, v10
-; CHECK-NEXT: vmv.v.v v9, v11
-; CHECK-NEXT: ret
+; V-LABEL: vector_deinterleave_v8i16_v16i16:
+; V: # %bb.0:
+; V-NEXT: vsetivli zero, 8, e16, m1, ta, ma
+; V-NEXT: vnsrl.wi v10, v8, 0
+; V-NEXT: vnsrl.wi v11, v8, 16
+; V-NEXT: vmv.v.v v8, v10
+; V-NEXT: vmv.v.v v9, v11
+; V-NEXT: ret
+;
+; ZVZIP-LABEL: vector_deinterleave_v8i16_v16i16:
+; ZVZIP: # %bb.0:
+; ZVZIP-NEXT: vsetivli zero, 8, e16, m1, ta, ma
+; ZVZIP-NEXT: vunzipe.v v10, v8
+; ZVZIP-NEXT: vunzipo.v v11, v8
+; ZVZIP-NEXT: vmv.v.v v8, v10
+; ZVZIP-NEXT: vmv.v.v v9, v11
+; ZVZIP-NEXT: ret
%retval = call {<8 x i16>, <8 x i16>} @llvm.vector.deinterleave2.v16i16(<16 x i16> %vec)
ret {<8 x i16>, <8 x i16>} %retval
}
define {<4 x i32>, <4 x i32>} @vector_deinterleave_v4i32_vv8i32(<8 x i32> %vec) {
-; CHECK-LABEL: vector_deinterleave_v4i32_vv8i32:
-; CHECK: # %bb.0:
-; CHECK-NEXT: li a0, 32
-; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma
-; CHECK-NEXT: vnsrl.wx v10, v8, a0
-; CHECK-NEXT: vnsrl.wi v11, v8, 0
-; CHECK-NEXT: vmv.v.v v8, v11
-; CHECK-NEXT: vmv.v.v v9, v10
-; CHECK-NEXT: ret
+; V-LABEL: vector_deinterleave_v4i32_vv8i32:
+; V: # %bb.0:
+; V-NEXT: li a0, 32
+; V-NEXT: vsetivli zero, 4, e32, m1, ta, ma
+; V-NEXT: vnsrl.wx v10, v8, a0
+; V-NEXT: vnsrl.wi v11, v8, 0
+; V-NEXT: vmv.v.v v8, v11
+; V-NEXT: vmv.v.v v9, v10
+; V-NEXT: ret
+;
+; ZVZIP-LABEL: vector_deinterleave_v4i32_vv8i32:
+; ZVZIP: # %bb.0:
+; ZVZIP-NEXT: vsetivli zero, 4, e32, m1, ta, ma
+; ZVZIP-NEXT: vunzipe.v v10, v8
+; ZVZIP-NEXT: vunzipo.v v11, v8
+; ZVZIP-NEXT: vmv.v.v v8, v10
+; ZVZIP-NEXT: vmv.v.v v9, v11
+; ZVZIP-NEXT: ret
%retval = call {<4 x i32>, <4 x i32>} @llvm.vector.deinterleave2.v8i32(<8 x i32> %vec)
ret {<4 x i32>, <4 x i32>} %retval
}
@@ -698,101 +747,168 @@ define {<2 x i8>, <2 x i8>, <2 x i8>, <2 x i8>, <2 x i8>, <2 x i8>, <2 x i8>, <2
; Floats
define {<2 x half>, <2 x half>} @vector_deinterleave_v2f16_v4f16(<4 x half> %vec) {
-; CHECK-LABEL: vector_deinterleave_v2f16_v4f16:
-; CHECK: # %bb.0:
-; CHECK-NEXT: vsetivli zero, 2, e16, mf4, ta, ma
-; CHECK-NEXT: vnsrl.wi v10, v8, 0
-; CHECK-NEXT: vnsrl.wi v9, v8, 16
-; CHECK-NEXT: vmv1r.v v8, v10
-; CHECK-NEXT: ret
+; V-LABEL: vector_deinterleave_v2f16_v4f16:
+; V: # %bb.0:
+; V-NEXT: vsetivli zero, 2, e16, mf4, ta, ma
+; V-NEXT: vnsrl.wi v10, v8, 0
+; V-NEXT: vnsrl.wi v9, v8, 16
+; V-NEXT: vmv1r.v v8, v10
+; V-NEXT: ret
+;
+; ZVZIP-LABEL: vector_deinterleave_v2f16_v4f16:
+; ZVZIP: # %bb.0:
+; ZVZIP-NEXT: vsetivli zero, 2, e16, mf4, ta, ma
+; ZVZIP-NEXT: vunzipe.v v10, v8
+; ZVZIP-NEXT: vunzipo.v v9, v8
+; ZVZIP-NEXT: vmv1r.v v8, v10
+; ZVZIP-NEXT: ret
%retval = call {<2 x half>, <2 x half>} @llvm.vector.deinterleave2.v4f16(<4 x half> %vec)
ret {<2 x half>, <2 x half>} %retval
}
define {<2 x bfloat>, <2 x bfloat>} @vector_deinterleave_v2bf16_v4bf16(<4 x bfloat> %vec) {
-; CHECK-LABEL: vector_deinterleave_v2bf16_v4bf16:
-; CHECK: # %bb.0:
-; CHECK-NEXT: vsetivli zero, 2, e16, mf4, ta, ma
-; CHECK-NEXT: vnsrl.wi v10, v8, 0
-; CHECK-NEXT: vnsrl.wi v9, v8, 16
-; CHECK-NEXT: vmv1r.v v8, v10
-; CHECK-NEXT: ret
+; V-LABEL: vector_deinterleave_v2bf16_v4bf16:
+; V: # %bb.0:
+; V-NEXT: vsetivli zero, 2, e16, mf4, ta, ma
+; V-NEXT: vnsrl.wi v10, v8, 0
+; V-NEXT: vnsrl.wi v9, v8, 16
+; V-NEXT: vmv1r.v v8, v10
+; V-NEXT: ret
+;
+; ZVZIP-LABEL: vector_deinterleave_v2bf16_v4bf16:
+; ZVZIP: # %bb.0:
+; ZVZIP-NEXT: vsetivli zero, 2, e16, mf4, ta, ma
+; ZVZIP-NEXT: vunzipe.v v10, v8
+; ZVZIP-NEXT: vunzipo.v v9, v8
+; ZVZIP-NEXT: vmv1r.v v8, v10
+; ZVZIP-NEXT: ret
%retval = call {<2 x bfloat>, <2 x bfloat>} @llvm.vector.deinterleave2.v4bf16(<4 x bfloat> %vec)
ret {<2 x bfloat>, <2 x bfloat>} %retval
}
define {<4 x half>, <4 x half>} @vector_deinterleave_v4f16_v8f16(<8 x half> %vec) {
-; CHECK-LABEL: vector_deinterleave_v4f16_v8f16:
-; CHECK: # %bb.0:
-; CHECK-NEXT: vsetivli zero, 4, e16, mf2, ta, ma
-; CHECK-NEXT: vnsrl.wi v10, v8, 0
-; CHECK-NEXT: vnsrl.wi v9, v8, 16
-; CHECK-NEXT: vmv1r.v v8, v10
-; CHECK-NEXT: ret
+; V-LABEL: vector_deinterleave_v4f16_v8f16:
+; V: # %bb.0:
+; V-NEXT: vsetivli zero, 4, e16, mf2, ta, ma
+; V-NEXT: vnsrl.wi v10, v8, 0
+; V-NEXT: vnsrl.wi v9, v8, 16
+; V-NEXT: vmv1r.v v8, v10
+; V-NEXT: ret
+;
+; ZVZIP-LABEL: vector_deinterleave_v4f16_v8f16:
+; ZVZIP: # %bb.0:
+; ZVZIP-NEXT: vsetivli zero, 4, e16, mf2, ta, ma
+; ZVZIP-NEXT: vunzipe.v v10, v8
+; ZVZIP-NEXT: vunzipo.v v9, v8
+; ZVZIP-NEXT: vmv1r.v v8, v10
+; ZVZIP-NEXT: ret
%retval = call {<4 x half>, <4 x half>} @llvm.vector.deinterleave2.v8f16(<8 x half> %vec)
ret {<4 x half>, <4 x half>} %retval
}
define {<4 x bfloat>, <4 x bfloat>} @vector_deinterleave_v4bf16_v8bf16(<8 x bfloat> %vec) {
-; CHECK-LABEL: vector_deinterleave_v4bf16_v8bf16:
-; CHECK: # %bb.0:
-; CHECK-NEXT: vsetivli zero, 4, e16, mf2, ta, ma
-; CHECK-NEXT: vnsrl.wi v10, v8, 0
-; CHECK-NEXT: vnsrl.wi v9, v8, 16
-; CHECK-NEXT: vmv1r.v v8, v10
-; CHECK-NEXT: ret
+; V-LABEL: vector_deinterleave_v4bf16_v8bf16:
+; V: # %bb.0:
+; V-NEXT: vsetivli zero, 4, e16, mf2, ta, ma
+; V-NEXT: vnsrl.wi v10, v8, 0
+; V-NEXT: vnsrl.wi v9, v8, 16
+; V-NEXT: vmv1r.v v8, v10
+; V-NEXT: ret
+;
+; ZVZIP-LABEL: vector_deinterleave_v4bf16_v8bf16:
+; ZVZIP: # %bb.0:
+; ZVZIP-NEXT: vsetivli zero, 4, e16, mf2, ta, ma
+; ZVZIP-NEXT: vunzipe.v v10, v8
+; ZVZIP-NEXT: vunzipo.v v9, v8
+; ZVZIP-NEXT: vmv1r.v v8, v10
+; ZVZIP-NEXT: ret
%retval = call {<4 x bfloat>, <4 x bfloat>} @llvm.vector.deinterleave2.v8bf16(<8 x bfloat> %vec)
ret {<4 x bfloat>, <4 x bfloat>} %retval
}
define {<2 x float>, <2 x float>} @vector_deinterleave_v2f32_v4f32(<4 x float> %vec) {
-; CHECK-LABEL: vector_deinterleave_v2f32_v4f32:
-; CHECK: # %bb.0:
-; CHECK-NEXT: li a0, 32
-; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma
-; CHECK-NEXT: vnsrl.wx v9, v8, a0
-; CHECK-NEXT: vnsrl.wi v8, v8, 0
-; CHECK-NEXT: ret
+; V-LABEL: vector_deinterleave_v2f32_v4f32:
+; V: # %bb.0:
+; V-NEXT: li a0, 32
+; V-NEXT: vsetivli zero, 2, e32, mf2, ta, ma
+; V-NEXT: vnsrl.wx v9, v8, a0
+; V-NEXT: vnsrl.wi v8, v8, 0
+; V-NEXT: ret
+;
+; ZVZIP-LABEL: vector_deinterleave_v2f32_v4f32:
+; ZVZIP: # %bb.0:
+; ZVZIP-NEXT: vsetivli zero, 2, e32, mf2, ta, ma
+; ZVZIP-NEXT: vunzipe.v v10, v8
+; ZVZIP-NEXT: vunzipo.v v9, v8
+; ZVZIP-NEXT: vmv1r.v v8, v10
+; ZVZIP-NEXT: ret
%retval = call {<2 x float>, <2 x float>} @llvm.vector.deinterleave2.v4f32(<4 x float> %vec)
ret {<2 x float>, <2 x float>} %retval
}
define {<8 x half>, <8 x half>} @vector_deinterleave_v8f16_v16f16(<16 x half> %vec) {
-; CHECK-LABEL: vector_deinterleave_v8f16_v16f16:
-; CHECK: # %bb.0:
-; CHECK-NEXT: vsetivli zero, 8, e16, m1, ta, ma
-; CHECK-NEXT: vnsrl.wi v10, v8, 0
-; CHECK-NEXT: vnsrl.wi v11, v8, 16
-; CHECK-NEXT: vmv.v.v v8, v10
-; CHECK-NEXT: vmv.v.v v9, v11
-; CHECK-NEXT: ret
+; V-LABEL: vector_deinterleave_v8f16_v16f16:
+; V: # %bb.0:
+; V-NEXT: vsetivli zero, 8, e16, m1, ta, ma
+; V-NEXT: vnsrl.wi v10, v8, 0
+; V-NEXT: vnsrl.wi v11, v8, 16
+; V-NEXT: vmv.v.v v8, v10
+; V-NEXT: vmv.v.v v9, v11
+; V-NEXT: ret
+;
+; ZVZIP-LABEL: vector_deinterleave_v8f16_v16f16:
+; ZVZIP: # %bb.0:
+; ZVZIP-NEXT: vsetivli zero, 8, e16, m1, ta, ma
+; ZVZIP-NEXT: vunzipe.v v10, v8
+; ZVZIP-NEXT: vunzipo.v v11, v8
+; ZVZIP-NEXT: vmv.v.v v8, v10
+; ZVZIP-NEXT: vmv.v.v v9, v11
+; ZVZIP-NEXT: ret
%retval = call {<8 x half>, <8 x half>} @llvm.vector.deinterleave2.v16f16(<16 x half> %vec)
ret {<8 x half>, <8 x half>} %retval
}
define {<8 x bfloat>, <8 x bfloat>} @vector_deinterleave_v8bf16_v16bf16(<16 x bfloat> %vec) {
-; CHECK-LABEL: vector_deinterleave_v8bf16_v16bf16:
-; CHECK: # %bb.0:
-; CHECK-NEXT: vsetivli zero, 8, e16, m1, ta, ma
-; CHECK-NEXT: vnsrl.wi v10, v8, 0
-; CHECK-NEXT: vnsrl.wi v11, v8, 16
-; CHECK-NEXT: vmv.v.v v8, v10
-; CHECK-NEXT: vmv.v.v v9, v11
-; CHECK-NEXT: ret
+; V-LABEL: vector_deinterleave_v8bf16_v16bf16:
+; V: # %bb.0:
+; V-NEXT: vsetivli zero, 8, e16, m1, ta, ma
+; V-NEXT: vnsrl.wi v10, v8, 0
+; V-NEXT: vnsrl.wi v11, v8, 16
+; V-NEXT: vmv.v.v v8, v10
+; V-NEXT: vmv.v.v v9, v11
+; V-NEXT: ret
+;
+; ZVZIP-LABEL: vector_deinterleave_v8bf16_v16bf16:
+; ZVZIP: # %bb.0:
+; ZVZIP-NEXT: vsetivli zero, 8, e16, m1, ta, ma
+; ZVZIP-NEXT: vunzipe.v v10, v8
+; ZVZIP-NEXT: vunzipo.v v11, v8
+; ZVZIP-NEXT: vmv.v.v v8, v10
+; ZVZIP-NEXT: vmv.v.v v9, v11
+; ZVZIP-NEXT: ret
%retval = call {<8 x bfloat>, <8 x bfloat>} @llvm.vector.deinterleave2.v16bf16(<16 x bfloat> %vec)
ret {<8 x bfloat>, <8 x bfloat>} %retval
}
define {<4 x float>, <4 x float>} @vector_deinterleave_v4f32_v8f32(<8 x float> %vec) {
-; CHECK-LABEL: vector_deinterleave_v4f32_v8f32:
-; CHECK: # %bb.0:
-; CHECK-NEXT: li a0, 32
-; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma
-; CHECK-NEXT: vnsrl.wx v10, v8, a0
-; CHECK-NEXT: vnsrl.wi v11, v8, 0
-; CHECK-NEXT: vmv.v.v v8, v11
-; CHECK-NEXT: vmv.v.v v9, v10
-; CHECK-NEXT: ret
+; V-LABEL: vector_deinterleave_v4f32_v8f32:
+; V: # %bb.0:
+; V-NEXT: li a0, 32
+; V-NEXT: vsetivli zero, 4, e32, m1, ta, ma
+; V-NEXT: vnsrl.wx v10, v8, a0
+; V-NEXT: vnsrl.wi v11, v8, 0
+; V-NEXT: vmv.v.v v8, v11
+; V-NEXT: vmv.v.v v9, v10
+; V-NEXT: ret
+;
+; ZVZIP-LABEL: vector_deinterleave_v4f32_v8f32:
+; ZVZIP: # %bb.0:
+; ZVZIP-NEXT: vsetivli zero, 4, e32, m1, ta, ma
+; ZVZIP-NEXT: vunzipe.v v10, v8
+; ZVZIP-NEXT: vunzipo.v v11, v8
+; ZVZIP-NEXT: vmv.v.v v8, v10
+; ZVZIP-NEXT: vmv.v.v v9, v11
+; ZVZIP-NEXT: ret
%retval = call {<4 x float>, <4 x float>} @llvm.vector.deinterleave2.v8f32(<8 x float> %vec)
ret {<4 x float>, <4 x float>} %retval
}
diff --git a/llvm/test/CodeGen/RISCV/rvv/vector-deinterleave.ll b/llvm/test/CodeGen/RISCV/rvv/vector-deinterleave.ll
index 6a23fb8f437fe..d241f48436035 100644
--- a/llvm/test/CodeGen/RISCV/rvv/vector-deinterleave.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/vector-deinterleave.ll
@@ -3802,12 +3802,11 @@ define { <8 x float>, <8 x float> } @interleave_deinterleave2(<8 x float> %a, <8
;
; ZVZIP-LABEL: interleave_deinterleave2:
; ZVZIP: # %bb.0: # %entry
-; ZVZIP-NEXT: li a0, 32
; ZVZIP-NEXT: vsetivli zero, 16, e32, m4, ta, ma
; ZVZIP-NEXT: vzip.vv v12, v8, v10
; ZVZIP-NEXT: vsetivli zero, 8, e32, m2, ta, ma
-; ZVZIP-NEXT: vnsrl.wx v10, v12, a0
-; ZVZIP-NEXT: vnsrl.wi v8, v12, 0
+; ZVZIP-NEXT: vunzipe.v v8, v12
+; ZVZIP-NEXT: vunzipo.v v10, v12
; ZVZIP-NEXT: ret
entry:
%0 = call <16 x float> @llvm.vector.interleave2.v16f32(<8 x float> %a, <8 x float> %b)
@@ -3829,10 +3828,9 @@ define <16 x float> @deinterleave_interleave2(<16 x float> %arg) {
;
; ZVZIP-LABEL: deinterleave_interleave2:
; ZVZIP: # %bb.0: # %entry
-; ZVZIP-NEXT: li a0, 32
; ZVZIP-NEXT: vsetivli zero, 8, e32, m2, ta, ma
-; ZVZIP-NEXT: vnsrl.wx v12, v8, a0
-; ZVZIP-NEXT: vnsrl.wi v14, v8, 0
+; ZVZIP-NEXT: vunzipo.v v12, v8
+; ZVZIP-NEXT: vunzipe.v v14, v8
; ZVZIP-NEXT: vsetivli zero, 16, e32, m4, ta, ma
; ZVZIP-NEXT: vzip.vv v8, v14, v12
; ZVZIP-NEXT: ret
More information about the llvm-commits
mailing list