mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-15 04:30:12 +00:00
Split SETCC if VSELECT requires splitting too.
This patch is a rewrite of the original patch commited in r194542. Instead of relying on the type legalizer to do the splitting for us, we now peform the splitting ourselves in the DAG combiner. This is necessary for the case where the vector mask is a legal type after promotion and still wouldn't require splitting. Patch by: Juergen Ributzka NOTE: This is a candidate for the 3.4 branch. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@195397 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
2d5d104c5b
commit
b7bad852f4
@ -1149,7 +1149,8 @@ public:
|
|||||||
|
|
||||||
/// SplitVectorOperand - Split the node's operand with EXTRACT_SUBVECTOR and
|
/// SplitVectorOperand - Split the node's operand with EXTRACT_SUBVECTOR and
|
||||||
/// return the low/high part.
|
/// return the low/high part.
|
||||||
std::pair<SDValue, SDValue> SplitVectorOperand(SDNode *N, unsigned OpNo) {
|
std::pair<SDValue, SDValue> SplitVectorOperand(const SDNode *N, unsigned OpNo)
|
||||||
|
{
|
||||||
return SplitVector(N->getOperand(OpNo), SDLoc(N));
|
return SplitVector(N->getOperand(OpNo), SDLoc(N));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4327,6 +4327,23 @@ SDValue DAGCombiner::visitSELECT(SDNode *N) {
|
|||||||
return SDValue();
|
return SDValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
std::pair<SDValue, SDValue> SplitVSETCC(const SDNode *N, SelectionDAG &DAG) {
|
||||||
|
SDLoc DL(N);
|
||||||
|
EVT LoVT, HiVT;
|
||||||
|
llvm::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(N->getValueType(0));
|
||||||
|
|
||||||
|
// Split the inputs.
|
||||||
|
SDValue Lo, Hi, LL, LH, RL, RH;
|
||||||
|
llvm::tie(LL, LH) = DAG.SplitVectorOperand(N, 0);
|
||||||
|
llvm::tie(RL, RH) = DAG.SplitVectorOperand(N, 1);
|
||||||
|
|
||||||
|
Lo = DAG.getNode(N->getOpcode(), DL, LoVT, LL, RL, N->getOperand(2));
|
||||||
|
Hi = DAG.getNode(N->getOpcode(), DL, HiVT, LH, RH, N->getOperand(2));
|
||||||
|
|
||||||
|
return std::make_pair(Lo, Hi);
|
||||||
|
}
|
||||||
|
|
||||||
SDValue DAGCombiner::visitVSELECT(SDNode *N) {
|
SDValue DAGCombiner::visitVSELECT(SDNode *N) {
|
||||||
SDValue N0 = N->getOperand(0);
|
SDValue N0 = N->getOperand(0);
|
||||||
SDValue N1 = N->getOperand(1);
|
SDValue N1 = N->getOperand(1);
|
||||||
@ -4364,27 +4381,32 @@ SDValue DAGCombiner::visitVSELECT(SDNode *N) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Treat SETCC as a vector mask and promote the result type based on the
|
// If the VSELECT result requires splitting and the mask is provided by a
|
||||||
// targets expected SETCC result type. This will ensure that SETCC and VSELECT
|
// SETCC, then split both nodes and its operands before legalization. This
|
||||||
// are both split by the type legalizer. This is done to prevent the type
|
// prevents the type legalizer from unrolling SETCC into scalar comparisons
|
||||||
// legalizer from unrolling SETCC into scalar comparions.
|
// and enables future optimizations (e.g. min/max pattern matching on X86).
|
||||||
EVT SelectVT = N->getValueType(0);
|
if (N0.getOpcode() == ISD::SETCC) {
|
||||||
EVT MaskVT = getSetCCResultType(SelectVT);
|
EVT VT = N->getValueType(0);
|
||||||
assert(MaskVT.isVector() && "Expected a vector type.");
|
|
||||||
if (N0.getOpcode() == ISD::SETCC && N0.getValueType() != MaskVT) {
|
|
||||||
SDLoc MaskDL(N0);
|
|
||||||
|
|
||||||
// Extend the mask to the desired value type.
|
// Check if any splitting is required.
|
||||||
ISD::NodeType ExtendCode =
|
if (TLI.getTypeAction(*DAG.getContext(), VT) !=
|
||||||
TargetLowering::getExtendForContent(TLI.getBooleanContents(true));
|
TargetLowering::TypeSplitVector)
|
||||||
SDValue Mask = DAG.getNode(ExtendCode, MaskDL, MaskVT, N0);
|
return SDValue();
|
||||||
|
|
||||||
AddToWorkList(Mask.getNode());
|
SDValue Lo, Hi, CCLo, CCHi, LL, LH, RL, RH;
|
||||||
|
llvm::tie(CCLo, CCHi) = SplitVSETCC(N0.getNode(), DAG);
|
||||||
|
llvm::tie(LL, LH) = DAG.SplitVectorOperand(N, 1);
|
||||||
|
llvm::tie(RL, RH) = DAG.SplitVectorOperand(N, 2);
|
||||||
|
|
||||||
SDValue LHS = N->getOperand(1);
|
Lo = DAG.getNode(N->getOpcode(), DL, LL.getValueType(), CCLo, LL, RL);
|
||||||
SDValue RHS = N->getOperand(2);
|
Hi = DAG.getNode(N->getOpcode(), DL, LH.getValueType(), CCHi, LH, RH);
|
||||||
|
|
||||||
return DAG.getNode(ISD::VSELECT, DL, SelectVT, Mask, LHS, RHS);
|
// Add the new VSELECT nodes to the work list in case they need to be split
|
||||||
|
// again.
|
||||||
|
AddToWorkList(Lo.getNode());
|
||||||
|
AddToWorkList(Hi.getNode());
|
||||||
|
|
||||||
|
return DAG.getNode(ISD::CONCAT_VECTORS, DL, VT, Lo, Hi);
|
||||||
}
|
}
|
||||||
|
|
||||||
return SDValue();
|
return SDValue();
|
||||||
|
@ -488,11 +488,11 @@ void DAGTypeLegalizer::SplitRes_SELECT(SDNode *N, SDValue &Lo,
|
|||||||
SDValue Cond = N->getOperand(0);
|
SDValue Cond = N->getOperand(0);
|
||||||
CL = CH = Cond;
|
CL = CH = Cond;
|
||||||
if (Cond.getValueType().isVector()) {
|
if (Cond.getValueType().isVector()) {
|
||||||
if (Cond.getOpcode() == ISD::SETCC) {
|
// Check if there are already splitted versions of the vector available and
|
||||||
assert(Cond.getValueType() == getSetCCResultType(N->getValueType(0)) &&
|
// use those instead of splitting the mask operand again.
|
||||||
"Condition has not been prepared for split!");
|
if (getTypeAction(Cond.getValueType()) == TargetLowering::TypeSplitVector)
|
||||||
GetSplitVector(Cond, CL, CH);
|
GetSplitVector(Cond, CL, CH);
|
||||||
} else
|
else
|
||||||
llvm::tie(CL, CH) = DAG.SplitVector(Cond, dl);
|
llvm::tie(CL, CH) = DAG.SplitVector(Cond, dl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user