diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp index f2e728e8b1cc1f..f741ee4849dfc6 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp @@ -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: @@ -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); diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h index 1c71ade5b66cc3..f5cce12a392993 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h @@ -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); diff --git a/llvm/test/CodeGen/AArch64/sve-vector-deinterleave.ll b/llvm/test/CodeGen/AArch64/sve-vector-deinterleave.ll index 5fc84a261e1cb3..fd2cf67bea2d67 100644 --- a/llvm/test/CodeGen/AArch64/sve-vector-deinterleave.ll +++ b/llvm/test/CodeGen/AArch64/sve-vector-deinterleave.ll @@ -206,6 +206,45 @@ ret {, } %retval } +; Promote illegal type size + +define {, } @vector_deinterleave_nxv8i8_nxv16i8( %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 {, } @llvm.experimental.vector.deinterleave2.nxv16i8( %vec) +ret {, } %retval +} + +define {, } @vector_deinterleave_nxv4i16_nxv8i16( %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 {, } @llvm.experimental.vector.deinterleave2.nxv8i16( %vec) +ret {, } %retval +} + +define {, } @vector_deinterleave_nxv2i32_nxv4i32( %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 {,} @llvm.experimental.vector.deinterleave2.nxv4i32( %vec) +ret {, } %retval +} + + ; Floating declarations declare {,} @llvm.experimental.vector.deinterleave2.nxv4f16() declare {, } @llvm.experimental.vector.deinterleave2.nxv8f16() @@ -229,3 +268,7 @@ declare {, } @llvm.experimental.vector.deinter ; Illegal size type declare {, } @llvm.experimental.vector.deinterleave2.nxv8i64() declare {, } @llvm.experimental.vector.deinterleave2.nxv16i64() + +declare {, } @llvm.experimental.vector.deinterleave2.nxv16i8() +declare {, } @llvm.experimental.vector.deinterleave2.nxv8i16() +declare {, } @llvm.experimental.vector.deinterleave2.nxv4i32() diff --git a/llvm/test/CodeGen/AArch64/sve-vector-interleave.ll b/llvm/test/CodeGen/AArch64/sve-vector-interleave.ll index ee1dc4a3fcd6fe..51700bc252f3be 100644 --- a/llvm/test/CodeGen/AArch64/sve-vector-interleave.ll +++ b/llvm/test/CodeGen/AArch64/sve-vector-interleave.ll @@ -189,6 +189,41 @@ define @interleave2_nxv8i64( %vec0, %retval } +; Promote illegal type size + +define @interleave2_nxv8i8( %vec0, %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 @llvm.experimental.vector.interleave2.nxv16i8( %vec0, %vec1) + ret %retval +} + +define @interleave2_nxv4i16( %vec0, %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 @llvm.experimental.vector.interleave2.nxv8i16( %vec0, %vec1) + ret %retval +} + +define @interleave2_nxv2i32( %vec0, %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 @llvm.experimental.vector.interleave2.nxv4i32( %vec0, %vec1) + ret %retval +} + ; Float declarations declare @llvm.experimental.vector.interleave2.nxv4f16(, ) declare @llvm.experimental.vector.interleave2.nxv8f16(, ) @@ -212,3 +247,7 @@ declare @llvm.experimental.vector.interleave2.nxv4i1( @llvm.experimental.vector.interleave2.nxv16i32(, ) declare @llvm.experimental.vector.interleave2.nxv8i64(, ) + +declare @llvm.experimental.vector.interleave2.nxv16i8(, ) +declare @llvm.experimental.vector.interleave2.nxv8i16(, ) +declare @llvm.experimental.vector.interleave2.nxv4i32(, )