Index: lib/CodeGen/SelectionDAG/SelectionDAG.cpp =================================================================== --- lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -4035,6 +4035,9 @@ case ISD::ANY_EXTEND: case ISD::ZERO_EXTEND: case ISD::SIGN_EXTEND: + case ISD::ANY_EXTEND_VECTOR_INREG: + case ISD::ZERO_EXTEND_VECTOR_INREG: + case ISD::SIGN_EXTEND_VECTOR_INREG: case ISD::UINT_TO_FP: case ISD::SINT_TO_FP: case ISD::ABS: @@ -4459,11 +4462,19 @@ if (!VT.isVector()) return SDValue(); + // VECTOR_INREG opcodes allow more elements in source than dest. + bool InVecExtend = Opcode == ISD::ANY_EXTEND_VECTOR_INREG || + Opcode == ISD::ZERO_EXTEND_VECTOR_INREG || + Opcode == ISD::SIGN_EXTEND_VECTOR_INREG; + unsigned NumElts = VT.getVectorNumElements(); auto IsScalarOrSameVectorSize = [&](const SDValue &Op) { return !Op.getValueType().isVector() || - Op.getValueType().getVectorNumElements() == NumElts; + (!InVecExtend && + Op.getValueType().getVectorNumElements() == NumElts) || + (InVecExtend && + Op.getValueType().getVectorNumElements() >= NumElts); }; auto IsConstantBuildVectorOrUndef = [&](const SDValue &Op) { @@ -4492,6 +4503,13 @@ return SDValue(); } + // Invec opcodes need to be changed to their scalar opcode. + switch (Opcode) { + case ISD::ANY_EXTEND_VECTOR_INREG: Opcode = ISD::ANY_EXTEND; break; + case ISD::SIGN_EXTEND_VECTOR_INREG: Opcode = ISD::SIGN_EXTEND; break; + case ISD::ZERO_EXTEND_VECTOR_INREG: Opcode = ISD::ZERO_EXTEND; break; + } + // Constant fold each scalar lane separately. SmallVector ScalarResults; for (unsigned i = 0; i != NumElts; i++) {