diff options
author | Chandler Carruth <chandlerc@gmail.com> | 2014-09-23 10:08:29 +0000 |
---|---|---|
committer | Chandler Carruth <chandlerc@gmail.com> | 2014-09-23 10:08:29 +0000 |
commit | 6d5916a2d7882725b86e19d0acb3061c46aa5833 (patch) | |
tree | 545f7c77f627a526450c3aaa106f65a2aa8cae01 /llvm/lib/Target/X86/Utils/X86ShuffleDecode.cpp | |
parent | e4e893bb360f823b73597b5a4e9ff917b883ba3e (diff) | |
download | bcm5719-llvm-6d5916a2d7882725b86e19d0acb3061c46aa5833.tar.gz bcm5719-llvm-6d5916a2d7882725b86e19d0acb3061c46aa5833.zip |
[x86] Teach the AVX1 path of the new vector shuffle lowering one more
trick that I missed.
VPERMILPS has a non-immediate memory operand mode that allows it to do
asymetric shuffles in the two 128-bit lanes. Use this rather than two
shuffles and a blend.
However, it turns out the variable shuffle path to VPERMILPS (and
VPERMILPD, although that one offers no functional differenc from the
immediate operand other than variability) wasn't even plumbed through
codegen. Do such plumbing so that we can reasonably emit
a variable-masked VPERMILP instruction. Also plumb basic comment parsing
and printing through so that the tests are reasonable.
There are still a few tests which don't show the shuffle pattern. These
are tests with undef lanes. I'll teach the shuffle decoding and printing
to handle undef mask entries in a follow-up. I've looked at the masks
and they seem reasonable.
llvm-svn: 218300
Diffstat (limited to 'llvm/lib/Target/X86/Utils/X86ShuffleDecode.cpp')
-rw-r--r-- | llvm/lib/Target/X86/Utils/X86ShuffleDecode.cpp | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/llvm/lib/Target/X86/Utils/X86ShuffleDecode.cpp b/llvm/lib/Target/X86/Utils/X86ShuffleDecode.cpp index 6d42a101b0e..9aca2da4902 100644 --- a/llvm/lib/Target/X86/Utils/X86ShuffleDecode.cpp +++ b/llvm/lib/Target/X86/Utils/X86ShuffleDecode.cpp @@ -287,4 +287,27 @@ void DecodeVPERMMask(unsigned Imm, SmallVectorImpl<int> &ShuffleMask) { } } +void DecodeVPERMILPMask(const ConstantDataSequential *C, + SmallVectorImpl<int> &ShuffleMask) { + Type *MaskTy = C->getType(); + assert(MaskTy->isVectorTy() && "Expected a vector constant mask!"); + assert(MaskTy->getVectorElementType()->isIntegerTy() && + "Expected integer constant mask elements!"); + int ElementBits = MaskTy->getScalarSizeInBits(); + int NumElements = MaskTy->getVectorNumElements(); + assert((NumElements == 2 || NumElements == 4 || NumElements == 8) && + "Unexpected number of vector elements."); + assert((unsigned)NumElements == C->getNumElements() && + "Constant mask has a different number of elements!"); + + ShuffleMask.reserve(NumElements); + for (int i = 0; i < NumElements; ++i) { + int Base = (i * ElementBits / 128) * (128 / ElementBits); + uint64_t Element = C->getElementAsInteger(i); + // Only the least significant 2 bits of the integer are used. + int Index = Base + (Element & 0x3); + ShuffleMask.push_back(Index); + } +} + } // llvm namespace |