From: Matthew Simpson Date: Thu, 17 Dec 2015 14:30:55 +0000 (+0000) Subject: [AArch64] Add DAG combine for extract extend pattern X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=commitdiff_plain;h=dbf81cc034169bfee63e8ddc1ab58f1e07bebca5 [AArch64] Add DAG combine for extract extend pattern This patch adds a DAG combine for (any_extend (extract_vector_elt v, i)) -> (extract_vector_elt v, i). The combine enables us to better match some SMOV patterns. Differential Revision: http://reviews.llvm.org/D15515 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@255895 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/AArch64/AArch64ISelLowering.cpp b/lib/Target/AArch64/AArch64ISelLowering.cpp index 9f5beff1210..2ede39eb7f2 100644 --- a/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -8450,6 +8450,25 @@ static SDValue performExtendCombine(SDNode *N, } } + const TargetLowering &TLI = DAG.getTargetLoweringInfo(); + + // If we see (any_extend (extract_vector_element v, i)), we can potentially + // remove the extend and promote the extract. We can do this if the vector + // type is legal and if the result is sign extended from the element type. + if (DCI.isAfterLegalizeVectorOps() && N->getOpcode() == ISD::ANY_EXTEND && + N->hasOneUse() && N->use_begin()->getOpcode() == ISD::SIGN_EXTEND_INREG) { + const SDValue &M = N->getOperand(0); + if (M.getNode()->hasOneUse() && M.getOpcode() == ISD::EXTRACT_VECTOR_ELT) { + EVT DstTy = N->getValueType(0); + EVT SrcTy = cast(N->use_begin()->getOperand(1))->getVT(); + EVT VecTy = M.getOperand(0).getValueType(); + EVT ElmTy = VecTy.getScalarType(); + if (TLI.isTypeLegal(VecTy) && SrcTy == ElmTy) + return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SDLoc(N), DstTy, + M.getOperand(0), M.getOperand(1)); + } + } + // This is effectively a custom type legalization for AArch64. // // Type legalization will split an extend of a small, legal, type to a larger @@ -8480,7 +8499,6 @@ static SDValue performExtendCombine(SDNode *N, // We're only interested in cleaning things up for non-legal vector types // here. If both the source and destination are legal, things will just // work naturally without any fiddling. - const TargetLowering &TLI = DAG.getTargetLoweringInfo(); EVT ResVT = N->getValueType(0); if (!ResVT.isVector() || TLI.isTypeLegal(ResVT)) return SDValue(); diff --git a/test/CodeGen/AArch64/arm64-neon-copy.ll b/test/CodeGen/AArch64/arm64-neon-copy.ll index b74a40626ce..83b1cac70f5 100644 --- a/test/CodeGen/AArch64/arm64-neon-copy.ll +++ b/test/CodeGen/AArch64/arm64-neon-copy.ll @@ -320,21 +320,20 @@ define i32 @smovw8h(<8 x i16> %tmp1) { ret i32 %tmp5 } -define i32 @smovx16b(<16 x i8> %tmp1) { +define i64 @smovx16b(<16 x i8> %tmp1) { ; CHECK-LABEL: smovx16b: -; CHECK: smov {{[xw][0-9]+}}, {{v[0-9]+}}.b[8] +; CHECK: smov {{x[0-9]+}}, {{v[0-9]+}}.b[8] %tmp3 = extractelement <16 x i8> %tmp1, i32 8 - %tmp4 = sext i8 %tmp3 to i32 - %tmp5 = add i32 %tmp4, %tmp4 - ret i32 %tmp5 + %tmp4 = sext i8 %tmp3 to i64 + ret i64 %tmp4 } -define i32 @smovx8h(<8 x i16> %tmp1) { +define i64 @smovx8h(<8 x i16> %tmp1) { ; CHECK-LABEL: smovx8h: -; CHECK: smov {{[xw][0-9]+}}, {{v[0-9]+}}.h[2] +; CHECK: smov {{x[0-9]+}}, {{v[0-9]+}}.h[2] %tmp3 = extractelement <8 x i16> %tmp1, i32 2 - %tmp4 = sext i16 %tmp3 to i32 - ret i32 %tmp4 + %tmp4 = sext i16 %tmp3 to i64 + ret i64 %tmp4 } define i64 @smovx4s(<4 x i32> %tmp1) {