From: Simon Pilgrim Date: Sun, 2 Jun 2019 14:42:11 +0000 (+0000) Subject: [DAGCombine] Fold insert_subvector(bitcast(x),bitcast(y),c1) -> bitcast(insert_subvec... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=68ea3a046b8e64ec695684042a9225dac578794f;p=llvm [DAGCombine] Fold insert_subvector(bitcast(x),bitcast(y),c1) -> bitcast(insert_subvector(x,y),c2) Move this combine from x86 into generic DAGCombine, which currently only manages cases where the bitcast is between types of the same scalarsize. Differential Revision: https://reviews.llvm.org/D59188 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@362324 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 4ed17440abc..949c14f3ce4 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -18780,6 +18780,43 @@ SDValue DAGCombiner::visitINSERT_SUBVECTOR(SDNode *N) { unsigned InsIdx = cast(N2)->getZExtValue(); + // Push subvector bitcasts to the output, adjusting the index as we go. + // insert_subvector(bitcast(v), bitcast(s), c1) + // -> bitcast(insert_subvector(v, s, c2)) + if ((N0.isUndef() || N0.getOpcode() == ISD::BITCAST) && + N1.getOpcode() == ISD::BITCAST) { + SDValue N0Src = peekThroughBitcasts(N0); + SDValue N1Src = peekThroughBitcasts(N1); + EVT N0SrcSVT = N0Src.getValueType().getScalarType(); + EVT N1SrcSVT = N1Src.getValueType().getScalarType(); + if ((N0.isUndef() || N0SrcSVT == N1SrcSVT) && + N0Src.getValueType().isVector() && N1Src.getValueType().isVector()) { + EVT NewVT; + SDLoc DL(N); + SDValue NewIdx; + MVT IdxVT = TLI.getVectorIdxTy(DAG.getDataLayout()); + LLVMContext &Ctx = *DAG.getContext(); + unsigned NumElts = VT.getVectorNumElements(); + unsigned EltSizeInBits = VT.getScalarSizeInBits(); + if ((EltSizeInBits % N1SrcSVT.getSizeInBits()) == 0) { + unsigned Scale = EltSizeInBits / N1SrcSVT.getSizeInBits(); + NewVT = EVT::getVectorVT(Ctx, N1SrcSVT, NumElts * Scale); + NewIdx = DAG.getConstant(InsIdx * Scale, DL, IdxVT); + } else if ((N1SrcSVT.getSizeInBits() % EltSizeInBits) == 0) { + unsigned Scale = N1SrcSVT.getSizeInBits() / EltSizeInBits; + if ((NumElts % Scale) == 0 && (InsIdx % Scale) == 0) { + NewVT = EVT::getVectorVT(Ctx, N1SrcSVT, NumElts / Scale); + NewIdx = DAG.getConstant(InsIdx / Scale, DL, IdxVT); + } + } + if (NewIdx && hasOperation(ISD::INSERT_SUBVECTOR, NewVT)) { + SDValue Res = DAG.getBitcast(NewVT, N0Src); + Res = DAG.getNode(ISD::INSERT_SUBVECTOR, DL, NewVT, Res, N1Src, NewIdx); + return DAG.getBitcast(VT, Res); + } + } + } + // Canonicalize insert_subvector dag nodes. // Example: // (insert_subvector (insert_subvector A, Idx0), Idx1) diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 253f4487976..5bdcb89b8f5 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -43066,42 +43066,6 @@ static SDValue combineInsertSubvector(SDNode *N, SelectionDAG &DAG, } } - // Push subvector bitcasts to the output, adjusting the index as we go. - // insert_subvector(bitcast(v), bitcast(s), c1) -> - // bitcast(insert_subvector(v,s,c2)) - // TODO: Move this to generic - which only supports same scalar sizes. - if ((Vec.isUndef() || Vec.getOpcode() == ISD::BITCAST) && - SubVec.getOpcode() == ISD::BITCAST) { - SDValue VecSrc = peekThroughBitcasts(Vec); - SDValue SubVecSrc = peekThroughBitcasts(SubVec); - MVT VecSrcSVT = VecSrc.getSimpleValueType().getScalarType(); - MVT SubVecSrcSVT = SubVecSrc.getSimpleValueType().getScalarType(); - if (Vec.isUndef() || VecSrcSVT == SubVecSrcSVT) { - MVT NewOpVT; - SDValue NewIdx; - unsigned NumElts = OpVT.getVectorNumElements(); - unsigned EltSizeInBits = OpVT.getScalarSizeInBits(); - if ((EltSizeInBits % SubVecSrcSVT.getSizeInBits()) == 0) { - unsigned Scale = EltSizeInBits / SubVecSrcSVT.getSizeInBits(); - NewOpVT = MVT::getVectorVT(SubVecSrcSVT, NumElts * Scale); - NewIdx = DAG.getIntPtrConstant(IdxVal * Scale, dl); - } else if ((SubVecSrcSVT.getSizeInBits() % EltSizeInBits) == 0) { - unsigned Scale = SubVecSrcSVT.getSizeInBits() / EltSizeInBits; - if ((IdxVal % Scale) == 0) { - NewOpVT = MVT::getVectorVT(SubVecSrcSVT, NumElts / Scale); - NewIdx = DAG.getIntPtrConstant(IdxVal / Scale, dl); - } - } - if (NewIdx && DAG.getTargetLoweringInfo().isOperationLegal( - ISD::INSERT_SUBVECTOR, NewOpVT)) { - SDValue Res = DAG.getBitcast(NewOpVT, VecSrc); - Res = DAG.getNode(ISD::INSERT_SUBVECTOR, dl, NewOpVT, Res, SubVecSrc, - NewIdx); - return DAG.getBitcast(OpVT, Res); - } - } - } - // Match concat_vector style patterns. SmallVector SubVectorOps; if (collectConcatOps(N, SubVectorOps))