From a21bff0673a1d593588c69e2ed2f557af40faa2d Mon Sep 17 00:00:00 2001 From: David Sherwood Date: Fri, 14 May 2021 10:50:08 +0100 Subject: [PATCH] [CodeGen] Add support for widening the result of EXTRACT_SUBVECTOR When trying to return a type such as from a function we crash in DAGTypeLegalizer::WidenVecRes_EXTRACT_SUBVECTOR when attempting to get the fixed number of elements in the vector. For the simple case we are dealing with, i.e. extracting from index 0 of input vector we can simply rely upon existing code that just returns the input. Differential Revision: https://reviews.llvm.org/D102605 --- .../SelectionDAG/LegalizeVectorTypes.cpp | 6 ++++- .../CodeGen/AArch64/sve-extract-vector.ll | 23 +++++++++++++++++++ llvm/test/CodeGen/AArch64/sve-int-arith.ll | 10 ++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp index 8b84864678fd..586df3577789 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp @@ -3960,7 +3960,6 @@ SDValue DAGTypeLegalizer::WidenVecRes_CONCAT_VECTORS(SDNode *N) { SDValue DAGTypeLegalizer::WidenVecRes_EXTRACT_SUBVECTOR(SDNode *N) { EVT VT = N->getValueType(0); EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT); - unsigned WidenNumElts = WidenVT.getVectorNumElements(); SDValue InOp = N->getOperand(0); SDValue Idx = N->getOperand(1); SDLoc dl(N); @@ -3975,7 +3974,12 @@ SDValue DAGTypeLegalizer::WidenVecRes_EXTRACT_SUBVECTOR(SDNode *N) { if (IdxVal == 0 && InVT == WidenVT) return InOp; + if (VT.isScalableVector()) + report_fatal_error("Don't know how to widen the result of " + "EXTRACT_SUBVECTOR for scalable vectors"); + // Check if we can extract from the vector. + unsigned WidenNumElts = WidenVT.getVectorNumElements(); unsigned InNumElts = InVT.getVectorNumElements(); if (IdxVal % WidenNumElts == 0 && IdxVal + WidenNumElts < InNumElts) return DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, WidenVT, InOp, Idx); diff --git a/llvm/test/CodeGen/AArch64/sve-extract-vector.ll b/llvm/test/CodeGen/AArch64/sve-extract-vector.ll index 5aa7eab619c0..572e246fe300 100644 --- a/llvm/test/CodeGen/AArch64/sve-extract-vector.ll +++ b/llvm/test/CodeGen/AArch64/sve-extract-vector.ll @@ -105,7 +105,30 @@ define <16 x i8> @extract_v16i8_nxv16i8_idx1( %vec) nounwind { ret <16 x i8> %retval } + +; Extracting illegal subvectors + +define @extract_nxv1i32_nxv4i32( %vec) nounwind { +; CHECK-LABEL: extract_nxv1i32_nxv4i32: +; CHECK: // %bb.0: +; CHECK-NEXT: ret + %retval = call @llvm.experimental.vector.extract.nxv1i32.nxv4i32( %vec, i64 0) + ret %retval +} + +define @extract_nxv1i16_nxv6i16( %vec) nounwind { +; CHECK-LABEL: extract_nxv1i16_nxv6i16: +; CHECK: // %bb.0: +; CHECK-NEXT: ret + %retval = call @llvm.experimental.vector.extract.nxv1i16.nxv6i16( %vec, i64 0) + ret %retval +} + + declare <2 x i64> @llvm.experimental.vector.extract.v2i64.nxv2i64(, i64) declare <4 x i32> @llvm.experimental.vector.extract.v4i32.nxv4i32(, i64) declare <8 x i16> @llvm.experimental.vector.extract.v8i16.nxv8i16(, i64) declare <16 x i8> @llvm.experimental.vector.extract.v16i8.nxv16i8(, i64) + +declare @llvm.experimental.vector.extract.nxv1i32.nxv4i32(, i64) +declare @llvm.experimental.vector.extract.nxv1i16.nxv6i16(, i64) diff --git a/llvm/test/CodeGen/AArch64/sve-int-arith.ll b/llvm/test/CodeGen/AArch64/sve-int-arith.ll index 2b0ce091a090..c71af6876a1b 100644 --- a/llvm/test/CodeGen/AArch64/sve-int-arith.ll +++ b/llvm/test/CodeGen/AArch64/sve-int-arith.ll @@ -45,6 +45,16 @@ define @add_i8_zero( %a) { ret %res } +define @add_nxv1i32( %a, %b) { +; CHECK-LABEL: add_nxv1i32: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: add z0.s, z0.s, z1.s +; CHECK-NEXT: ret +entry: + %c = add %a, %b + ret %c +} + define @sub_i64( %a, %b) { ; CHECK-LABEL: sub_i64: ; CHECK: // %bb.0: