Index: llvm/lib/Target/AArch64/AArch64ISelLowering.cpp =================================================================== --- llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -16136,6 +16136,7 @@ TargetLowering::DAGCombinerInfo &DCI, SelectionDAG &DAG) { SDLoc DL(N); + EVT VT = N->getValueType(0); // A build vector of two extracted elements is equivalent to an // extract subvector where the inner vector is any-extended to the @@ -16146,10 +16147,17 @@ // For now, only consider the v2i32 case, which arises as a result of // legalization. - if (N->getValueType(0) != MVT::v2i32) + if (VT != MVT::v2i32) return SDValue(); SDValue Elt0 = N->getOperand(0), Elt1 = N->getOperand(1); + uint64_t Idx = Elt0->getConstantOperandVal(1); + + // EXTRACT_SUBVECTOR requires that Idx be a constant multiple of ResultType's + // known minimum vector length. + if (Idx % VT.getVectorMinNumElements() != 0) + return SDValue(); + // Reminder, EXTRACT_VECTOR_ELT has the effect of any-extending to its VT. if (Elt0->getOpcode() == ISD::EXTRACT_VECTOR_ELT && Elt1->getOpcode() == ISD::EXTRACT_VECTOR_ELT && @@ -16159,7 +16167,7 @@ // Both EXTRACT_VECTOR_ELT from same vector... Elt0->getOperand(0) == Elt1->getOperand(0) && // ... and contiguous. First element's index +1 == second element's index. - Elt0->getConstantOperandVal(1) + 1 == Elt1->getConstantOperandVal(1)) { + Idx + 1 == Elt1->getConstantOperandVal(1)) { SDValue VecToExtend = Elt0->getOperand(0); EVT ExtVT = VecToExtend.getValueType().changeVectorElementType(MVT::i32); if (!DAG.getTargetLoweringInfo().isTypeLegal(ExtVT))