From d5681f1d688a45c000dd1e2c4f4d3678e0440b94 Mon Sep 17 00:00:00 2001 From: Sander de Smalen Date: Wed, 22 Sep 2021 10:59:21 +0100 Subject: [PATCH] [SelectionDAG] Add PromoteIntOp_INSERT_SUBVECTOR. This is required to codegen something like: @llvm.experimental.vector.insert( %vec, %subvec, i64 %idx) where the output vector is legal, but the input vector needs promoting. It implements this by performing the whole operation on the promoted type, and then truncating the result. Reviewed By: david-arm, craig.topper Differential Revision: https://reviews.llvm.org/D110059 --- .../SelectionDAG/LegalizeIntegerTypes.cpp | 16 ++++++++++++++++ llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h | 1 + llvm/test/CodeGen/AArch64/sve-insert-vector.ll | 17 +++++++++++++++++ 3 files changed, 34 insertions(+) diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp index 31babbb4207f6..a6a1b0b558316 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp @@ -1578,6 +1578,7 @@ bool DAGTypeLegalizer::PromoteIntegerOperand(SDNode *N, unsigned OpNo) { case ISD::STRICT_UINT_TO_FP: Res = PromoteIntOp_STRICT_UINT_TO_FP(N); break; case ISD::ZERO_EXTEND: Res = PromoteIntOp_ZERO_EXTEND(N); break; case ISD::EXTRACT_SUBVECTOR: Res = PromoteIntOp_EXTRACT_SUBVECTOR(N); break; + case ISD::INSERT_SUBVECTOR: Res = PromoteIntOp_INSERT_SUBVECTOR(N); break; case ISD::SHL: case ISD::SRA: @@ -5078,6 +5079,21 @@ SDValue DAGTypeLegalizer::PromoteIntOp_EXTRACT_VECTOR_ELT(SDNode *N) { return DAG.getAnyExtOrTrunc(Ext, dl, N->getValueType(0)); } +SDValue DAGTypeLegalizer::PromoteIntOp_INSERT_SUBVECTOR(SDNode *N) { + SDLoc dl(N); + // The result type is equal to the first input operand's type, so the + // type that needs promoting must be the second source vector. + SDValue V0 = N->getOperand(0); + SDValue V1 = GetPromotedInteger(N->getOperand(1)); + SDValue Idx = N->getOperand(2); + EVT PromVT = EVT::getVectorVT(*DAG.getContext(), + V1.getValueType().getVectorElementType(), + V0.getValueType().getVectorElementCount()); + V0 = DAG.getAnyExtOrTrunc(V0, dl, PromVT); + SDValue Ext = DAG.getNode(ISD::INSERT_SUBVECTOR, dl, PromVT, V0, V1, Idx); + return DAG.getAnyExtOrTrunc(Ext, dl, N->getValueType(0)); +} + SDValue DAGTypeLegalizer::PromoteIntOp_EXTRACT_SUBVECTOR(SDNode *N) { SDLoc dl(N); SDValue V0 = GetPromotedInteger(N->getOperand(0)); diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h index 57e8be933b037..1d46946364dda 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h @@ -369,6 +369,7 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer { SDValue PromoteIntOp_INSERT_VECTOR_ELT(SDNode *N, unsigned OpNo); SDValue PromoteIntOp_EXTRACT_VECTOR_ELT(SDNode *N); SDValue PromoteIntOp_EXTRACT_SUBVECTOR(SDNode *N); + SDValue PromoteIntOp_INSERT_SUBVECTOR(SDNode *N); SDValue PromoteIntOp_CONCAT_VECTORS(SDNode *N); SDValue PromoteIntOp_SCALAR_TO_VECTOR(SDNode *N); SDValue PromoteIntOp_SPLAT_VECTOR(SDNode *N); diff --git a/llvm/test/CodeGen/AArch64/sve-insert-vector.ll b/llvm/test/CodeGen/AArch64/sve-insert-vector.ll index 7ddf7b93b1a4c..3f9b18c6a2f6f 100644 --- a/llvm/test/CodeGen/AArch64/sve-insert-vector.ll +++ b/llvm/test/CodeGen/AArch64/sve-insert-vector.ll @@ -299,6 +299,21 @@ entry: ret %retval } +; This tests promotion of the input operand to INSERT_SUBVECTOR. +define @insert_nxv8i16_nxv2i16( %vec, %in) nounwind { +; CHECK-LABEL: insert_nxv8i16_nxv2i16: +; CHECK: // %bb.0: +; CHECK-NEXT: uunpklo z2.s, z0.h +; CHECK-NEXT: uunpklo z2.d, z2.s +; CHECK-NEXT: uzp1 z1.s, z2.s, z1.s +; CHECK-NEXT: uunpkhi z0.s, z0.h +; CHECK-NEXT: uzp1 z0.h, z1.h, z0.h +; CHECK-NEXT: ret + %r = call @llvm.experimental.vector.insert.nxv8i16.nxv2i16( %vec, %in, i64 2) + ret %r +} + + ; Fixed length clamping define @insert_fixed_v2i64_nxv2i64( %vec, <2 x i64> %subvec) nounwind #0 { @@ -362,3 +377,5 @@ declare @llvm.experimental.vector.insert.nxv8i64.nxv16i64( @llvm.experimental.vector.insert.v2i64.nxv16i64(, <2 x i64>, i64) declare @llvm.experimental.vector.insert.nxv4i32.nxv1i32(, , i64) declare @llvm.experimental.vector.insert.nxv6i16.nxv1i16(, , i64) + +declare @llvm.experimental.vector.insert.nxv8i16.nxv2i16(, , i64)