diff options
author | Simon Pilgrim <llvm-dev@redking.me.uk> | 2016-12-02 13:16:08 +0000 |
---|---|---|
committer | Simon Pilgrim <llvm-dev@redking.me.uk> | 2016-12-02 13:16:08 +0000 |
commit | cbf5f97018db689bdc72294892ee01da1135331a (patch) | |
tree | da6e98c6547849040b6692b0c6689f7fef4798b5 /llvm/lib/Target/X86/X86ISelLowering.cpp | |
parent | 08e402ac932cd9a725c1c2b6957bd15a6755c1fa (diff) | |
download | bcm5719-llvm-cbf5f97018db689bdc72294892ee01da1135331a.tar.gz bcm5719-llvm-cbf5f97018db689bdc72294892ee01da1135331a.zip |
[X86][SSE] Add support for extracting constant bit data from broadcasted constants
llvm-svn: 288499
Diffstat (limited to 'llvm/lib/Target/X86/X86ISelLowering.cpp')
-rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.cpp | 68 |
1 files changed, 44 insertions, 24 deletions
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index fb3a29c2d89..f64bb096a1c 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -5138,6 +5138,8 @@ static bool getTargetConstantBitsFromNode(SDValue Op, unsigned EltSizeInBits, assert(UndefElts.empty() && "Expected an empty UndefElts vector"); assert(EltBits.empty() && "Expected an empty EltBits vector"); + Op = peekThroughBitcasts(Op); + EVT VT = Op.getValueType(); unsigned SizeInBits = VT.getSizeInBits(); assert((SizeInBits % EltSizeInBits) == 0 && "Can't split constant!"); @@ -5170,35 +5172,35 @@ static bool getTargetConstantBitsFromNode(SDValue Op, unsigned EltSizeInBits, return true; }; - // Extract constant bits from constant pool scalar/vector. + 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; + }; + + // Extract constant bits from constant pool vector. if (auto *Cst = getTargetConstantFromNode(Op)) { Type *CstTy = Cst->getType(); if (!CstTy->isVectorTy() || (SizeInBits != CstTy->getPrimitiveSizeInBits())) return false; - 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; - }; - unsigned CstEltSizeInBits = CstTy->getScalarSizeInBits(); for (unsigned i = 0, e = CstTy->getVectorNumElements(); i != e; ++i) { APInt Bits, Undefs; @@ -5211,9 +5213,27 @@ static bool getTargetConstantBitsFromNode(SDValue Op, unsigned EltSizeInBits, return SplitBitData(); } + // Extract constant bits from a broadcasted constant pool scalar. + if (Op.getOpcode() == X86ISD::VBROADCAST && + EltSizeInBits <= Op.getScalarValueSizeInBits()) { + if (auto *Broadcast = getTargetConstantFromNode(Op.getOperand(0))) { + APInt Bits, Undefs; + if (ExtractConstantBits(Broadcast, Bits, Undefs)) { + unsigned NumBroadcastBits = Op.getScalarValueSizeInBits(); + unsigned NumBroadcastElts = SizeInBits / NumBroadcastBits; + for (unsigned i = 0; i != NumBroadcastElts; ++i) { + MaskBits |= Bits.shl(i * NumBroadcastBits); + UndefBits |= Undefs.shl(i * NumBroadcastBits); + } + return SplitBitData(); + } + } + } + return false; } +// TODO: Merge more of this with getTargetConstantBitsFromNode. static bool getTargetShuffleMaskIndices(SDValue MaskNode, unsigned MaskEltSizeInBits, SmallVectorImpl<uint64_t> &RawMask) { |