diff options
author | Nadav Rotem <nadav.rotem@intel.com> | 2011-10-19 09:45:11 +0000 |
---|---|---|
committer | Nadav Rotem <nadav.rotem@intel.com> | 2011-10-19 09:45:11 +0000 |
commit | 6652e22bad8962b79430108a7fed10f83a59b3a3 (patch) | |
tree | e317b2682a3e5063509f58c3cfce577777f59a3e /llvm/lib/CodeGen | |
parent | f96a5bc15b8f74bc0bc523f746f0fcc723693488 (diff) | |
download | bcm5719-llvm-6652e22bad8962b79430108a7fed10f83a59b3a3.tar.gz bcm5719-llvm-6652e22bad8962b79430108a7fed10f83a59b3a3.zip |
Add support for the vector-widening of vselect and vector-setcc
llvm-svn: 142488
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h | 1 | ||||
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp | 28 |
2 files changed, 28 insertions, 1 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h index abacdac686b..0a8db0897b5 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h @@ -633,6 +633,7 @@ private: SDValue WidenVecOp_EXTRACT_VECTOR_ELT(SDNode *N); SDValue WidenVecOp_EXTRACT_SUBVECTOR(SDNode *N); SDValue WidenVecOp_STORE(SDNode* N); + SDValue WidenVecOp_SETCC(SDNode* N, unsigned ResNo); SDValue WidenVecOp_Convert(SDNode *N); diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp index 107a42b2951..7fc7525a5b9 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp @@ -1239,6 +1239,7 @@ void DAGTypeLegalizer::WidenVectorResult(SDNode *N, unsigned ResNo) { case ISD::LOAD: Res = WidenVecRes_LOAD(N); break; case ISD::SCALAR_TO_VECTOR: Res = WidenVecRes_SCALAR_TO_VECTOR(N); break; case ISD::SIGN_EXTEND_INREG: Res = WidenVecRes_InregOp(N); break; + case ISD::VSELECT: case ISD::SELECT: Res = WidenVecRes_SELECT(N); break; case ISD::SELECT_CC: Res = WidenVecRes_SELECT_CC(N); break; case ISD::SETCC: Res = WidenVecRes_SETCC(N); break; @@ -1928,7 +1929,7 @@ SDValue DAGTypeLegalizer::WidenVecRes_SELECT(SDNode *N) { SDValue InOp1 = GetWidenedVector(N->getOperand(1)); SDValue InOp2 = GetWidenedVector(N->getOperand(2)); assert(InOp1.getValueType() == WidenVT && InOp2.getValueType() == WidenVT); - return DAG.getNode(ISD::SELECT, N->getDebugLoc(), + return DAG.getNode(N->getOpcode(), N->getDebugLoc(), WidenVT, Cond1, InOp1, InOp2); } @@ -2032,6 +2033,7 @@ bool DAGTypeLegalizer::WidenVectorOperand(SDNode *N, unsigned ResNo) { case ISD::EXTRACT_SUBVECTOR: Res = WidenVecOp_EXTRACT_SUBVECTOR(N); break; case ISD::EXTRACT_VECTOR_ELT: Res = WidenVecOp_EXTRACT_VECTOR_ELT(N); break; case ISD::STORE: Res = WidenVecOp_STORE(N); break; + case ISD::SETCC: Res = WidenVecOp_SETCC(N, ResNo); break; case ISD::FP_EXTEND: case ISD::FP_TO_SINT: @@ -2165,6 +2167,30 @@ SDValue DAGTypeLegalizer::WidenVecOp_STORE(SDNode *N) { MVT::Other,&StChain[0],StChain.size()); } +SDValue DAGTypeLegalizer::WidenVecOp_SETCC(SDNode *N, unsigned ResNo) { + assert(ResNo < 2 && "Invalid res num to widen"); + SDValue InOp0 = GetWidenedVector(N->getOperand(0)); + SDValue InOp1 = GetWidenedVector(N->getOperand(1)); + EVT VT = InOp0.getValueType(); + DebugLoc dl = N->getDebugLoc(); + + // WARNING: In this code we widen the compare instruction with garbage. + // This garbage may contain denormal floats which may be slow. Is this a real + // concern ? Should we zero the unused lanes if this is a float compare ? + + SDValue Zero = DAG.getIntPtrConstant(0); + EVT ResVT = EVT::getVectorVT(*DAG.getContext(), + N->getValueType(0).getVectorElementType(), + VT.getVectorNumElements()); + + SDValue WideSETCC = DAG.getNode(ISD::SETCC, N->getDebugLoc(), + ResVT, InOp0, InOp1, N->getOperand(2)); + + return DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, N->getValueType(0), + WideSETCC, Zero); +} + + //===----------------------------------------------------------------------===// // Vector Widening Utilities //===----------------------------------------------------------------------===// |