diff options
| author | Simon Pilgrim <llvm-dev@redking.me.uk> | 2018-09-29 17:01:55 +0000 |
|---|---|---|
| committer | Simon Pilgrim <llvm-dev@redking.me.uk> | 2018-09-29 17:01:55 +0000 |
| commit | d633e290c8b5c831d09b3ff3ae72e4ae79a96171 (patch) | |
| tree | 0545cc2c63f4434ca937a0ebd922782906992720 /llvm/lib | |
| parent | ae34ae12ef6bff8d750ed3aca922687227c2198e (diff) | |
| download | bcm5719-llvm-d633e290c8b5c831d09b3ff3ae72e4ae79a96171.tar.gz bcm5719-llvm-d633e290c8b5c831d09b3ff3ae72e4ae79a96171.zip | |
[X86] getTargetConstantBitsFromNode - add support for rearranging constant bits via shuffles
Exposed an issue that recursive calls to getTargetConstantBitsFromNode don't handle changes to EltSizeInBits yet.
llvm-svn: 343384
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.cpp | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index c2054c1b79a..cb5af7d9fdc 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -5745,6 +5745,10 @@ static bool getTargetConstantBitsFromNode(SDValue Op, unsigned EltSizeInBits, // Extract constant bits from a subvector's source. if (Op.getOpcode() == ISD::EXTRACT_SUBVECTOR && isa<ConstantSDNode>(Op.getOperand(1))) { + // TODO - support extract_subvector through bitcasts. + if (EltSizeInBits != VT.getScalarSizeInBits()) + return false; + if (getTargetConstantBitsFromNode(Op.getOperand(0), EltSizeInBits, UndefElts, EltBits, AllowWholeUndefs, AllowPartialUndefs)) { @@ -5761,6 +5765,49 @@ static bool getTargetConstantBitsFromNode(SDValue Op, unsigned EltSizeInBits, } } + // Extract constant bits from shuffle node sources. + if (auto *SVN = dyn_cast<ShuffleVectorSDNode>(Op)) { + // TODO - support shuffle through bitcasts. + if (EltSizeInBits != VT.getScalarSizeInBits()) + return false; + + ArrayRef<int> Mask = SVN->getMask(); + if ((!AllowWholeUndefs || !AllowPartialUndefs) && + llvm::any_of(Mask, [](int M) { return M < 0; })) + return false; + + APInt UndefElts0, UndefElts1; + SmallVector<APInt, 32> EltBits0, EltBits1; + if (isAnyInRange(Mask, 0, NumElts) && + !getTargetConstantBitsFromNode(Op.getOperand(0), EltSizeInBits, + UndefElts0, EltBits0, AllowWholeUndefs, + AllowPartialUndefs)) + return false; + if (isAnyInRange(Mask, NumElts, 2 * NumElts) && + !getTargetConstantBitsFromNode(Op.getOperand(1), EltSizeInBits, + UndefElts1, EltBits1, AllowWholeUndefs, + AllowPartialUndefs)) + return false; + + UndefElts = APInt::getNullValue(NumElts); + for (int i = 0; i != NumElts; ++i) { + int M = Mask[i]; + if (M < 0) { + UndefElts.setBit(i); + EltBits.push_back(APInt::getNullValue(EltSizeInBits)); + } else if (M < (int)NumElts) { + if (UndefElts0[M]) + UndefElts.setBit(i); + EltBits.push_back(EltBits0[M]); + } else { + if (UndefElts1[M - NumElts]) + UndefElts.setBit(i); + EltBits.push_back(EltBits1[M - NumElts]); + } + } + return true; + } + return false; } |

