Skip to content

Commit

Permalink
[X86] Add generic splitVectorOp helper. NFC
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
RKSimon committed Nov 15, 2021
1 parent f59307b commit 441de25
Showing 1 changed file with 30 additions and 32 deletions.
62 changes: 30 additions & 32 deletions llvm/lib/Target/X86/X86ISelLowering.cpp
Expand Up @@ -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
Expand Down

0 comments on commit 441de25

Please sign in to comment.