Skip to content

Commit

Permalink
[IR][Legalization] Promote illegal deinterleave and interleave vectors
Browse files Browse the repository at this point in the history
To make legalization easier, the operands and outputs have the same size for
these ISD Nodes. When legalizing the results in PromoteIntegerResult the operands
are legalized to the same size as the outputs.
The ISD Node has two output/results, therefore the legalizing functions update
both results/outputs.

Reviewed By: paulwalker-arm

Differential Revision: https://reviews.llvm.org/D144846
  • Loading branch information
CarolineConcatto committed Mar 3, 2023
1 parent 093b5ac commit 204800a
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 0 deletions.
33 changes: 33 additions & 0 deletions llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
Expand Up @@ -115,6 +115,12 @@ void DAGTypeLegalizer::PromoteIntegerResult(SDNode *N, unsigned ResNo) {
Res = PromoteIntRes_VECTOR_SHUFFLE(N); break;
case ISD::VECTOR_SPLICE:
Res = PromoteIntRes_VECTOR_SPLICE(N); break;
case ISD::VECTOR_DEINTERLEAVE:
Res = PromoteIntRes_VECTOR_DEINTERLEAVE(N);
return;
case ISD::VECTOR_INTERLEAVE:
Res = PromoteIntRes_VECTOR_INTERLEAVE(N);
return;
case ISD::INSERT_VECTOR_ELT:
Res = PromoteIntRes_INSERT_VECTOR_ELT(N); break;
case ISD::BUILD_VECTOR:
Expand Down Expand Up @@ -5308,6 +5314,33 @@ SDValue DAGTypeLegalizer::PromoteIntRes_VECTOR_SPLICE(SDNode *N) {
return DAG.getNode(ISD::VECTOR_SPLICE, dl, OutVT, V0, V1, N->getOperand(2));
}

SDValue DAGTypeLegalizer::PromoteIntRes_VECTOR_DEINTERLEAVE(SDNode *N) {
SDLoc dl(N);

SDValue V0 = GetPromotedInteger(N->getOperand(0));
SDValue V1 = GetPromotedInteger(N->getOperand(1));
EVT ResVT = V0.getValueType();
SDValue Res = DAG.getNode(ISD::VECTOR_DEINTERLEAVE, dl,
DAG.getVTList(ResVT, ResVT), V0, V1);
SetPromotedInteger(SDValue(N, 0), Res.getValue(0));
SetPromotedInteger(SDValue(N, 1), Res.getValue(1));
return SDValue();
}

SDValue DAGTypeLegalizer::PromoteIntRes_VECTOR_INTERLEAVE(SDNode *N) {
SDLoc dl(N);

SDValue V0 = GetPromotedInteger(N->getOperand(0));
SDValue V1 = GetPromotedInteger(N->getOperand(1));

EVT ResVT = V0.getValueType();
SDValue Res = DAG.getNode(ISD::VECTOR_INTERLEAVE, dl,
DAG.getVTList(ResVT, ResVT), V0, V1);
SetPromotedInteger(SDValue(N, 0), Res.getValue(0));
SetPromotedInteger(SDValue(N, 1), Res.getValue(1));
return SDValue();
}

SDValue DAGTypeLegalizer::PromoteIntRes_EXTRACT_SUBVECTOR(SDNode *N) {

EVT OutVT = N->getValueType(0);
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
Expand Up @@ -307,6 +307,8 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer {
SDValue PromoteIntRes_VECTOR_REVERSE(SDNode *N);
SDValue PromoteIntRes_VECTOR_SHUFFLE(SDNode *N);
SDValue PromoteIntRes_VECTOR_SPLICE(SDNode *N);
SDValue PromoteIntRes_VECTOR_DEINTERLEAVE(SDNode *N);
SDValue PromoteIntRes_VECTOR_INTERLEAVE(SDNode *N);
SDValue PromoteIntRes_BUILD_VECTOR(SDNode *N);
SDValue PromoteIntRes_ScalarOp(SDNode *N);
SDValue PromoteIntRes_STEP_VECTOR(SDNode *N);
Expand Down
43 changes: 43 additions & 0 deletions llvm/test/CodeGen/AArch64/sve-vector-deinterleave.ll
Expand Up @@ -206,6 +206,45 @@ ret {<vscale x 8 x i64>, <vscale x 8 x i64>} %retval
}


; Promote illegal type size

define {<vscale x 8 x i8>, <vscale x 8 x i8>} @vector_deinterleave_nxv8i8_nxv16i8(<vscale x 16 x i8> %vec) {
; CHECK-LABEL: vector_deinterleave_nxv8i8_nxv16i8:
; CHECK: // %bb.0:
; CHECK-NEXT: uunpkhi z1.h, z0.b
; CHECK-NEXT: uunpklo z2.h, z0.b
; CHECK-NEXT: uzp1 z0.h, z2.h, z1.h
; CHECK-NEXT: uzp2 z1.h, z2.h, z1.h
; CHECK-NEXT: ret
%retval = call {<vscale x 8 x i8>, <vscale x 8 x i8>} @llvm.experimental.vector.deinterleave2.nxv16i8(<vscale x 16 x i8> %vec)
ret {<vscale x 8 x i8>, <vscale x 8 x i8>} %retval
}

define {<vscale x 4 x i16>, <vscale x 4 x i16>} @vector_deinterleave_nxv4i16_nxv8i16(<vscale x 8 x i16> %vec) {
; CHECK-LABEL: vector_deinterleave_nxv4i16_nxv8i16:
; CHECK: // %bb.0:
; CHECK-NEXT: uunpkhi z1.s, z0.h
; CHECK-NEXT: uunpklo z2.s, z0.h
; CHECK-NEXT: uzp1 z0.s, z2.s, z1.s
; CHECK-NEXT: uzp2 z1.s, z2.s, z1.s
; CHECK-NEXT: ret
%retval = call {<vscale x 4 x i16>, <vscale x 4 x i16>} @llvm.experimental.vector.deinterleave2.nxv8i16(<vscale x 8 x i16> %vec)
ret {<vscale x 4 x i16>, <vscale x 4 x i16>} %retval
}

define {<vscale x 2 x i32>, <vscale x 2 x i32>} @vector_deinterleave_nxv2i32_nxv4i32(<vscale x 4 x i32> %vec) {
; CHECK-LABEL: vector_deinterleave_nxv2i32_nxv4i32:
; CHECK: // %bb.0:
; CHECK-NEXT: uunpkhi z1.d, z0.s
; CHECK-NEXT: uunpklo z2.d, z0.s
; CHECK-NEXT: uzp1 z0.d, z2.d, z1.d
; CHECK-NEXT: uzp2 z1.d, z2.d, z1.d
; CHECK-NEXT: ret
%retval = call {<vscale x 2 x i32>,<vscale x 2 x i32>} @llvm.experimental.vector.deinterleave2.nxv4i32(<vscale x 4 x i32> %vec)
ret {<vscale x 2 x i32>, <vscale x 2 x i32>} %retval
}


; Floating declarations
declare {<vscale x 2 x half>,<vscale x 2 x half>} @llvm.experimental.vector.deinterleave2.nxv4f16(<vscale x 4 x half>)
declare {<vscale x 4 x half>, <vscale x 4 x half>} @llvm.experimental.vector.deinterleave2.nxv8f16(<vscale x 8 x half>)
Expand All @@ -229,3 +268,7 @@ declare {<vscale x 2 x i1>, <vscale x 2 x i1>} @llvm.experimental.vector.deinter
; Illegal size type
declare {<vscale x 4 x i64>, <vscale x 4 x i64>} @llvm.experimental.vector.deinterleave2.nxv8i64(<vscale x 8 x i64>)
declare {<vscale x 8 x i64>, <vscale x 8 x i64>} @llvm.experimental.vector.deinterleave2.nxv16i64(<vscale x 16 x i64>)

declare {<vscale x 8 x i8>, <vscale x 8 x i8>} @llvm.experimental.vector.deinterleave2.nxv16i8(<vscale x 16 x i8>)
declare {<vscale x 4 x i16>, <vscale x 4 x i16>} @llvm.experimental.vector.deinterleave2.nxv8i16(<vscale x 8 x i16>)
declare {<vscale x 2 x i32>, <vscale x 2 x i32>} @llvm.experimental.vector.deinterleave2.nxv4i32(<vscale x 4 x i32>)
39 changes: 39 additions & 0 deletions llvm/test/CodeGen/AArch64/sve-vector-interleave.ll
Expand Up @@ -189,6 +189,41 @@ define <vscale x 8 x i64> @interleave2_nxv8i64(<vscale x 4 x i64> %vec0, <vscale
ret <vscale x 8 x i64> %retval
}

; Promote illegal type size

define <vscale x 16 x i8> @interleave2_nxv8i8(<vscale x 8 x i8> %vec0, <vscale x 8 x i8> %vec1) {
; CHECK-LABEL: interleave2_nxv8i8:
; CHECK: // %bb.0:
; CHECK-NEXT: zip2 z2.h, z0.h, z1.h
; CHECK-NEXT: zip1 z0.h, z0.h, z1.h
; CHECK-NEXT: uzp1 z0.b, z0.b, z2.b
; CHECK-NEXT: ret
%retval = call <vscale x 16 x i8> @llvm.experimental.vector.interleave2.nxv16i8(<vscale x 8 x i8> %vec0, <vscale x 8 x i8> %vec1)
ret <vscale x 16 x i8> %retval
}

define <vscale x 8 x i16> @interleave2_nxv4i16(<vscale x 4 x i16> %vec0, <vscale x 4 x i16> %vec1) {
; CHECK-LABEL: interleave2_nxv4i16:
; CHECK: // %bb.0:
; CHECK-NEXT: zip2 z2.s, z0.s, z1.s
; CHECK-NEXT: zip1 z0.s, z0.s, z1.s
; CHECK-NEXT: uzp1 z0.h, z0.h, z2.h
; CHECK-NEXT: ret
%retval = call <vscale x 8 x i16> @llvm.experimental.vector.interleave2.nxv8i16(<vscale x 4 x i16> %vec0, <vscale x 4 x i16> %vec1)
ret <vscale x 8 x i16> %retval
}

define <vscale x 4 x i32> @interleave2_nxv2i32(<vscale x 2 x i32> %vec0, <vscale x 2 x i32> %vec1) {
; CHECK-LABEL: interleave2_nxv2i32:
; CHECK: // %bb.0:
; CHECK-NEXT: zip2 z2.d, z0.d, z1.d
; CHECK-NEXT: zip1 z0.d, z0.d, z1.d
; CHECK-NEXT: uzp1 z0.s, z0.s, z2.s
; CHECK-NEXT: ret
%retval = call <vscale x 4 x i32> @llvm.experimental.vector.interleave2.nxv4i32(<vscale x 2 x i32> %vec0, <vscale x 2 x i32> %vec1)
ret <vscale x 4 x i32> %retval
}

; Float declarations
declare <vscale x 4 x half> @llvm.experimental.vector.interleave2.nxv4f16(<vscale x 2 x half>, <vscale x 2 x half>)
declare <vscale x 8 x half> @llvm.experimental.vector.interleave2.nxv8f16(<vscale x 4 x half>, <vscale x 4 x half>)
Expand All @@ -212,3 +247,7 @@ declare <vscale x 4 x i1> @llvm.experimental.vector.interleave2.nxv4i1(<vscale x
; Illegal type size
declare <vscale x 16 x i32> @llvm.experimental.vector.interleave2.nxv16i32(<vscale x 8 x i32>, <vscale x 8 x i32>)
declare <vscale x 8 x i64> @llvm.experimental.vector.interleave2.nxv8i64(<vscale x 4 x i64>, <vscale x 4 x i64>)

declare <vscale x 16 x i8> @llvm.experimental.vector.interleave2.nxv16i8(<vscale x 8 x i8>, <vscale x 8 x i8>)
declare <vscale x 8 x i16> @llvm.experimental.vector.interleave2.nxv8i16(<vscale x 4 x i16>, <vscale x 4 x i16>)
declare <vscale x 4 x i32> @llvm.experimental.vector.interleave2.nxv4i32(<vscale x 2 x i32>, <vscale x 2 x i32>)

0 comments on commit 204800a

Please sign in to comment.