From d633e290c8b5c831d09b3ff3ae72e4ae79a96171 Mon Sep 17 00:00:00 2001 From: Simon Pilgrim Date: Sat, 29 Sep 2018 17:01:55 +0000 Subject: [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 --- llvm/lib/Target/X86/X86ISelLowering.cpp | 47 +++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) (limited to 'llvm/lib') 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(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(Op)) { + // TODO - support shuffle through bitcasts. + if (EltSizeInBits != VT.getScalarSizeInBits()) + return false; + + ArrayRef Mask = SVN->getMask(); + if ((!AllowWholeUndefs || !AllowPartialUndefs) && + llvm::any_of(Mask, [](int M) { return M < 0; })) + return false; + + APInt UndefElts0, UndefElts1; + SmallVector 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; } -- cgit v1.2.3