diff options
author | Chandler Carruth <chandlerc@gmail.com> | 2014-09-23 11:15:19 +0000 |
---|---|---|
committer | Chandler Carruth <chandlerc@gmail.com> | 2014-09-23 11:15:19 +0000 |
commit | 40592d2dec009c2bb3204c75d195f42ebcada739 (patch) | |
tree | 7ec88defda6227d3591bea6b63dfce3fb1d65797 /llvm/lib/Target/X86/Utils/X86ShuffleDecode.cpp | |
parent | 6d5916a2d7882725b86e19d0acb3061c46aa5833 (diff) | |
download | llvm-40592d2dec009c2bb3204c75d195f42ebcada739.zip llvm-40592d2dec009c2bb3204c75d195f42ebcada739.tar.gz llvm-40592d2dec009c2bb3204c75d195f42ebcada739.tar.bz2 |
[x86] Teach the vector comment parsing and printing to correctly handle
undef in the shuffle mask. This shows up when we're printing comments
during lowering and we still have an IR-level constant hanging around
that models undef.
A nice consequence of this is *much* prettier test cases where the undef
lanes actually show up as undef rather than as a particular set of
values. This also allows us to print shuffle comments in cases that use
undef such as the recently added variable VPERMILPS lowering. Now those
test cases have nice shuffle comments attached with their details.
The shuffle lowering for PSHUFB has been augmented to use undef, and the
shuffle combining has been augmented to comprehend it.
llvm-svn: 218301
Diffstat (limited to 'llvm/lib/Target/X86/Utils/X86ShuffleDecode.cpp')
-rw-r--r-- | llvm/lib/Target/X86/Utils/X86ShuffleDecode.cpp | 102 |
1 files changed, 74 insertions, 28 deletions
diff --git a/llvm/lib/Target/X86/Utils/X86ShuffleDecode.cpp b/llvm/lib/Target/X86/Utils/X86ShuffleDecode.cpp index 9aca2da..713e147 100644 --- a/llvm/lib/Target/X86/Utils/X86ShuffleDecode.cpp +++ b/llvm/lib/Target/X86/Utils/X86ShuffleDecode.cpp @@ -224,8 +224,7 @@ void DecodeVPERM2X128Mask(MVT VT, unsigned Imm, } } -void DecodePSHUFBMask(const ConstantDataSequential *C, - SmallVectorImpl<int> &ShuffleMask) { +void DecodePSHUFBMask(const Constant *C, SmallVectorImpl<int> &ShuffleMask) { Type *MaskTy = C->getType(); assert(MaskTy->isVectorTy() && "Expected a vector constant mask!"); assert(MaskTy->getVectorElementType()->isIntegerTy(8) && @@ -234,22 +233,48 @@ void DecodePSHUFBMask(const ConstantDataSequential *C, // FIXME: Add support for AVX-512. assert((NumElements == 16 || NumElements == 32) && "Only 128-bit and 256-bit vectors supported!"); - assert((unsigned)NumElements == C->getNumElements() && - "Constant mask has a different number of elements!"); - ShuffleMask.reserve(NumElements); - for (int i = 0; i < NumElements; ++i) { - // For AVX vectors with 32 bytes the base of the shuffle is the half of the - // vector we're inside. - int Base = i < 16 ? 0 : 16; - uint64_t Element = C->getElementAsInteger(i); - // If the high bit (7) of the byte is set, the element is zeroed. - if (Element & (1 << 7)) - ShuffleMask.push_back(SM_SentinelZero); - else { - // Only the least significant 4 bits of the byte are used. - int Index = Base + (Element & 0xf); - ShuffleMask.push_back(Index); + + if (auto *CDS = dyn_cast<ConstantDataSequential>(C)) { + assert((unsigned)NumElements == CDS->getNumElements() && + "Constant mask has a different number of elements!"); + + for (int i = 0; i < NumElements; ++i) { + // For AVX vectors with 32 bytes the base of the shuffle is the 16-byte + // lane of the vector we're inside. + int Base = i < 16 ? 0 : 16; + uint64_t Element = CDS->getElementAsInteger(i); + // If the high bit (7) of the byte is set, the element is zeroed. + if (Element & (1 << 7)) + ShuffleMask.push_back(SM_SentinelZero); + else { + // Only the least significant 4 bits of the byte are used. + int Index = Base + (Element & 0xf); + ShuffleMask.push_back(Index); + } + } + } else if (auto *CV = dyn_cast<ConstantVector>(C)) { + assert((unsigned)NumElements == CV->getNumOperands() && + "Constant mask has a different number of elements!"); + + for (int i = 0; i < NumElements; ++i) { + // For AVX vectors with 32 bytes the base of the shuffle is the 16-byte + // lane of the vector we're inside. + int Base = i < 16 ? 0 : 16; + Constant *COp = CV->getOperand(i); + if (isa<UndefValue>(COp)) { + ShuffleMask.push_back(SM_SentinelUndef); + continue; + } + uint64_t Element = cast<ConstantInt>(COp)->getZExtValue(); + // If the high bit (7) of the byte is set, the element is zeroed. + if (Element & (1 << 7)) + ShuffleMask.push_back(SM_SentinelZero); + else { + // Only the least significant 4 bits of the byte are used. + int Index = Base + (Element & 0xf); + ShuffleMask.push_back(Index); + } } } } @@ -258,6 +283,10 @@ void DecodePSHUFBMask(ArrayRef<uint64_t> RawMask, SmallVectorImpl<int> &ShuffleMask) { for (int i = 0, e = RawMask.size(); i < e; ++i) { uint64_t M = RawMask[i]; + if (M == (uint64_t)SM_SentinelUndef) { + ShuffleMask.push_back(M); + continue; + } // For AVX vectors with 32 bytes the base of the shuffle is the half of // the vector we're inside. int Base = i < 16 ? 0 : 16; @@ -287,8 +316,7 @@ void DecodeVPERMMask(unsigned Imm, SmallVectorImpl<int> &ShuffleMask) { } } -void DecodeVPERMILPMask(const ConstantDataSequential *C, - SmallVectorImpl<int> &ShuffleMask) { +void DecodeVPERMILPMask(const Constant *C, SmallVectorImpl<int> &ShuffleMask) { Type *MaskTy = C->getType(); assert(MaskTy->isVectorTy() && "Expected a vector constant mask!"); assert(MaskTy->getVectorElementType()->isIntegerTy() && @@ -297,16 +325,34 @@ void DecodeVPERMILPMask(const ConstantDataSequential *C, 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); + if (auto *CDS = dyn_cast<ConstantDataSequential>(C)) { + assert((unsigned)NumElements == CDS->getNumElements() && + "Constant mask has a different number of elements!"); + + for (int i = 0; i < NumElements; ++i) { + int Base = (i * ElementBits / 128) * (128 / ElementBits); + uint64_t Element = CDS->getElementAsInteger(i); + // Only the least significant 2 bits of the integer are used. + int Index = Base + (Element & 0x3); + ShuffleMask.push_back(Index); + } + } else if (auto *CV = dyn_cast<ConstantVector>(C)) { + assert((unsigned)NumElements == C->getNumOperands() && + "Constant mask has a different number of elements!"); + + for (int i = 0; i < NumElements; ++i) { + int Base = (i * ElementBits / 128) * (128 / ElementBits); + Constant *COp = CV->getOperand(i); + if (isa<UndefValue>(COp)) { + ShuffleMask.push_back(SM_SentinelUndef); + continue; + } + uint64_t Element = cast<ConstantInt>(COp)->getZExtValue(); + // Only the least significant 2 bits of the integer are used. + int Index = Base + (Element & 0x3); + ShuffleMask.push_back(Index); + } } } |