From b3ae4168393c78aa47acbe35f5fb32448f355acc Mon Sep 17 00:00:00 2001 From: Simon Pilgrim Date: Fri, 2 Dec 2016 11:58:05 +0000 Subject: [PATCH] [X86] Refactored getTargetConstantBitsFromNode to allow for expansion. NFCI. getTargetConstantBitsFromNode currently only extracts constant pool vector data, but it will need to be generalized to support broadcast and scalar constant pool data as well. Converted Constant bit extraction and Bitset splitting to helper lambda functions. llvm-svn: 288496 --- llvm/lib/Target/X86/X86ISelLowering.cpp | 100 ++++++++++++++++++-------------- 1 file changed, 56 insertions(+), 44 deletions(-) diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index ac5c9db..fb3a29c 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -5131,7 +5131,7 @@ static const Constant *getTargetConstantFromNode(SDValue Op) { return dyn_cast(CNode->getConstVal()); } -// Extract constant bits from constant pool vector. +// Extract raw constant bits from constant pools. static bool getTargetConstantBitsFromNode(SDValue Op, unsigned EltSizeInBits, SmallBitVector &UndefElts, SmallVectorImpl &EltBits) { @@ -5143,63 +5143,75 @@ static bool getTargetConstantBitsFromNode(SDValue Op, unsigned EltSizeInBits, assert((SizeInBits % EltSizeInBits) == 0 && "Can't split constant!"); unsigned NumElts = SizeInBits / EltSizeInBits; - auto *Cst = getTargetConstantFromNode(Op); - if (!Cst) - return false; - - Type *CstTy = Cst->getType(); - if (!CstTy->isVectorTy() || (SizeInBits != CstTy->getPrimitiveSizeInBits())) - return false; - // Extract all the undef/constant element data and pack into single bitsets. APInt UndefBits(SizeInBits, 0); APInt MaskBits(SizeInBits, 0); - unsigned CstEltSizeInBits = CstTy->getScalarSizeInBits(); - for (unsigned i = 0, e = CstTy->getVectorNumElements(); i != e; ++i) { - auto *COp = Cst->getAggregateElement(i); - if (!COp || - !(isa(COp) || isa(COp) || - isa(COp))) - return false; + // Split the undef/constant single bitset data into the target elements. + auto SplitBitData = [&]() { + UndefElts = SmallBitVector(NumElts, false); + EltBits.resize(NumElts, APInt(EltSizeInBits, 0)); - if (isa(COp)) { - APInt EltUndef = APInt::getLowBitsSet(SizeInBits, CstEltSizeInBits); - UndefBits |= EltUndef.shl(i * CstEltSizeInBits); - continue; - } + for (unsigned i = 0; i != NumElts; ++i) { + APInt UndefEltBits = UndefBits.lshr(i * EltSizeInBits); + UndefEltBits = UndefEltBits.zextOrTrunc(EltSizeInBits); - APInt Bits; - if (auto *CInt = dyn_cast(COp)) - Bits = CInt->getValue(); - else if (auto *CFP = dyn_cast(COp)) - Bits = CFP->getValueAPF().bitcastToAPInt(); + // Only treat an element as UNDEF if all bits are UNDEF, otherwise + // treat it as zero. + if (UndefEltBits.isAllOnesValue()) { + UndefElts[i] = true; + continue; + } - Bits = Bits.zextOrTrunc(SizeInBits); - MaskBits |= Bits.shl(i * CstEltSizeInBits); - } + APInt Bits = MaskBits.lshr(i * EltSizeInBits); + Bits = Bits.zextOrTrunc(EltSizeInBits); + EltBits[i] = Bits.getZExtValue(); + } + return true; + }; - UndefElts = SmallBitVector(NumElts, false); - EltBits.resize(NumElts, APInt(EltSizeInBits, 0)); + // Extract constant bits from constant pool scalar/vector. + if (auto *Cst = getTargetConstantFromNode(Op)) { + Type *CstTy = Cst->getType(); + if (!CstTy->isVectorTy() || (SizeInBits != CstTy->getPrimitiveSizeInBits())) + return false; - // Now extract the undef/constant bit data into the target elts. - for (unsigned i = 0; i != NumElts; ++i) { - APInt UndefEltBits = UndefBits.lshr(i * EltSizeInBits); - UndefEltBits = UndefEltBits.zextOrTrunc(EltSizeInBits); + auto ExtractConstantBits = [SizeInBits](const Constant *Cst, APInt &Mask, + APInt &Undefs) { + if (!Cst) + return false; + unsigned CstSizeInBits = Cst->getType()->getPrimitiveSizeInBits(); + if (isa(Cst)) { + Mask = APInt::getNullValue(SizeInBits); + Undefs = APInt::getLowBitsSet(SizeInBits, CstSizeInBits); + return true; + } + if (auto *CInt = dyn_cast(Cst)) { + Mask = CInt->getValue().zextOrTrunc(SizeInBits); + Undefs = APInt::getNullValue(SizeInBits); + return true; + } + if (auto *CFP = dyn_cast(Cst)) { + Mask = CFP->getValueAPF().bitcastToAPInt().zextOrTrunc(SizeInBits); + Undefs = APInt::getNullValue(SizeInBits); + return true; + } + return false; + }; - // Only treat the element as UNDEF if all bits are UNDEF, otherwise - // treat it as zero. - if (UndefEltBits.isAllOnesValue()) { - UndefElts[i] = true; - continue; + unsigned CstEltSizeInBits = CstTy->getScalarSizeInBits(); + for (unsigned i = 0, e = CstTy->getVectorNumElements(); i != e; ++i) { + APInt Bits, Undefs; + if (!ExtractConstantBits(Cst->getAggregateElement(i), Bits, Undefs)) + return false; + MaskBits |= Bits.shl(i * CstEltSizeInBits); + UndefBits |= Undefs.shl(i * CstEltSizeInBits); } - APInt Bits = MaskBits.lshr(i * EltSizeInBits); - Bits = Bits.zextOrTrunc(EltSizeInBits); - EltBits[i] = Bits.getZExtValue(); + return SplitBitData(); } - return true; + return false; } static bool getTargetShuffleMaskIndices(SDValue MaskNode, -- 2.7.4