Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions llvm/lib/Target/RISCV/RISCVISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5593,6 +5593,20 @@ static SDValue lowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG,
1 < count_if(Mask, [](int Idx) { return Idx != -1; })) {
if (SDValue Src = getSingleShuffleSrc(VT, V1, V2))
return getDeinterleaveShiftAndTrunc(DL, VT, Src, Factor, Index, DAG);
if (1 < count_if(Mask,
[&Mask](int Idx) { return Idx < (int)Mask.size(); }) &&
1 < count_if(Mask, [&Mask](int Idx) {
return Idx >= (int)Mask.size();
})) {
// Narrow each source and concatenate them.
// FIXME: For small LMUL it is better to concatenate first.
MVT HalfVT = VT.getHalfNumVectorElementsVT();
SDValue Lo =
getDeinterleaveShiftAndTrunc(DL, HalfVT, V1, Factor, Index, DAG);
SDValue Hi =
getDeinterleaveShiftAndTrunc(DL, HalfVT, V2, Factor, Index, DAG);
return DAG.getNode(ISD::CONCAT_VECTORS, DL, VT, Lo, Hi);
}
}
}
}
Expand Down
34 changes: 13 additions & 21 deletions llvm/test/CodeGen/RISCV/rvv/fixed-vectors-deinterleave-load.ll
Original file line number Diff line number Diff line change
Expand Up @@ -10,34 +10,26 @@ define {<16 x i1>, <16 x i1>} @vector_deinterleave_load_v16i1_v32i1(ptr %p) {
; CHECK-LABEL: vector_deinterleave_load_v16i1_v32i1:
; CHECK: # %bb.0:
; CHECK-NEXT: li a1, 32
; CHECK-NEXT: vsetivli zero, 16, e8, m1, ta, ma
; CHECK-NEXT: vmv.v.i v10, 0
; CHECK-NEXT: vid.v v9
; CHECK-NEXT: vsetvli zero, a1, e8, m2, ta, ma
; CHECK-NEXT: vlm.v v8, (a0)
; CHECK-NEXT: li a0, -256
; CHECK-NEXT: vlm.v v0, (a0)
; CHECK-NEXT: vsetivli zero, 16, e8, m1, ta, ma
; CHECK-NEXT: vadd.vv v11, v9, v9
; CHECK-NEXT: vsetvli zero, zero, e16, m2, ta, ma
; CHECK-NEXT: vmv.s.x v9, a0
; CHECK-NEXT: vsetvli zero, zero, e8, m1, ta, ma
; CHECK-NEXT: vadd.vi v12, v11, -16
; 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, v8, 2
; 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: vadd.vi v11, v11, -15
; CHECK-NEXT: vmerge.vim v13, v10, 1, v0
; CHECK-NEXT: vmv1r.v v0, v8
; CHECK-NEXT: vmerge.vim v8, v10, 1, v0
; CHECK-NEXT: vmerge.vim v8, v8, 1, v0
; CHECK-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
; CHECK-NEXT: vnsrl.wi v10, v8, 0
; CHECK-NEXT: vnsrl.wi v9, v9, 8
; CHECK-NEXT: vnsrl.wi v11, v8, 0
; CHECK-NEXT: vnsrl.wi v8, v8, 8
; CHECK-NEXT: vmv1r.v v0, v9
; CHECK-NEXT: vsetivli zero, 16, e8, m1, ta, mu
; CHECK-NEXT: vrgather.vv v10, v13, v12, v0.t
; CHECK-NEXT: vrgather.vv v8, v13, v11, v0.t
; 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, v8, 0
; CHECK-NEXT: vmsne.vi v8, v9, 0
; CHECK-NEXT: ret
%vec = load <32 x i1>, ptr %p
%deinterleaved.results = call {<16 x i1>, <16 x i1>} @llvm.vector.deinterleave2.v32i1(<32 x i1> %vec)
Expand Down
86 changes: 86 additions & 0 deletions llvm/test/CodeGen/RISCV/rvv/fixed-vectors-shuffle-deinterleave.ll
Original file line number Diff line number Diff line change
Expand Up @@ -369,3 +369,89 @@ entry:
store <2 x i8> %shuffle.i5, ptr %out, align 1
ret void
}

define void @deinterleave4_0_i8_two_source(ptr %in0, ptr %in1, ptr %out) {
; CHECK-LABEL: deinterleave4_0_i8_two_source:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
; CHECK-NEXT: vle8.v v8, (a1)
; CHECK-NEXT: vle8.v v9, (a0)
; CHECK-NEXT: vsetivli zero, 2, e16, mf4, ta, ma
; CHECK-NEXT: vnsrl.wi v8, v8, 0
; CHECK-NEXT: vnsrl.wi v9, v9, 0
; CHECK-NEXT: vsetvli zero, zero, e8, mf8, ta, ma
; CHECK-NEXT: vnsrl.wi v8, v8, 0
; CHECK-NEXT: vnsrl.wi v9, v9, 0
; CHECK-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
; CHECK-NEXT: vslideup.vi v9, v8, 4
; CHECK-NEXT: vse8.v v9, (a2)
; CHECK-NEXT: ret
entry:
%0 = load <8 x i8>, ptr %in0, align 1
%1 = load <8 x i8>, ptr %in1, align 1
%shuffle.i5 = shufflevector <8 x i8> %0, <8 x i8> %1, <8 x i32> <i32 0, i32 4, i32 8, i32 12, i32 undef, i32 undef, i32 undef, i32 undef>
store <8 x i8> %shuffle.i5, ptr %out, align 1
ret void
}

define void @deinterleave4_8_i8_two_source(ptr %in0, ptr %in1, ptr %out) {
; CHECK-LABEL: deinterleave4_8_i8_two_source:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
; CHECK-NEXT: vle8.v v8, (a1)
; CHECK-NEXT: vle8.v v9, (a0)
; CHECK-NEXT: vsetivli zero, 2, e16, mf4, ta, ma
; CHECK-NEXT: vnsrl.wi v8, v8, 8
; CHECK-NEXT: vnsrl.wi v9, v9, 8
; CHECK-NEXT: vsetvli zero, zero, e8, mf8, ta, ma
; CHECK-NEXT: vnsrl.wi v8, v8, 0
; CHECK-NEXT: vnsrl.wi v9, v9, 0
; CHECK-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
; CHECK-NEXT: vslideup.vi v9, v8, 4
; CHECK-NEXT: vse8.v v9, (a2)
; CHECK-NEXT: ret
entry:
%0 = load <8 x i8>, ptr %in0, align 1
%1 = load <8 x i8>, ptr %in1, align 1
%shuffle.i5 = shufflevector <8 x i8> %0, <8 x i8> %1, <8 x i32> <i32 1, i32 5, i32 9, i32 13, i32 undef, i32 undef, i32 undef, i32 undef>
store <8 x i8> %shuffle.i5, ptr %out, align 1
ret void
}

define void @deinterleave8_0_i8_two_source(ptr %in0, ptr %in1, ptr %out) {
; CHECK-LABEL: deinterleave8_0_i8_two_source:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
; CHECK-NEXT: vle8.v v8, (a0)
; CHECK-NEXT: vsetivli zero, 2, e8, mf2, ta, ma
; CHECK-NEXT: vle8.v v9, (a1)
; CHECK-NEXT: vsetvli zero, zero, e8, mf2, tu, ma
; CHECK-NEXT: vslideup.vi v8, v9, 1
; CHECK-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
; CHECK-NEXT: vse8.v v8, (a2)
; CHECK-NEXT: ret
entry:
%0 = load <8 x i8>, ptr %in0, align 1
%1 = load <8 x i8>, ptr %in1, align 1
%shuffle.i5 = shufflevector <8 x i8> %0, <8 x i8> %1, <8 x i32> <i32 0, i32 8, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
store <8 x i8> %shuffle.i5, ptr %out, align 1
ret void
}

define void @deinterleave8_8_i8_two_source(ptr %in0, ptr %in1, ptr %out) {
; CHECK-LABEL: deinterleave8_8_i8_two_source:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: vsetivli zero, 8, e8, mf2, ta, mu
; CHECK-NEXT: vle8.v v8, (a0)
; CHECK-NEXT: vle8.v v9, (a1)
; CHECK-NEXT: vmv.v.i v0, -3
; CHECK-NEXT: vrgather.vi v9, v8, 1, v0.t
; CHECK-NEXT: vse8.v v9, (a2)
; CHECK-NEXT: ret
entry:
%0 = load <8 x i8>, ptr %in0, align 1
%1 = load <8 x i8>, ptr %in1, align 1
%shuffle.i5 = shufflevector <8 x i8> %0, <8 x i8> %1, <8 x i32> <i32 1, i32 9, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
store <8 x i8> %shuffle.i5, ptr %out, align 1
ret void
}
Loading
Loading