Skip to content
Open
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
6 changes: 3 additions & 3 deletions llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28283,10 +28283,10 @@ SDValue DAGCombiner::visitVECTOR_INTERLEAVE(SDNode *N) {

SDValue DAGCombiner::visitVECTOR_DEINTERLEAVE(SDNode *N) {
EVT VT = N->getValueType(0);
SDValue Op0 = N->getOperand(0);

// Canonicalize shuffle undef -> {undef, undef, ..}
if (Op0.isUndef()) {
// Canonicalize shuffle undef, undef -> {undef, undef, ..}
// Every result takes lanes from every operand, so all operands must be undef.
if (all_of(N->op_values(), [](SDValue Op) { return Op.isUndef(); })) {
SDLoc DL(N);
SmallVector<SDValue> Ops(N->getNumValues(), DAG.getUNDEF(VT));
return DAG.getMergeValues(Ops, DL);
Expand Down
64 changes: 64 additions & 0 deletions llvm/test/CodeGen/AArch64/fixed-vector-deinterleave.ll
Original file line number Diff line number Diff line change
Expand Up @@ -873,3 +873,67 @@ define {<8 x bfloat>, <8 x bfloat>, <8 x bfloat>, <8 x bfloat>, <8 x bfloat>, <8
%retval = call {<8 x bfloat>, <8 x bfloat>, <8 x bfloat>, <8 x bfloat>, <8 x bfloat>, <8 x bfloat>, <8 x bfloat>, <8 x bfloat>} @llvm.vector.deinterleave8.v64bf16(<64 x bfloat> %ins7)
ret {<8 x bfloat>, <8 x bfloat>, <8 x bfloat>, <8 x bfloat>, <8 x bfloat>, <8 x bfloat>, <8 x bfloat>, <8 x bfloat>} %retval
}

; Only the low half of the deinterleaved vector is poison, so the results are
; not poison: lanes 2 and 3 of each result come from %v.
define void @deinterleave2_v8i8_lo_poison(ptr %p, ptr %o) {
; CHECK-SD-LABEL: deinterleave2_v8i8_lo_poison:
; CHECK-SD: // %bb.0:
; CHECK-SD-NEXT: ldr s0, [x0]
; CHECK-SD-NEXT: ushll v0.8h, v0.8b, #0
; CHECK-SD-NEXT: uzp2 v1.4h, v0.4h, v0.4h
; CHECK-SD-NEXT: uzp1 v0.4h, v0.4h, v0.4h
; CHECK-SD-NEXT: zip2 v0.2s, v0.2s, v1.2s
; CHECK-SD-NEXT: uzp1 v0.8b, v0.8b, v0.8b
; CHECK-SD-NEXT: str s0, [x1]
; CHECK-SD-NEXT: ret
;
; CHECK-GI-LABEL: deinterleave2_v8i8_lo_poison:
; CHECK-GI: // %bb.0:
; CHECK-GI-NEXT: ld1 { v0.s }[1], [x0]
; CHECK-GI-NEXT: adrp x8, .LCPI42_0
; CHECK-GI-NEXT: uzp1 v1.8b, v0.8b, v0.8b
; CHECK-GI-NEXT: uzp2 v0.8b, v0.8b, v0.8b
; CHECK-GI-NEXT: mov v1.d[1], v0.d[0]
; CHECK-GI-NEXT: ldr d0, [x8, :lo12:.LCPI42_0]
; CHECK-GI-NEXT: tbl v0.16b, { v1.16b }, v0.16b
; CHECK-GI-NEXT: str s0, [x1]
; CHECK-GI-NEXT: ret
%v = load <4 x i8>, ptr %p
%x = shufflevector <4 x i8> %v, <4 x i8> poison, <8 x i32> <i32 poison, i32 poison, i32 poison, i32 poison, i32 0, i32 1, i32 2, i32 3>
%d = call {<4 x i8>, <4 x i8>} @llvm.vector.deinterleave2.v8i8(<8 x i8> %x)
%even = extractvalue {<4 x i8>, <4 x i8>} %d, 0
%odd = extractvalue {<4 x i8>, <4 x i8>} %d, 1
%r = shufflevector <4 x i8> %even, <4 x i8> %odd, <4 x i32> <i32 2, i32 3, i32 6, i32 7>
store <4 x i8> %r, ptr %o
ret void
}

define <4 x i32> @deinterleave2_v8i32_lo_poison(<4 x i32> %v) {
; CHECK-LABEL: deinterleave2_v8i32_lo_poison:
; CHECK: // %bb.0:
; CHECK-NEXT: uzp1 v0.4s, v0.4s, v0.4s
; CHECK-NEXT: ret
%x = shufflevector <4 x i32> %v, <4 x i32> poison, <8 x i32> <i32 poison, i32 poison, i32 poison, i32 poison, i32 0, i32 1, i32 2, i32 3>
%d = call {<4 x i32>, <4 x i32>} @llvm.vector.deinterleave2.v8i32(<8 x i32> %x)
%even = extractvalue {<4 x i32>, <4 x i32>} %d, 0
ret <4 x i32> %even
}

define <2 x i32> @deinterleave3_v6i32_first_poison(<2 x i32> %b, <2 x i32> %c) {
; CHECK-LABEL: deinterleave3_v6i32_first_poison:
; CHECK: // %bb.0:
; CHECK-NEXT: sub sp, sp, #32
; CHECK-NEXT: .cfi_def_cfa_offset 32
; CHECK-NEXT: add x8, sp, #8
; CHECK-NEXT: stp d0, d1, [sp, #16]
; CHECK-NEXT: ld3 { v31.2s, v0.2s, v1.2s }, [x8]
; CHECK-NEXT: // kill: def $d0 killed $d0 killed $d31_d0_d1
; CHECK-NEXT: add sp, sp, #32
; CHECK-NEXT: ret
%bc = shufflevector <2 x i32> %b, <2 x i32> %c, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
%x = shufflevector <4 x i32> %bc, <4 x i32> poison, <6 x i32> <i32 poison, i32 poison, i32 0, i32 1, i32 2, i32 3>
%d = call {<2 x i32>, <2 x i32>, <2 x i32>} @llvm.vector.deinterleave3.v6i32(<6 x i32> %x)
%r = extractvalue {<2 x i32>, <2 x i32>, <2 x i32>} %d, 1
ret <2 x i32> %r
}
Loading