diff options
| author | Simon Pilgrim <llvm-dev@redking.me.uk> | 2016-11-27 21:08:19 +0000 |
|---|---|---|
| committer | Simon Pilgrim <llvm-dev@redking.me.uk> | 2016-11-27 21:08:19 +0000 |
| commit | 91d6f5fbc1ab57b867917b26990870975e2b56c8 (patch) | |
| tree | 8f9a6a9869f554bea13700d96698b4ed1e5782cb /llvm/lib | |
| parent | 8ca30ab0c5daf44bc6e86c257ecb5da01345fc28 (diff) | |
| download | bcm5719-llvm-91d6f5fbc1ab57b867917b26990870975e2b56c8.tar.gz bcm5719-llvm-91d6f5fbc1ab57b867917b26990870975e2b56c8.zip | |
[X86][SSE] Add support for combining target shuffles to 128/256-bit PSLL/PSRL bit shifts
llvm-svn: 288006
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.cpp | 71 |
1 files changed, 22 insertions, 49 deletions
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index 74687213856..25ad59f919b 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -25480,63 +25480,36 @@ static bool matchUnaryPermuteVectorShuffle(MVT MaskVT, ArrayRef<int> Mask, unsigned &Shuffle, MVT &ShuffleVT, unsigned &PermuteImm) { unsigned NumMaskElts = Mask.size(); - unsigned NumLanes = MaskVT.getSizeInBits() / 128; - unsigned NumEltsPerLane = NumMaskElts / NumLanes; bool FloatDomain = MaskVT.isFloatingPoint(); - // Attempt to match against PSLLDQ/PSRLDQ byte shifts. - // TODO: Share common code with lowerVectorShuffleAsShift? - // - // PSLLDQ : (little-endian) left byte shift - // [ zz, 0, 1, 2, 3, 4, 5, 6] - // [ zz, zz, -1, -1, 2, 3, 4, -1] - // [ zz, zz, zz, zz, zz, zz, -1, 1] - // PSRLDQ : (little-endian) right byte shift - // [ 5, 6, 7, zz, zz, zz, zz, zz] - // [ -1, 5, 6, 7, zz, zz, zz, zz] - // [ 1, 2, -1, -1, -1, -1, zz, zz] + bool ContainsZeros = false; + SmallBitVector Zeroable(NumMaskElts, false); + for (unsigned i = 0; i != NumMaskElts; ++i) { + int M = Mask[i]; + Zeroable[i] = isUndefOrZero(M); + ContainsZeros |= (M == SM_SentinelZero); + } + + // Attempt to match against byte/bit shifts. + // FIXME: Add 512-bit support. if (!FloatDomain && ((MaskVT.is128BitVector() && Subtarget.hasSSE2()) || (MaskVT.is256BitVector() && Subtarget.hasAVX2()))) { - for (unsigned Shift = 1; Shift != NumEltsPerLane; ++Shift) { - bool IsVSHLDQ = true; - bool IsVSRLDQ = true; - - for (unsigned Lane = 0; Lane != NumLanes; ++Lane) { - unsigned Base = Lane * NumEltsPerLane; - unsigned Ofs = NumEltsPerLane - Shift; - - IsVSHLDQ &= isUndefOrZeroInRange(Mask, Base, Shift); - IsVSHLDQ &= isSequentialOrUndefInRange(Mask, Base + Shift, Ofs, Base); - - IsVSRLDQ &= isUndefOrZeroInRange(Mask, Base + Ofs, Shift); - IsVSRLDQ &= isSequentialOrUndefInRange(Mask, Base, Ofs, Base + Shift); - - if (!IsVSHLDQ && !IsVSRLDQ) - break; - } - - if (IsVSHLDQ) { - Shuffle = X86ISD::VSHLDQ; - ShuffleVT = MVT::getVectorVT(MVT::i8, NumLanes * 16); - PermuteImm = Shift * (MaskVT.getScalarSizeInBits() / 8); - return true; - } - if (IsVSRLDQ) { - Shuffle = X86ISD::VSRLDQ; - ShuffleVT = MVT::getVectorVT(MVT::i8, NumLanes * 16); - PermuteImm = Shift * (MaskVT.getScalarSizeInBits() / 8); - return true; - } + int ShiftAmt = matchVectorShuffleAsShift(ShuffleVT, Shuffle, + MaskVT.getScalarSizeInBits(), Mask, + 0, Zeroable, Subtarget); + if (0 < ShiftAmt) { + PermuteImm = (unsigned)ShiftAmt; + return true; } } // Ensure we don't contain any zero elements. - for (int M : Mask) { - if (M == SM_SentinelZero) - return false; - assert(SM_SentinelUndef <= M && M < (int)Mask.size() && - "Expected unary shuffle"); - } + if (ContainsZeros) + return false; + + assert(llvm::all_of(Mask, [&](int M) { + return SM_SentinelUndef <= M && M < (int)NumMaskElts; + }) && "Expected unary shuffle"); unsigned InputSizeInBits = MaskVT.getSizeInBits(); unsigned MaskScalarSizeInBits = InputSizeInBits / Mask.size(); |

