Index: lib/Target/AArch64/AArch64ISelLowering.cpp =================================================================== --- lib/Target/AArch64/AArch64ISelLowering.cpp +++ lib/Target/AArch64/AArch64ISelLowering.cpp @@ -8437,6 +8437,16 @@ } } + // (any_extend (extract_vector_element v, i)) -> (extract_vector_element v, i) + if (DCI.isAfterLegalizeVectorOps() && N->getOpcode() == ISD::ANY_EXTEND && + N->hasOneUse() && N->use_begin()->getOpcode() == ISD::SIGN_EXTEND_INREG) { + auto N0 = N->getOperand(0); + auto VT = N->getValueType(0); + if (N0.getNode()->hasOneUse() && N0.getOpcode() == ISD::EXTRACT_VECTOR_ELT) + return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SDLoc(N), VT, + N0.getOperand(0), N0.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 Index: test/CodeGen/AArch64/arm64-neon-copy.ll =================================================================== --- test/CodeGen/AArch64/arm64-neon-copy.ll +++ test/CodeGen/AArch64/arm64-neon-copy.ll @@ -320,21 +320,20 @@ 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) {