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<SDValue> LoOps(NumOps, SDValue());
+ SmallVector<SDValue> 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