diff options
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Analysis/VectorUtils.cpp')
-rw-r--r-- | contrib/llvm-project/llvm/lib/Analysis/VectorUtils.cpp | 67 |
1 files changed, 60 insertions, 7 deletions
diff --git a/contrib/llvm-project/llvm/lib/Analysis/VectorUtils.cpp b/contrib/llvm-project/llvm/lib/Analysis/VectorUtils.cpp index bc20f33f174c..1e48d3e2fbca 100644 --- a/contrib/llvm-project/llvm/lib/Analysis/VectorUtils.cpp +++ b/contrib/llvm-project/llvm/lib/Analysis/VectorUtils.cpp @@ -398,7 +398,7 @@ bool llvm::isSplatValue(const Value *V, int Index, unsigned Depth) { if (auto *Shuf = dyn_cast<ShuffleVectorInst>(V)) { // FIXME: We can safely allow undefs here. If Index was specified, we will // check that the mask elt is defined at the required index. - if (!is_splat(Shuf->getShuffleMask())) + if (!all_equal(Shuf->getShuffleMask())) return false; // Match any index. @@ -429,6 +429,43 @@ bool llvm::isSplatValue(const Value *V, int Index, unsigned Depth) { return false; } +bool llvm::getShuffleDemandedElts(int SrcWidth, ArrayRef<int> Mask, + const APInt &DemandedElts, APInt &DemandedLHS, + APInt &DemandedRHS, bool AllowUndefElts) { + DemandedLHS = DemandedRHS = APInt::getZero(SrcWidth); + + // Early out if we don't demand any elements. + if (DemandedElts.isZero()) + return true; + + // Simple case of a shuffle with zeroinitializer. + if (all_of(Mask, [](int Elt) { return Elt == 0; })) { + DemandedLHS.setBit(0); + return true; + } + + for (unsigned I = 0, E = Mask.size(); I != E; ++I) { + int M = Mask[I]; + assert((-1 <= M) && (M < (SrcWidth * 2)) && + "Invalid shuffle mask constant"); + + if (!DemandedElts[I] || (AllowUndefElts && (M < 0))) + continue; + + // For undef elements, we don't know anything about the common state of + // the shuffle result. + if (M < 0) + return false; + + if (M < SrcWidth) + DemandedLHS.setBit(M); + else + DemandedRHS.setBit(M - SrcWidth); + } + + return true; +} + void llvm::narrowShuffleMaskElts(int Scale, ArrayRef<int> Mask, SmallVectorImpl<int> &ScaledMask) { assert(Scale > 0 && "Unexpected scaling factor"); @@ -478,7 +515,7 @@ bool llvm::widenShuffleMaskElts(int Scale, ArrayRef<int> Mask, if (SliceFront < 0) { // Negative values (undef or other "sentinel" values) must be equal across // the entire slice. - if (!is_splat(MaskSlice)) + if (!all_equal(MaskSlice)) return false; ScaledMask.push_back(SliceFront); } else { @@ -501,6 +538,20 @@ bool llvm::widenShuffleMaskElts(int Scale, ArrayRef<int> Mask, return true; } +void llvm::getShuffleMaskWithWidestElts(ArrayRef<int> Mask, + SmallVectorImpl<int> &ScaledMask) { + std::array<SmallVector<int, 16>, 2> TmpMasks; + SmallVectorImpl<int> *Output = &TmpMasks[0], *Tmp = &TmpMasks[1]; + ArrayRef<int> InputMask = Mask; + for (unsigned Scale = 2; Scale <= InputMask.size(); ++Scale) { + while (widenShuffleMaskElts(Scale, InputMask, *Output)) { + InputMask = *Output; + std::swap(Output, Tmp); + } + } + ScaledMask.assign(InputMask.begin(), InputMask.end()); +} + void llvm::processShuffleMasks( ArrayRef<int> Mask, unsigned NumOfSrcRegs, unsigned NumOfDestRegs, unsigned NumOfUsedRegs, function_ref<void()> NoInputAction, @@ -1123,8 +1174,9 @@ void InterleavedAccessInfo::collectConstStrideAccesses( // wrap around the address space we would do a memory access at nullptr // even without the transformation. The wrapping checks are therefore // deferred until after we've formed the interleaved groups. - int64_t Stride = getPtrStride(PSE, ElementTy, Ptr, TheLoop, Strides, - /*Assume=*/true, /*ShouldCheckWrap=*/false); + int64_t Stride = + getPtrStride(PSE, ElementTy, Ptr, TheLoop, Strides, + /*Assume=*/true, /*ShouldCheckWrap=*/false).value_or(0); const SCEV *Scev = replaceSymbolicStrideSCEV(PSE, Strides, Ptr); AccessStrideInfo[&I] = StrideDescriptor(Stride, Scev, Size, @@ -1343,7 +1395,7 @@ void InterleavedAccessInfo::analyzeInterleaving( Value *MemberPtr = getLoadStorePointerOperand(Member); Type *AccessTy = getLoadStoreType(Member); if (getPtrStride(PSE, AccessTy, MemberPtr, TheLoop, Strides, - /*Assume=*/false, /*ShouldCheckWrap=*/true)) + /*Assume=*/false, /*ShouldCheckWrap=*/true).value_or(0)) return false; LLVM_DEBUG(dbgs() << "LV: Invalidate candidate interleaved group due to " << FirstOrLast @@ -1505,9 +1557,10 @@ void VFABI::getVectorVariantNames( for (const auto &S : SetVector<StringRef>(ListAttr.begin(), ListAttr.end())) { #ifndef NDEBUG LLVM_DEBUG(dbgs() << "VFABI: adding mapping '" << S << "'\n"); - Optional<VFInfo> Info = VFABI::tryDemangleForVFABI(S, *(CI.getModule())); + std::optional<VFInfo> Info = + VFABI::tryDemangleForVFABI(S, *(CI.getModule())); assert(Info && "Invalid name for a VFABI variant."); - assert(CI.getModule()->getFunction(Info.value().VectorName) && + assert(CI.getModule()->getFunction(Info->VectorName) && "Vector function is missing."); #endif VariantMappings.push_back(std::string(S)); |