From: Philip Reames Date: Thu, 25 Apr 2019 02:30:17 +0000 (+0000) Subject: Consolidate existing utilities for interpreting vector predicate maskes [NFC] X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=bc60690d7c05821e9e5a66da0b3c0996731de588;p=llvm Consolidate existing utilities for interpreting vector predicate maskes [NFC] git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@359163 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/Analysis/VectorUtils.h b/include/llvm/Analysis/VectorUtils.h index 4d940860b63..f79bdc17502 100644 --- a/include/llvm/Analysis/VectorUtils.h +++ b/include/llvm/Analysis/VectorUtils.h @@ -223,6 +223,20 @@ Constant *createSequentialMask(IRBuilder<> &Builder, unsigned Start, /// elements, it will be padded with undefs. Value *concatenateVectors(IRBuilder<> &Builder, ArrayRef Vecs); +/// Given a mask vector of the form , Return true if all of the +/// elements of this predicate mask are false or undef. That is, return true +/// if all lanes can be assumed inactive. +bool maskIsAllZeroOrUndef(Value *Mask); + +/// Given a mask vector of the form , Return true if all of the +/// elements of this predicate mask are true or undef. That is, return true +/// if all lanes can be assumed active. +bool maskIsAllOneOrUndef(Value *Mask); + +/// Given a mask vector of the form , return an APInt (of bitwidth Y) +/// for each lane which may be active. +APInt possiblyDemandedEltsInMask(Value *Mask); + /// The group of interleaved loads/stores sharing the same stride and /// close to each other. /// diff --git a/lib/Analysis/InstructionSimplify.cpp b/lib/Analysis/InstructionSimplify.cpp index 87e0df29bbd..4c358a052f8 100644 --- a/lib/Analysis/InstructionSimplify.cpp +++ b/lib/Analysis/InstructionSimplify.cpp @@ -4635,22 +4635,6 @@ static Value *SimplifyRelativeLoad(Constant *Ptr, Constant *Offset, return ConstantExpr::getBitCast(LoadedLHSPtr, Int8PtrTy); } -static bool maskIsAllZeroOrUndef(Value *Mask) { - auto *ConstMask = dyn_cast(Mask); - if (!ConstMask) - return false; - if (ConstMask->isNullValue() || isa(ConstMask)) - return true; - for (unsigned I = 0, E = ConstMask->getType()->getVectorNumElements(); I != E; - ++I) { - if (auto *MaskElt = ConstMask->getAggregateElement(I)) - if (MaskElt->isNullValue() || isa(MaskElt)) - continue; - return false; - } - return true; -} - static Value *simplifyUnaryIntrinsic(Function *F, Value *Op0, const SimplifyQuery &Q) { // Idempotent functions return the same result when called repeatedly. diff --git a/lib/Analysis/VectorUtils.cpp b/lib/Analysis/VectorUtils.cpp index ef70e14da7f..f1a05ae5055 100644 --- a/lib/Analysis/VectorUtils.cpp +++ b/lib/Analysis/VectorUtils.cpp @@ -715,6 +715,52 @@ Value *llvm::concatenateVectors(IRBuilder<> &Builder, ArrayRef Vecs) { return ResList[0]; } +bool llvm::maskIsAllZeroOrUndef(Value *Mask) { + auto *ConstMask = dyn_cast(Mask); + if (!ConstMask) + return false; + if (ConstMask->isNullValue() || isa(ConstMask)) + return true; + for (unsigned I = 0, E = ConstMask->getType()->getVectorNumElements(); I != E; + ++I) { + if (auto *MaskElt = ConstMask->getAggregateElement(I)) + if (MaskElt->isNullValue() || isa(MaskElt)) + continue; + return false; + } + return true; +} + + +bool llvm::maskIsAllOneOrUndef(Value *Mask) { + auto *ConstMask = dyn_cast(Mask); + if (!ConstMask) + return false; + if (ConstMask->isAllOnesValue() || isa(ConstMask)) + return true; + for (unsigned I = 0, E = ConstMask->getType()->getVectorNumElements(); I != E; + ++I) { + if (auto *MaskElt = ConstMask->getAggregateElement(I)) + if (MaskElt->isAllOnesValue() || isa(MaskElt)) + continue; + return false; + } + return true; +} + +/// TODO: This is a lot like known bits, but for +/// vectors. Is there something we can common this with? +APInt llvm::possiblyDemandedEltsInMask(Value *Mask) { + + const unsigned VWidth = cast(Mask->getType())->getNumElements(); + APInt DemandedElts = APInt::getAllOnesValue(VWidth); + if (auto *CV = dyn_cast(Mask)) + for (unsigned i = 0; i < VWidth; i++) + if (CV->getAggregateElement(i)->isNullValue()) + DemandedElts.clearBit(i); + return DemandedElts; +} + bool InterleavedAccessInfo::isStrided(int Stride) { unsigned Factor = std::abs(Stride); return Factor >= 2 && Factor <= MaxInterleaveGroupFactor; diff --git a/lib/Transforms/InstCombine/InstCombineCalls.cpp b/lib/Transforms/InstCombine/InstCombineCalls.cpp index fbdc1b77821..c60e9d1c1cb 100644 --- a/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -24,7 +24,6 @@ #include "llvm/Analysis/Loads.h" #include "llvm/Analysis/InstructionSimplify.h" #include "llvm/Analysis/MemoryBuiltins.h" -#include "llvm/Transforms/Utils/Local.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/Analysis/VectorUtils.h" #include "llvm/IR/Attributes.h" @@ -58,6 +57,7 @@ #include "llvm/Support/MathExtras.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Transforms/InstCombine/InstCombineWorklist.h" +#include "llvm/Transforms/Utils/Local.h" #include "llvm/Transforms/Utils/SimplifyLibCalls.h" #include #include @@ -1147,36 +1147,6 @@ static Value *simplifyX86vpermv(const IntrinsicInst &II, return Builder.CreateShuffleVector(V1, V2, ShuffleMask); } -static bool maskIsAllOneOrUndef(Value *Mask) { - auto *ConstMask = dyn_cast(Mask); - if (!ConstMask) - return false; - if (ConstMask->isAllOnesValue() || isa(ConstMask)) - return true; - for (unsigned I = 0, E = ConstMask->getType()->getVectorNumElements(); I != E; - ++I) { - if (auto *MaskElt = ConstMask->getAggregateElement(I)) - if (MaskElt->isAllOnesValue() || isa(MaskElt)) - continue; - return false; - } - return true; -} - -/// Given a mask vector , return an APInt (of bitwidth Y) for each lane -/// which may be active. TODO: This is a lot like known bits, but for -/// vectors. Is there something we can common this with? -static APInt possiblyDemandedEltsInMask(Value *Mask) { - - const unsigned VWidth = cast(Mask->getType())->getNumElements(); - APInt DemandedElts = APInt::getAllOnesValue(VWidth); - if (auto *CV = dyn_cast(Mask)) - for (unsigned i = 0; i < VWidth; i++) - if (CV->getAggregateElement(i)->isNullValue()) - DemandedElts.clearBit(i); - return DemandedElts; -} - // TODO, Obvious Missing Transforms: // * Narrow width by halfs excluding zero/undef lanes Value *InstCombiner::simplifyMaskedLoad(IntrinsicInst &II) {