Skip to content

Commit

Permalink
[LegalizeTypes][VP] Add splitting support for vp.select
Browse files Browse the repository at this point in the history
Split vp.select in a similar way as vselect, splitting also the length
parameter.

Reviewed By: craig.topper

Differential Revision: https://reviews.llvm.org/D116651
  • Loading branch information
victor-eds committed Jan 7, 2022
1 parent 2aed081 commit 38efa68
Show file tree
Hide file tree
Showing 9 changed files with 486 additions and 26 deletions.
3 changes: 3 additions & 0 deletions llvm/include/llvm/CodeGen/SelectionDAG.h
Original file line number Diff line number Diff line change
Expand Up @@ -2001,6 +2001,9 @@ class SelectionDAG {
return SplitVector(N, DL, LoVT, HiVT);
}

/// Split the explicit vector length parameter of a VP operation.
std::pair<SDValue, SDValue> SplitEVL(SDValue N, EVT VecVT, const SDLoc &DL);

/// Split the node's operand with EXTRACT_SUBVECTOR and
/// return the low/high part.
std::pair<SDValue, SDValue> SplitVectorOperand(const SDNode *N, unsigned OpNo)
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1193,7 +1193,7 @@ void DAGTypeLegalizer::ExpandFloatResult(SDNode *N, unsigned ResNo) {
llvm_unreachable("Do not know how to expand the result of this operator!");

case ISD::UNDEF: SplitRes_UNDEF(N, Lo, Hi); break;
case ISD::SELECT: SplitRes_SELECT(N, Lo, Hi); break;
case ISD::SELECT: SplitRes_Select(N, Lo, Hi); break;
case ISD::SELECT_CC: SplitRes_SELECT_CC(N, Lo, Hi); break;

case ISD::MERGE_VALUES: ExpandRes_MERGE_VALUES(N, ResNo, Lo, Hi); break;
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2252,7 +2252,7 @@ void DAGTypeLegalizer::ExpandIntegerResult(SDNode *N, unsigned ResNo) {

case ISD::ARITH_FENCE: SplitRes_ARITH_FENCE(N, Lo, Hi); break;
case ISD::MERGE_VALUES: SplitRes_MERGE_VALUES(N, ResNo, Lo, Hi); break;
case ISD::SELECT: SplitRes_SELECT(N, Lo, Hi); break;
case ISD::SELECT: SplitRes_Select(N, Lo, Hi); break;
case ISD::SELECT_CC: SplitRes_SELECT_CC(N, Lo, Hi); break;
case ISD::UNDEF: SplitRes_UNDEF(N, Lo, Hi); break;
case ISD::FREEZE: SplitRes_FREEZE(N, Lo, Hi); break;
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -1022,7 +1022,7 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer {
void SplitRes_MERGE_VALUES(SDNode *N, unsigned ResNo,
SDValue &Lo, SDValue &Hi);
void SplitRes_ARITH_FENCE (SDNode *N, SDValue &Lo, SDValue &Hi);
void SplitRes_SELECT (SDNode *N, SDValue &Lo, SDValue &Hi);
void SplitRes_Select (SDNode *N, SDValue &Lo, SDValue &Hi);
void SplitRes_SELECT_CC (SDNode *N, SDValue &Lo, SDValue &Hi);
void SplitRes_UNDEF (SDNode *N, SDValue &Lo, SDValue &Hi);
void SplitRes_FREEZE (SDNode *N, SDValue &Lo, SDValue &Hi);
Expand Down
17 changes: 14 additions & 3 deletions llvm/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -506,9 +506,10 @@ void DAGTypeLegalizer::SplitRes_MERGE_VALUES(SDNode *N, unsigned ResNo,
GetSplitOp(Op, Lo, Hi);
}

void DAGTypeLegalizer::SplitRes_SELECT(SDNode *N, SDValue &Lo, SDValue &Hi) {
void DAGTypeLegalizer::SplitRes_Select(SDNode *N, SDValue &Lo, SDValue &Hi) {
SDValue LL, LH, RL, RH, CL, CH;
SDLoc dl(N);
unsigned Opcode = N->getOpcode();
GetSplitOp(N->getOperand(1), LL, LH);
GetSplitOp(N->getOperand(2), RL, RH);

Expand Down Expand Up @@ -539,8 +540,18 @@ void DAGTypeLegalizer::SplitRes_SELECT(SDNode *N, SDValue &Lo, SDValue &Hi) {
std::tie(CL, CH) = DAG.SplitVector(Cond, dl);
}

Lo = DAG.getNode(N->getOpcode(), dl, LL.getValueType(), CL, LL, RL);
Hi = DAG.getNode(N->getOpcode(), dl, LH.getValueType(), CH, LH, RH);
if (Opcode != ISD::VP_SELECT) {
Lo = DAG.getNode(Opcode, dl, LL.getValueType(), CL, LL, RL);
Hi = DAG.getNode(Opcode, dl, LH.getValueType(), CH, LH, RH);
return;
}

SDValue EVLLo, EVLHi;
std::tie(EVLLo, EVLHi) =
DAG.SplitEVL(N->getOperand(3), N->getValueType(0), dl);

Lo = DAG.getNode(Opcode, dl, LL.getValueType(), CL, LL, RL, EVLLo);
Hi = DAG.getNode(Opcode, dl, LH.getValueType(), CH, LH, RH, EVLHi);
}

void DAGTypeLegalizer::SplitRes_SELECT_CC(SDNode *N, SDValue &Lo,
Expand Down
21 changes: 5 additions & 16 deletions llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -914,7 +914,8 @@ void DAGTypeLegalizer::SplitVectorResult(SDNode *N, unsigned ResNo) {

case ISD::MERGE_VALUES: SplitRes_MERGE_VALUES(N, ResNo, Lo, Hi); break;
case ISD::VSELECT:
case ISD::SELECT: SplitRes_SELECT(N, Lo, Hi); break;
case ISD::SELECT:
case ISD::VP_SELECT: SplitRes_Select(N, Lo, Hi); break;
case ISD::SELECT_CC: SplitRes_SELECT_CC(N, Lo, Hi); break;
case ISD::UNDEF: SplitRes_UNDEF(N, Lo, Hi); break;
case ISD::BITCAST: SplitVecRes_BITCAST(N, Lo, Hi); break;
Expand Down Expand Up @@ -1140,21 +1141,9 @@ void DAGTypeLegalizer::SplitVecRes_BinOp(SDNode *N, SDValue &Lo, SDValue &Hi) {
else
std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, SDLoc(Mask));

// Split the vector length parameter.
// %evl -> umin(%evl, %halfnumelts) and usubsat(%evl - %halfnumelts).
SDValue EVL = N->getOperand(3);
EVT VecVT = N->getValueType(0);
EVT EVLVT = EVL.getValueType();
assert(VecVT.getVectorElementCount().isKnownEven() &&
"Expecting the mask to be an evenly-sized vector");
unsigned HalfMinNumElts = VecVT.getVectorMinNumElements() / 2;
SDValue HalfNumElts =
VecVT.isFixedLengthVector()
? DAG.getConstant(HalfMinNumElts, dl, EVLVT)
: DAG.getVScale(dl, EVLVT,
APInt(EVLVT.getScalarSizeInBits(), HalfMinNumElts));
SDValue EVLLo = DAG.getNode(ISD::UMIN, dl, EVLVT, EVL, HalfNumElts);
SDValue EVLHi = DAG.getNode(ISD::USUBSAT, dl, EVLVT, EVL, HalfNumElts);
SDValue EVLLo, EVLHi;
std::tie(EVLLo, EVLHi) =
DAG.SplitEVL(N->getOperand(3), N->getValueType(0), dl);

Lo = DAG.getNode(Opcode, dl, LHSLo.getValueType(),
{LHSLo, RHSLo, MaskLo, EVLLo}, Flags);
Expand Down
17 changes: 17 additions & 0 deletions llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10648,6 +10648,23 @@ SelectionDAG::SplitVector(const SDValue &N, const SDLoc &DL, const EVT &LoVT,
return std::make_pair(Lo, Hi);
}

std::pair<SDValue, SDValue> SelectionDAG::SplitEVL(SDValue N, EVT VecVT,
const SDLoc &DL) {
// Split the vector length parameter.
// %evl -> umin(%evl, %halfnumelts) and usubsat(%evl - %halfnumelts).
EVT VT = N.getValueType();
assert(VecVT.getVectorElementCount().isKnownEven() &&
"Expecting the mask to be an evenly-sized vector");
unsigned HalfMinNumElts = VecVT.getVectorMinNumElements() / 2;
SDValue HalfNumElts =
VecVT.isFixedLengthVector()
? getConstant(HalfMinNumElts, DL, VT)
: getVScale(DL, VT, APInt(VT.getScalarSizeInBits(), HalfMinNumElts));
SDValue Lo = getNode(ISD::UMIN, DL, VT, N, HalfNumElts);
SDValue Hi = getNode(ISD::USUBSAT, DL, VT, N, HalfNumElts);
return std::make_pair(Lo, Hi);
}

/// Widen the vector up to the next power of two using INSERT_SUBVECTOR.
SDValue SelectionDAG::WidenVector(const SDValue &N, const SDLoc &DL) {
EVT VT = N.getValueType();
Expand Down
Loading

0 comments on commit 38efa68

Please sign in to comment.