diff options
author | Justin Holewinski <jholewinski@nvidia.com> | 2012-11-29 14:26:28 +0000 |
---|---|---|
committer | Justin Holewinski <jholewinski@nvidia.com> | 2012-11-29 14:26:28 +0000 |
commit | 7f128ea00c5358729906a9b98f844e887a1c3d73 (patch) | |
tree | 4f4e1f0e4817e64578d6cc2f0fac73f3a4efb935 /lib/CodeGen | |
parent | 3d200255d5b93344c1ab0a5ba4b47a52cfa5893e (diff) | |
download | external_llvm-7f128ea00c5358729906a9b98f844e887a1c3d73.zip external_llvm-7f128ea00c5358729906a9b98f844e887a1c3d73.tar.gz external_llvm-7f128ea00c5358729906a9b98f844e887a1c3d73.tar.bz2 |
Teach the legalizer how to handle operands for VSELECT nodes
If we need to split the operand of a VSELECT, it must be the mask operand. We
split the entire VSELECT operand with EXTRACT_SUBVECTOR.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@168883 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/SelectionDAG/LegalizeTypes.h | 1 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp | 60 |
2 files changed, 60 insertions, 1 deletions
diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypes.h b/lib/CodeGen/SelectionDAG/LegalizeTypes.h index 20b7ce6..8464b7d 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeTypes.h +++ b/lib/CodeGen/SelectionDAG/LegalizeTypes.h @@ -578,6 +578,7 @@ private: // Vector Operand Splitting: <128 x ty> -> 2 x <64 x ty>. bool SplitVectorOperand(SDNode *N, unsigned OpNo); + SDValue SplitVecOp_VSELECT(SDNode *N, unsigned OpNo); SDValue SplitVecOp_UnaryOp(SDNode *N); SDValue SplitVecOp_BITCAST(SDNode *N); diff --git a/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp index d51a6eb..595d83b 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp @@ -1030,7 +1030,9 @@ bool DAGTypeLegalizer::SplitVectorOperand(SDNode *N, unsigned OpNo) { case ISD::STORE: Res = SplitVecOp_STORE(cast<StoreSDNode>(N), OpNo); break; - + case ISD::VSELECT: + Res = SplitVecOp_VSELECT(N, OpNo); + break; case ISD::CTTZ: case ISD::CTLZ: case ISD::CTPOP: @@ -1064,6 +1066,62 @@ bool DAGTypeLegalizer::SplitVectorOperand(SDNode *N, unsigned OpNo) { return false; } +SDValue DAGTypeLegalizer::SplitVecOp_VSELECT(SDNode *N, unsigned OpNo) { + // The only possibility for an illegal operand is the mask, since result type + // legalization would have handled this node already otherwise. + assert(OpNo == 0 && "Illegal operand must be mask"); + + SDValue Mask = N->getOperand(0); + SDValue Src0 = N->getOperand(1); + SDValue Src1 = N->getOperand(2); + DebugLoc DL = N->getDebugLoc(); + EVT MaskVT = Mask.getValueType(); + assert(MaskVT.isVector() && "VSELECT without a vector mask?"); + + SDValue Lo, Hi; + GetSplitVector(N->getOperand(0), Lo, Hi); + + unsigned LoNumElts = Lo.getValueType().getVectorNumElements(); + unsigned HiNumElts = Hi.getValueType().getVectorNumElements(); + assert(LoNumElts == HiNumElts && "Asymmetric vector split?"); + + EVT LoOpVT = EVT::getVectorVT(*DAG.getContext(), + Src0.getValueType().getVectorElementType(), + LoNumElts); + EVT LoMaskVT = EVT::getVectorVT(*DAG.getContext(), + MaskVT.getVectorElementType(), + LoNumElts); + EVT HiOpVT = EVT::getVectorVT(*DAG.getContext(), + Src0.getValueType().getVectorElementType(), + HiNumElts); + EVT HiMaskVT = EVT::getVectorVT(*DAG.getContext(), + MaskVT.getVectorElementType(), + HiNumElts); + + SDValue LoOp0 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, LoOpVT, Src0, + DAG.getIntPtrConstant(0)); + SDValue LoOp1 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, LoOpVT, Src1, + DAG.getIntPtrConstant(0)); + + SDValue HiOp0 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, HiOpVT, Src0, + DAG.getIntPtrConstant(LoNumElts)); + SDValue HiOp1 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, HiOpVT, Src1, + DAG.getIntPtrConstant(LoNumElts)); + + SDValue LoMask = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, LoMaskVT, Mask, + DAG.getIntPtrConstant(0)); + SDValue HiMask = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, HiMaskVT, Mask, + DAG.getIntPtrConstant(LoNumElts)); + + SDValue LoSelect = DAG.getNode(ISD::VSELECT, DL, LoOpVT, LoMask, LoOp0, + LoOp1); + SDValue HiSelect = DAG.getNode(ISD::VSELECT, DL, HiOpVT, HiMask, HiOp0, + HiOp1); + + return DAG.getNode(ISD::CONCAT_VECTORS, DL, Src0.getValueType(), LoSelect, + HiSelect); +} + SDValue DAGTypeLegalizer::SplitVecOp_UnaryOp(SDNode *N) { // The result has a legal vector type, but the input needs splitting. EVT ResVT = N->getValueType(0); |