48 switch (
I->getOpcode()) {
49 case Instruction::ExtractValue:
50 case Instruction::InsertValue:
52 case Instruction::ExtractElement:
55 case Instruction::InsertElement:
65 "ScalableVectorType is not supported.");
76 return std::min<unsigned>(PartNumElems,
Size - Part * PartNumElems);
84 OS <<
"Idx: " << Idx <<
", ";
85 OS <<
"n=" << VL.
size() <<
" [" << *VL.
front() <<
", ..]";
106 if (BB !=
II->getParent())
119 Value *FirstNonUndef =
nullptr;
120 for (
Value *V : VL) {
123 if (!FirstNonUndef) {
127 if (V != FirstNonUndef)
130 return FirstNonUndef !=
nullptr;
136 if ((LHS == Intrinsic::fma || LHS == Intrinsic::fmuladd) &&
137 (RHS == Intrinsic::fma || RHS == Intrinsic::fmuladd))
138 return Intrinsic::fma;
145 return Cmp->isCommutative();
147 return BO->isCommutative() ||
148 (BO->getOpcode() == Instruction::Sub && ValWithUses->
hasUseList() &&
155 if (match(U.getUser(),
156 m_ICmp(Pred, m_Specific(U.get()), m_Zero())) &&
157 (Pred == ICmpInst::ICMP_EQ || Pred == ICmpInst::ICMP_NE))
161 auto *I = dyn_cast<BinaryOperator>(U.get());
162 return match(U.getUser(),
163 m_Intrinsic<Intrinsic::abs>(
164 m_Specific(U.get()), m_ConstantInt(Flag))) &&
165 ((!IsCopyable && I && !I->hasNoSignedWrap()) ||
168 (BO->getOpcode() == Instruction::FSub && ValWithUses->
hasUseList() &&
171 return match(U.getUser(),
172 m_Intrinsic<Intrinsic::fabs>(m_Specific(U.get())));
174 return I->isCommutative();
182 "The instruction is not commutative.");
186 switch (BO->getOpcode()) {
187 case Instruction::Sub:
188 case Instruction::FSub:
194 return I->isCommutableOperand(
Op);
201 constexpr unsigned IntrinsicNumOperands = 2;
202 return IntrinsicNumOperands;
204 return I->getNumOperands();
219 Type *CurrentType =
IV->getType();
220 for (
unsigned I :
IV->indices()) {
222 Index *= ST->getNumElements();
223 CurrentType = ST->getElementType(
I);
225 Index *= AT->getNumElements();
226 CurrentType = AT->getElementType();
245 if (auto *CI = dyn_cast<CmpInst>(V))
246 return BasePred == CI->getPredicate();
247 if (auto *I = dyn_cast<Instruction>(V))
248 return I->getOpcode() == Opcode;
249 return isa<PoisonValue>(V);
254 unsigned Opcode = E->getOpcode();
255 assert((Opcode == Instruction::ExtractElement ||
256 Opcode == Instruction::ExtractValue) &&
257 "Expected extractelement or extractvalue instruction.");
258 if (Opcode == Instruction::ExtractElement) {
264 unsigned Idx = CI->getZExtValue();
272 if (EI->getNumIndices() != 1)
274 return *EI->idx_begin();
280 const unsigned E = Indices.
size();
282 for (
unsigned I = 0;
I < E; ++
I)
283 Mask[Indices[
I]] =
I;
287 assert(!Mask.empty() &&
"Expected non-empty mask.");
291 for (
unsigned I = 0, E = Prev.
size();
I < E; ++
I)
293 Scalars[Mask[
I]] = Prev[
I];
297 assert(!VL.
empty() &&
"Expected non-empty list of values.");
299 return all_of(VL, [&](
Value *V) {
return V->getType() == Ty; });
305 static_assert(std::is_same_v<T, InsertElementInst> ||
306 std::is_same_v<T, ExtractElementInst>,
313 constexpr bool IsInsert = std::is_same_v<T, InsertElementInst>;
314 Type *VecTy = IsInsert ? IE->getType() : IE->getOperand(0)->getType();
321 if (CI->getValue().uge(VT->getNumElements()))
324 Index *= VT->getNumElements();
325 Index += CI->getZExtValue();
331template std::optional<unsigned>
333template std::optional<unsigned>
342 auto *IO = dyn_cast<Instruction>(V);
345 return isa<PHINode>(IO) || IO->getParent() != I->getParent();
354 return !
I->mayReadOrWriteMemory() && !
I->hasNUsesOrMore(
UsesLimit) &&
356 auto *IU = dyn_cast<Instruction>(U);
359 return IU->getParent() != I->getParent() || isa<PHINode>(IU);
368 return !VL.
empty() &&
381 I * VecTyNumElements, VecTyNumElements)))
383 : Mask[
I] * VecTyNumElements + J;
393 unsigned SVNumElements =
395 unsigned ShuffleMaskSize = SV->getShuffleMask().size();
396 if (SVNumElements % ShuffleMaskSize != 0)
398 unsigned GroupSize = SVNumElements / ShuffleMaskSize;
399 if (GroupSize == 0 || (VL.
size() % GroupSize) != 0)
401 unsigned NumGroup = 0;
402 for (
size_t I = 0, E = VL.
size();
I != E;
I += GroupSize) {
404 Value *Src = SV->getOperand(0);
410 if (SV->getOperand(0) != Src)
413 if (!SV->isExtractSubvectorMask(Index))
415 ExpectedIndex.
set(Index / ShuffleMaskSize);
419 if (!ExpectedIndex.
all())
423 assert(NumGroup == (VL.
size() / GroupSize) &&
"Unexpected number of groups");
430 unsigned SVNumElements =
433 unsigned AccumulateLength = 0;
434 for (
Value *V : VL) {
436 for (
int M : SV->getShuffleMask())
438 : AccumulateLength + M);
439 AccumulateLength += SVNumElements;
460template <
bool IsPoisonOnly>
463 using T = std::conditional_t<IsPoisonOnly, PoisonValue, UndefValue>;
497 for (
unsigned I = 0, E = VecTy->getNumElements();
I != E; ++
I) {
498 if (
Constant *Elem =
C->getAggregateElement(
I))
518 case Instruction::Load: {
522 case Instruction::Store: {
524 return (
SI->getPointerOperand() == Scalar);
526 case Instruction::Call: {
530 return isVectorIntrinsicWithScalarOpAtArg(ID, Arg.index(), TTI) &&
531 Arg.value().get() == Scalar;
549 return LI->isSimple();
551 return SI->isSimple();
553 return !
MI->isVolatile();
563 uint64_t ScalarSize =
DL.getTypeStoreSize(ScalarTy);
564 Conditions.
assign(PointerOps.
size(),
nullptr);
569 APInt OffsetAP(
DL.getIndexTypeSizeInBits(
GEP->getType()), 0);
570 if (!
GEP->accumulateConstantOffset(
DL, OffsetAP) || OffsetAP.
isNegative())
573 Base =
GEP->getPointerOperand();
578 Value *
T = Sel->getTrueValue();
579 Value *
F = Sel->getFalseValue();
585 }
else if (TrueBase !=
T || FalseBase !=
F) {
592 Conditions[Idx] = Sel->getCondition();
594 return TrueBase !=
nullptr;
598 bool ExtendingManyInputs) {
602 (!ExtendingManyInputs || SubMask.
size() > Mask.size() ||
605 "SubMask with many inputs support must be larger than the mask.");
607 Mask.append(SubMask.
begin(), SubMask.
end());
611 int TermValue = std::min(Mask.size(), SubMask.
size());
612 for (
int I = 0, E = SubMask.
size();
I < E; ++
I) {
614 (!ExtendingManyInputs &&
615 (SubMask[
I] >= TermValue || Mask[SubMask[
I]] >= TermValue)))
617 NewMask[
I] = Mask[SubMask[
I]];
623 const size_t Sz = Order.
size();
626 for (
unsigned I = 0;
I < Sz; ++
I) {
628 UnusedIndices.
reset(Order[
I]);
630 MaskedIndices.
set(
I);
632 if (MaskedIndices.
none())
635 "Non-synced masked/available indices.");
639 assert(Idx >= 0 &&
"Indices must be synced.");
647 unsigned Opcode0,
unsigned Opcode1) {
654 OpcodeMask.
set(Lane * ScalarTyNumElements,
655 Lane * ScalarTyNumElements + ScalarTyNumElements);
662 "Expected scalar constants.");
665 std::fill_n(NewVal.begin() +
I * VF, VF, V);
671 case Instruction::UDiv:
672 return Intrinsic::masked_udiv;
673 case Instruction::SDiv:
674 return Intrinsic::masked_sdiv;
675 case Instruction::URem:
676 return Intrinsic::masked_urem;
677 case Instruction::SRem:
678 return Intrinsic::masked_srem;
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
uint64_t IntrinsicInst * II
Provides some synthesis utilities to produce sequences of values.
static const uint32_t IV[8]
Class for arbitrary precision integers.
uint64_t getZExtValue() const
Get zero extended value.
bool isNegative() const
Determine sign of this APInt.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
const T & front() const
Get the first element.
size_t size() const
Get the array size.
bool empty() const
Check if the array is empty.
ArrayRef< T > slice(size_t N, size_t M) const
slice(n, m) - Chop off the first N elements of the array, and keep M elements in the array.
const T & consume_front()
consume_front() - Returns the first element and drops it from ArrayRef.
LLVM Basic Block Representation.
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
This class represents a function call, abstracting a target machine's calling convention.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
static LLVM_ABI Constant * getBinOpIdentity(unsigned Opcode, Type *Ty, bool AllowRHSConstant=false, bool NSZ=false)
Return the identity constant for a binary opcode.
This is an important base class in LLVM.
A parsed version of the target data layout string in and methods for querying it.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
An instruction for reading from memory.
Value * getPointerOperand()
This is the common base class for memset/memcpy/memmove.
Representation for a specific memory location.
static LLVM_ABI MemoryLocation get(const LoadInst *LI)
Return a location with information about the memory reference by the given instruction.
Represent a mutable reference to an array (0 or more elements consecutively in memory),...
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
This is a 'bitvector' (really, a variable-sized bit array), optimized for the case when the array is ...
int find_first() const
Returns the index of the first set bit, -1 if none of the bits are set.
int find_next(unsigned Prev) const
Returns the index of the next set bit following the "Prev" bit.
bool all() const
Returns true if all bits are set.
size_type count() const
Returns the number of bits which are set.
bool none() const
Returns true if none of the bits are set.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void assign(size_type NumElts, ValueParamT Elt)
void swap(SmallVectorImpl &RHS)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An instruction for storing to memory.
Provides information about what library functions are available for the current target.
The instances of the Type class are immutable: once they are created, they are never changed.
A Use represents the edge between a Value definition and its users.
LLVM Value Representation.
bool hasUseList() const
Check if this Value has a use-list.
LLVM_ABI bool hasNUsesOrMore(unsigned N) const
Return true if this value has N uses or more.
iterator_range< use_iterator > uses()
constexpr ScalarTy getFixedValue() const
const ParentTy * getParent() const
A raw_ostream that writes to an std::string.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
A private "module" namespace for types and utilities used by this pass.
std::optional< unsigned > getExtractIndex(const Instruction *E)
template SmallBitVector isUndefVector< true >(const Value *, const SmallBitVector &)
bool areAllOperandsNonInsts(Value *V)
Checks if the provided value does not require scheduling.
std::optional< unsigned > getElementIndex(const Value *Inst, unsigned Offset)
bool doesInTreeUserNeedToExtract(Value *Scalar, Instruction *UserInst, TargetLibraryInfo *TLI, const TargetTransformInfo *TTI)
MemoryLocation getLocation(Instruction *I)
bool isSelectedBaseLoad(Type *ScalarTy, ArrayRef< Value * > PointerOps, const DataLayout &DL, Value *&TrueBase, Value *&FalseBase, SmallVectorImpl< Value * > &Conditions)
Checks if the loads with scalar type ScalarTy and pointer operands PointerOps are each (optionally vi...
SmallBitVector getAltInstrMask(ArrayRef< Value * > VL, Type *ScalarTy, unsigned Opcode0, unsigned Opcode1)
SmallBitVector isUndefVector(const Value *V, const SmallBitVector &UseMask)
Checks if the given value is actually an undefined constant vector.
Intrinsic::ID getMaskedDivRemIntrinsic(unsigned Opcode)
bool isUsedOutsideBlock(Value *V)
Checks if the provided value does not require scheduling.
bool doesNotNeedToSchedule(ArrayRef< Value * > VL)
Checks if the specified array of instructions does not require scheduling.
std::optional< unsigned > getInsertExtractIndex(const Value *Inst, unsigned Offset)
void reorderScalars(SmallVectorImpl< Value * > &Scalars, ArrayRef< int > Mask)
Reorders the list of scalars in accordance with the given Mask.
bool allSameType(ArrayRef< Value * > VL)
bool allSameOpcode(ArrayRef< Value * > VL)
bool isSplat(ArrayRef< Value * > VL)
unsigned getNumElements(Type *Ty)
std::string shortBundleName(ArrayRef< Value * > VL, int Idx)
Print a short descriptor of the instruction bundle suitable for debug output.
unsigned getPartNumElems(unsigned Size, unsigned NumParts)
Returns power-of-2 number of elements in a single register (part), given the total number of elements...
bool isCommutableOperand(const Instruction *I, Value *ValWithUses, unsigned Op, bool IsCopyable)
Checks if the operand is commutative.
void transformScalarShuffleIndiciesToVector(unsigned VecTyNumElements, SmallVectorImpl< int > &Mask)
SmallVector< int > calculateShufflevectorMask(ArrayRef< Value * > VL)
SmallBitVector buildUseMask(int VF, ArrayRef< int > Mask, UseMask MaskArg)
Prepares a use bitset for the given mask either for the first argument or for the second.
bool isCommutative(const Instruction *I, const Value *ValWithUses, bool IsCopyable)
template SmallBitVector isUndefVector< false >(const Value *, const SmallBitVector &)
unsigned getNumberOfPotentiallyCommutativeOps(Instruction *I)
bool allConstant(ArrayRef< Value * > VL)
template std::optional< unsigned > getInsertExtractIndex< InsertElementInst >(const Value *, unsigned)
void inversePermutation(ArrayRef< unsigned > Indices, SmallVectorImpl< int > &Mask)
Compute the inverse permutation Mask of Indices.
bool allSameBlock(ArrayRef< Value * > VL)
Intrinsic::ID isEquivalentIntrinsicID(Intrinsic::ID LHS, Intrinsic::ID RHS)
Checks if LHS and RHS are the same intrinsic, or one is llvm.fma and the other is llvm....
UseMask
Specifies the way the mask should be analyzed for undefs/poisonous elements in the shuffle mask.
@ SecondArg
The mask is expected to be for permutation of 2 vectors, check for the mask elements for the second a...
@ UndefsAsMask
Consider undef mask elements (-1) as placeholders for future shuffle elements and mark them as ones a...
@ FirstArg
The mask is expected to be for permutation of 1-2 vectors, check for the mask elements for the first ...
void addMask(SmallVectorImpl< int > &Mask, ArrayRef< int > SubMask, bool ExtendingManyInputs)
Shuffles Mask in accordance with the given SubMask.
bool isSimple(Instruction *I)
bool isBinOpIdentityConstant(const Value *V, unsigned Opcode)
unsigned getShufflevectorNumGroups(ArrayRef< Value * > VL)
SmallVector< Constant * > replicateMask(ArrayRef< Constant * > Val, unsigned VF)
Replicates the given Val VF times.
bool isVectorLikeInstWithConstOps(Value *V)
Checks if V is one of vector-like instructions, i.e.
bool doesNotNeedToBeScheduled(Value *V)
Checks if the specified value does not require scheduling.
unsigned getNumElems(unsigned Size, unsigned PartNumElems, unsigned Part)
Returns correct remaining number of elements, considering total amount Size, (power-of-2 number) of e...
constexpr int UsesLimit
Limit of the number of uses for potentially transformed instructions/values, used in checks to avoid ...
bool isConstant(Value *V)
template std::optional< unsigned > getInsertExtractIndex< ExtractElementInst >(const Value *, unsigned)
void fixupOrderingIndices(MutableArrayRef< unsigned > Order)
Order may have elements assigned special value (size) which is out of bounds.
This is an optimization pass for GlobalISel generic memory operations.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI Intrinsic::ID getVectorIntrinsicIDForCall(const CallInst *CI, const TargetLibraryInfo *TLI)
Returns intrinsic ID for call.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
bool isVectorizedTy(Type *Ty)
Returns true if Ty is a vector type or a struct of vector types where all vector types share the same...
T bit_ceil(T Value)
Returns the smallest integral power of two no smaller than Value if Value is nonzero.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
ElementCount getVectorizedTypeVF(Type *Ty)
Returns the number of vector elements for a vectorized type.
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
MutableArrayRef(T &OneElt) -> MutableArrayRef< T >
constexpr int PoisonMaskElem
iterator_range(Container &&) -> iterator_range< llvm::detail::IterOfRange< Container > >
constexpr T divideCeil(U Numerator, V Denominator)
Returns the integer ceil(Numerator / Denominator).
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
constexpr auto seq(T Begin, T End)
Iterate over an integral type from Begin up to - but not including - End.
LLVM_ABI bool mayHaveNonDefUseDependency(const Instruction &I)
Returns true if the result or effects of the given instructions I depend values not reachable through...
constexpr detail::IsaCheckPredicate< Types... > IsaPred
Function object wrapper for the llvm::isa type check.