summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Stellard <thomas.stellard@amd.com>2013-11-22 00:39:23 +0000
committerTom Stellard <thomas.stellard@amd.com>2013-11-22 00:39:23 +0000
commitb7bad852f404f562f93e9add3e0ef8977eb3c677 (patch)
tree5a4a9bcbc349313af442cc64809eb81dca021e0d
parent2d5d104c5b945a214c117328fd9982360782cef0 (diff)
downloadllvm-b7bad852f404f562f93e9add3e0ef8977eb3c677.tar.gz
llvm-b7bad852f404f562f93e9add3e0ef8977eb3c677.tar.bz2
llvm-b7bad852f404f562f93e9add3e0ef8977eb3c677.tar.xz
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
-rw-r--r--include/llvm/CodeGen/SelectionDAG.h3
-rw-r--r--lib/CodeGen/SelectionDAG/DAGCombiner.cpp56
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp8
3 files changed, 45 insertions, 22 deletions
diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h
index 4b3f904bc6..82becca315 100644
--- a/include/llvm/CodeGen/SelectionDAG.h
+++ b/include/llvm/CodeGen/SelectionDAG.h
@@ -1149,7 +1149,8 @@ public:
/// SplitVectorOperand - Split the node's operand with EXTRACT_SUBVECTOR and
/// 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));
}
diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 15b4ddc033..20b0981e97 100644
--- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -4327,6 +4327,23 @@ SDValue DAGCombiner::visitSELECT(SDNode *N) {
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 N0 = N->getOperand(0);
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
- // targets expected SETCC result type. This will ensure that SETCC and VSELECT
- // are both split by the type legalizer. This is done to prevent the type
- // legalizer from unrolling SETCC into scalar comparions.
- EVT SelectVT = N->getValueType(0);
- EVT MaskVT = getSetCCResultType(SelectVT);
- assert(MaskVT.isVector() && "Expected a vector type.");
- if (N0.getOpcode() == ISD::SETCC && N0.getValueType() != MaskVT) {
- SDLoc MaskDL(N0);
+ // If the VSELECT result requires splitting and the mask is provided by a
+ // SETCC, then split both nodes and its operands before legalization. This
+ // prevents the type legalizer from unrolling SETCC into scalar comparisons
+ // and enables future optimizations (e.g. min/max pattern matching on X86).
+ if (N0.getOpcode() == ISD::SETCC) {
+ EVT VT = N->getValueType(0);
+
+ // Check if any splitting is required.
+ if (TLI.getTypeAction(*DAG.getContext(), VT) !=
+ TargetLowering::TypeSplitVector)
+ return SDValue();
- // Extend the mask to the desired value type.
- ISD::NodeType ExtendCode =
- TargetLowering::getExtendForContent(TLI.getBooleanContents(true));
- SDValue Mask = DAG.getNode(ExtendCode, MaskDL, MaskVT, N0);
+ 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);
- AddToWorkList(Mask.getNode());
+ Lo = DAG.getNode(N->getOpcode(), DL, LL.getValueType(), CCLo, LL, RL);
+ Hi = DAG.getNode(N->getOpcode(), DL, LH.getValueType(), CCHi, LH, RH);
- SDValue LHS = N->getOperand(1);
- SDValue RHS = N->getOperand(2);
+ // 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::VSELECT, DL, SelectVT, Mask, LHS, RHS);
+ return DAG.getNode(ISD::CONCAT_VECTORS, DL, VT, Lo, Hi);
}
return SDValue();
diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp b/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp
index 9e97c49ddf..b3174fd373 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp
@@ -488,11 +488,11 @@ void DAGTypeLegalizer::SplitRes_SELECT(SDNode *N, SDValue &Lo,
SDValue Cond = N->getOperand(0);
CL = CH = Cond;
if (Cond.getValueType().isVector()) {
- if (Cond.getOpcode() == ISD::SETCC) {
- assert(Cond.getValueType() == getSetCCResultType(N->getValueType(0)) &&
- "Condition has not been prepared for split!");
+ // Check if there are already splitted versions of the vector available and
+ // use those instead of splitting the mask operand again.
+ if (getTypeAction(Cond.getValueType()) == TargetLowering::TypeSplitVector)
GetSplitVector(Cond, CL, CH);
- } else
+ else
llvm::tie(CL, CH) = DAG.SplitVector(Cond, dl);
}