summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorSimon Pilgrim <llvm-dev@redking.me.uk>2016-11-27 21:08:19 +0000
committerSimon Pilgrim <llvm-dev@redking.me.uk>2016-11-27 21:08:19 +0000
commit91d6f5fbc1ab57b867917b26990870975e2b56c8 (patch)
tree8f9a6a9869f554bea13700d96698b4ed1e5782cb /llvm/lib
parent8ca30ab0c5daf44bc6e86c257ecb5da01345fc28 (diff)
downloadbcm5719-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.cpp71
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();
OpenPOWER on IntegriCloud