diff options
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.cpp | 100 |
1 files changed, 56 insertions, 44 deletions
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index ac5c9dbef6d..fb3a29c2d89 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<Constant>(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<APInt> &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<UndefValue>(COp) || isa<ConstantInt>(COp) || - isa<ConstantFP>(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<UndefValue>(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<ConstantInt>(COp)) - Bits = CInt->getValue(); - else if (auto *CFP = dyn_cast<ConstantFP>(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<UndefValue>(Cst)) { + Mask = APInt::getNullValue(SizeInBits); + Undefs = APInt::getLowBitsSet(SizeInBits, CstSizeInBits); + return true; + } + if (auto *CInt = dyn_cast<ConstantInt>(Cst)) { + Mask = CInt->getValue().zextOrTrunc(SizeInBits); + Undefs = APInt::getNullValue(SizeInBits); + return true; + } + if (auto *CFP = dyn_cast<ConstantFP>(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, |

