diff options
author | Simon Pilgrim <llvm-dev@redking.me.uk> | 2017-03-23 16:09:34 +0000 |
---|---|---|
committer | Simon Pilgrim <llvm-dev@redking.me.uk> | 2017-03-23 16:09:34 +0000 |
commit | 1c048ab6ba2321be0ae4a6dd8052b12f21963943 (patch) | |
tree | 31c2c6fda042d1c97ef55a471e3a300d9337f3cf /llvm/lib/Target/X86/X86ISelLowering.cpp | |
parent | 1fb4064531161167324a35aa860f67f3005f3f24 (diff) | |
download | bcm5719-llvm-1c048ab6ba2321be0ae4a6dd8052b12f21963943.tar.gz bcm5719-llvm-1c048ab6ba2321be0ae4a6dd8052b12f21963943.zip |
[X86][SSE] Extract elements from narrower shuffle masks.
Add support for widening narrow shuffle masks so we can directly extract from the relevant input vector of the shuffle.
llvm-svn: 298616
Diffstat (limited to 'llvm/lib/Target/X86/X86ISelLowering.cpp')
-rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.cpp | 35 |
1 files changed, 21 insertions, 14 deletions
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index f4685c14874..d7fe86c7730 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -29165,9 +29165,10 @@ static SDValue combineExtractWithShuffle(SDNode *N, SelectionDAG &DAG, SDValue Src = N->getOperand(0); SDValue Idx = N->getOperand(1); + EVT VT = N->getValueType(0); EVT SrcVT = Src.getValueType(); EVT SrcSVT = SrcVT.getVectorElementType(); - EVT VT = N->getValueType(0); + unsigned NumSrcElts = SrcVT.getVectorNumElements(); // Don't attempt this for boolean mask vectors or unknown extraction indices. if (SrcSVT == MVT::i1 || !isa<ConstantSDNode>(Idx)) @@ -29179,21 +29180,27 @@ static SDValue combineExtractWithShuffle(SDNode *N, SelectionDAG &DAG, if (!resolveTargetShuffleInputs(peekThroughBitcasts(Src), Ops, Mask)) return SDValue(); - // At the moment we can only narrow a shuffle mask to handle extractions - // of smaller scalars. - // TODO - investigate support for wider shuffle masks with known upper - // undef/zero elements for implicit zero-extension. - unsigned NumMaskElts = Mask.size(); - if ((SrcVT.getVectorNumElements() % NumMaskElts) != 0) - return SDValue(); - - int Scale = SrcVT.getVectorNumElements() / NumMaskElts; - if (Scale != 1) { - SmallVector<int, 16> ScaledMask; - scaleShuffleMask(Scale, Mask, ScaledMask); - Mask = ScaledMask; + // Attempt to narrow/widen the shuffle mask to the correct size. + if (Mask.size() != NumSrcElts) { + if ((NumSrcElts % Mask.size()) == 0) { + SmallVector<int, 16> ScaledMask; + int Scale = NumSrcElts / Mask.size(); + scaleShuffleMask(Scale, Mask, ScaledMask); + Mask = std::move(ScaledMask); + } else if ((Mask.size() % NumSrcElts) == 0) { + SmallVector<int, 16> WidenedMask; + while (Mask.size() > NumSrcElts && + canWidenShuffleElements(Mask, WidenedMask)) + Mask = std::move(WidenedMask); + // TODO - investigate support for wider shuffle masks with known upper + // undef/zero elements for implicit zero-extension. + } } + // Check if narrowing/widening failed. + if (Mask.size() != NumSrcElts) + return SDValue(); + int SrcIdx = Mask[N->getConstantOperandVal(1)]; SDLoc dl(N); |