Index: lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp =================================================================== --- lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp +++ lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp @@ -305,6 +305,26 @@ // make us bitcast between two vectors which are legalized in different ways. if (NOutVT.bitsEq(NInVT) && !NOutVT.isVector()) return DAG.getNode(ISD::BITCAST, dl, NOutVT, GetWidenedVector(InOp)); + // If the output type is also a vector and widening it to the same size + // as the widened input type would be a legal type, we can widen the bitcast + // and handle the promotion after. + if (NOutVT.isVector()) { + unsigned WidenInSize = NInVT.getSizeInBits(); + unsigned OutSize = OutVT.getSizeInBits(); + if (WidenInSize % OutSize == 0) { + unsigned Scale = WidenInSize / OutSize; + EVT WideOutVT = EVT::getVectorVT(*DAG.getContext(), + OutVT.getVectorElementType(), + OutVT.getVectorNumElements() * Scale); + if (isTypeLegal(WideOutVT)) { + InOp = DAG.getBitcast(WideOutVT, GetWidenedVector(InOp)); + MVT IdxTy = TLI.getVectorIdxTy(DAG.getDataLayout()); + InOp = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, OutVT, InOp, + DAG.getConstant(0, dl, IdxTy)); + return DAG.getNode(ISD::ANY_EXTEND, dl, NOutVT, InOp); + } + } + } } return DAG.getNode(ISD::ANY_EXTEND, dl, NOutVT, Index: lib/Target/X86/X86ISelLowering.cpp =================================================================== --- lib/Target/X86/X86ISelLowering.cpp +++ lib/Target/X86/X86ISelLowering.cpp @@ -26296,7 +26296,7 @@ return; } - if ((SrcVT != MVT::f64 && SrcVT != MVT::v2f32) || + if (SrcVT != MVT::f64 || (DstVT != MVT::v2i32 && DstVT != MVT::v4i16 && DstVT != MVT::v8i8) || getTypeAction(*DAG.getContext(), DstVT) == TypeWidenVector) return; @@ -26305,13 +26305,7 @@ EVT SVT = DstVT.getVectorElementType(); EVT WiderVT = EVT::getVectorVT(*DAG.getContext(), SVT, NumElts * 2); SDValue Res; - if (SrcVT == MVT::f64) - Res = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, - MVT::v2f64, N->getOperand(0)); - else - Res = DAG.getNode(ISD::CONCAT_VECTORS, dl, MVT::v4f32, N->getOperand(0), - DAG.getUNDEF(MVT::v2f32)); - + Res = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, MVT::v2f64, N->getOperand(0)); Res = DAG.getBitcast(WiderVT, Res); Res = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, DstVT, Res, DAG.getIntPtrConstant(0, dl));