diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index f431c41860587c..f0bd1b450815c7 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -6293,57 +6293,55 @@ static std::pair splitVector(SDValue Op, SelectionDAG &DAG, return std::make_pair(Lo, Hi); } -// Split an unary integer op into 2 half sized ops. -static SDValue splitVectorIntUnary(SDValue Op, SelectionDAG &DAG) { +/// Break an operation into 2 half sized ops and then concatenate the results. +static SDValue splitVectorOp(SDValue Op, SelectionDAG &DAG) { + unsigned NumOps = Op.getNumOperands(); EVT VT = Op.getValueType(); + SDLoc dl(Op); + + // Extract the LHS Lo/Hi vectors + SmallVector LoOps(NumOps, SDValue()); + SmallVector HiOps(NumOps, SDValue()); + for (unsigned I = 0; I != NumOps; ++I) { + SDValue SrcOp = Op.getOperand(I); + if (!SrcOp.getValueType().isVector()) { + LoOps[I] = HiOps[I] = SrcOp; + continue; + } + std::tie(LoOps[I], HiOps[I]) = splitVector(SrcOp, DAG, dl); + } + EVT LoVT, HiVT; + std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VT); + return DAG.getNode(ISD::CONCAT_VECTORS, dl, VT, + DAG.getNode(Op.getOpcode(), dl, LoVT, LoOps), + DAG.getNode(Op.getOpcode(), dl, HiVT, HiOps)); +} + +/// Break an unary integer operation into 2 half sized ops and then +/// concatenate the result back. +static SDValue splitVectorIntUnary(SDValue Op, SelectionDAG &DAG) { // Make sure we only try to split 256/512-bit types to avoid creating // narrow vectors. + EVT VT = Op.getValueType(); assert((Op.getOperand(0).getValueType().is256BitVector() || Op.getOperand(0).getValueType().is512BitVector()) && (VT.is256BitVector() || VT.is512BitVector()) && "Unsupported VT!"); assert(Op.getOperand(0).getValueType().getVectorNumElements() == VT.getVectorNumElements() && "Unexpected VTs!"); - - SDLoc dl(Op); - - // Extract the Lo/Hi vectors - SDValue Lo, Hi; - std::tie(Lo, Hi) = splitVector(Op.getOperand(0), DAG, dl); - - EVT LoVT, HiVT; - std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VT); - return DAG.getNode(ISD::CONCAT_VECTORS, dl, VT, - DAG.getNode(Op.getOpcode(), dl, LoVT, Lo), - DAG.getNode(Op.getOpcode(), dl, HiVT, Hi)); + return splitVectorOp(Op, DAG); } /// Break a binary integer operation into 2 half sized ops and then /// concatenate the result back. static SDValue splitVectorIntBinary(SDValue Op, SelectionDAG &DAG) { - EVT VT = Op.getValueType(); - // Sanity check that all the types match. + EVT VT = Op.getValueType(); assert(Op.getOperand(0).getValueType() == VT && Op.getOperand(1).getValueType() == VT && "Unexpected VTs!"); assert((VT.is256BitVector() || VT.is512BitVector()) && "Unsupported VT!"); - - SDLoc dl(Op); - - // Extract the LHS Lo/Hi vectors - SDValue LHS1, LHS2; - std::tie(LHS1, LHS2) = splitVector(Op.getOperand(0), DAG, dl); - - // Extract the RHS Lo/Hi vectors - SDValue RHS1, RHS2; - std::tie(RHS1, RHS2) = splitVector(Op.getOperand(1), DAG, dl); - - EVT LoVT, HiVT; - std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VT); - return DAG.getNode(ISD::CONCAT_VECTORS, dl, VT, - DAG.getNode(Op.getOpcode(), dl, LoVT, LHS1, RHS1), - DAG.getNode(Op.getOpcode(), dl, HiVT, LHS2, RHS2)); + return splitVectorOp(Op, DAG); } // Helper for splitting operands of an operation to legal target size and