diff options
author | Nate Begeman <natebegeman@mac.com> | 2009-04-27 18:41:29 +0000 |
---|---|---|
committer | Nate Begeman <natebegeman@mac.com> | 2009-04-27 18:41:29 +0000 |
commit | 543d214c596c7c0f186038ddfe00462563b75ca8 (patch) | |
tree | 0b13ccb79eb37ff6bb74f3be7234826602c7aff1 /lib/Target/CellSPU | |
parent | c40ab84e4024e1d7fc690eeb41edfd18c79beea2 (diff) | |
download | external_llvm-543d214c596c7c0f186038ddfe00462563b75ca8.zip external_llvm-543d214c596c7c0f186038ddfe00462563b75ca8.tar.gz external_llvm-543d214c596c7c0f186038ddfe00462563b75ca8.tar.bz2 |
2nd attempt, fixing SSE4.1 issues and implementing feedback from duncan.
PR2957
ISD::VECTOR_SHUFFLE now stores an array of integers representing the shuffle
mask internal to the node, rather than taking a BUILD_VECTOR of ConstantSDNodes
as the shuffle mask. A value of -1 represents UNDEF.
In addition to eliminating the creation of illegal BUILD_VECTORS just to
represent shuffle masks, we are better about canonicalizing the shuffle mask,
resulting in substantially better code for some classes of shuffles.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@70225 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/CellSPU')
-rw-r--r-- | lib/Target/CellSPU/SPUISelLowering.cpp | 69 |
1 files changed, 32 insertions, 37 deletions
diff --git a/lib/Target/CellSPU/SPUISelLowering.cpp b/lib/Target/CellSPU/SPUISelLowering.cpp index c07e6d5..cef87e9 100644 --- a/lib/Target/CellSPU/SPUISelLowering.cpp +++ b/lib/Target/CellSPU/SPUISelLowering.cpp @@ -1670,9 +1670,9 @@ SPU::LowerV2I64Splat(MVT OpVT, SelectionDAG& DAG, uint64_t SplatVal, /// \note /// SPUISD::SHUFB is eventually selected as Cell's <i>shufb</i> instructions. static SDValue LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) { + const ShuffleVectorSDNode *SVN = cast<ShuffleVectorSDNode>(Op); SDValue V1 = Op.getOperand(0); SDValue V2 = Op.getOperand(1); - SDValue PermMask = Op.getOperand(2); DebugLoc dl = Op.getDebugLoc(); if (V2.getOpcode() == ISD::UNDEF) V2 = V1; @@ -1703,39 +1703,40 @@ static SDValue LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) { } else assert(0 && "Unhandled vector type in LowerVECTOR_SHUFFLE"); - for (unsigned i = 0; i != PermMask.getNumOperands(); ++i) { - if (PermMask.getOperand(i).getOpcode() != ISD::UNDEF) { - unsigned SrcElt = cast<ConstantSDNode > (PermMask.getOperand(i))->getZExtValue(); + for (unsigned i = 0; i != MaxElts; ++i) { + if (SVN->getMaskElt(i) < 0) + continue; + + unsigned SrcElt = SVN->getMaskElt(i); - if (monotonic) { - if (SrcElt >= V2EltIdx0) { - if (1 >= (++EltsFromV2)) { - V2Elt = (V2EltIdx0 - SrcElt) << 2; - } - } else if (CurrElt != SrcElt) { - monotonic = false; + if (monotonic) { + if (SrcElt >= V2EltIdx0) { + if (1 >= (++EltsFromV2)) { + V2Elt = (V2EltIdx0 - SrcElt) << 2; } - - ++CurrElt; + } else if (CurrElt != SrcElt) { + monotonic = false; } - if (rotate) { - if (PrevElt > 0 && SrcElt < MaxElts) { - if ((PrevElt == SrcElt - 1) - || (PrevElt == MaxElts - 1 && SrcElt == 0)) { - PrevElt = SrcElt; - if (SrcElt == 0) - V0Elt = i; - } else { - rotate = false; - } - } else if (PrevElt == 0) { - // First time through, need to keep track of previous element + ++CurrElt; + } + + if (rotate) { + if (PrevElt > 0 && SrcElt < MaxElts) { + if ((PrevElt == SrcElt - 1) + || (PrevElt == MaxElts - 1 && SrcElt == 0)) { PrevElt = SrcElt; + if (SrcElt == 0) + V0Elt = i; } else { - // This isn't a rotation, takes elements from vector 2 rotate = false; } + } else if (PrevElt == 0) { + // First time through, need to keep track of previous element + PrevElt = SrcElt; + } else { + // This isn't a rotation, takes elements from vector 2 + rotate = false; } } } @@ -1768,17 +1769,11 @@ static SDValue LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) { unsigned BytesPerElement = EltVT.getSizeInBits()/8; SmallVector<SDValue, 16> ResultMask; - for (unsigned i = 0, e = PermMask.getNumOperands(); i != e; ++i) { - unsigned SrcElt; - if (PermMask.getOperand(i).getOpcode() == ISD::UNDEF) - SrcElt = 0; - else - SrcElt = cast<ConstantSDNode>(PermMask.getOperand(i))->getZExtValue(); - - for (unsigned j = 0; j < BytesPerElement; ++j) { - ResultMask.push_back(DAG.getConstant(SrcElt*BytesPerElement+j, - MVT::i8)); - } + for (unsigned i = 0, e = MaxElts; i != e; ++i) { + unsigned SrcElt = SVN->getMaskElt(i) < 0 ? 0 : SVN->getMaskElt(i); + + for (unsigned j = 0; j < BytesPerElement; ++j) + ResultMask.push_back(DAG.getConstant(SrcElt*BytesPerElement+j,MVT::i8)); } SDValue VPermMask = DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v16i8, |