[X86] Add generic splitVectorOp helper. NFC

Update splitVectorIntUnary/splitVectorIntBinary to use this internally, after some operand type sanity checks.

Avoid code duplication and makes it easier to split other vector instruction forms in the future.
This commit is contained in:
Simon Pilgrim 2021-11-15 17:57:33 +00:00
parent f59307bfdc
commit 441de2536b
1 changed files with 30 additions and 32 deletions

View File

@ -6293,57 +6293,55 @@ static std::pair<SDValue, SDValue> 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<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