42 switch (
I->getOpcode()) {
43 case Instruction::ExtractValue:
44 case Instruction::InsertValue:
46 case Instruction::ExtractElement:
49 case Instruction::InsertElement:
59 "ScalableVectorType is not supported.");
70 return std::min<unsigned>(PartNumElems,
Size - Part * PartNumElems);
78 OS <<
"Idx: " << Idx <<
", ";
79 OS <<
"n=" << VL.
size() <<
" [" << *VL.
front() <<
", ..]";
100 if (BB !=
II->getParent())
113 Value *FirstNonUndef =
nullptr;
114 for (
Value *V : VL) {
117 if (!FirstNonUndef) {
121 if (V != FirstNonUndef)
124 return FirstNonUndef !=
nullptr;
130 return Cmp->isCommutative();
132 return BO->isCommutative() ||
133 (BO->getOpcode() == Instruction::Sub && ValWithUses->
hasUseList() &&
140 if (match(U.getUser(),
141 m_ICmp(Pred, m_Specific(U.get()), m_Zero())) &&
142 (Pred == ICmpInst::ICMP_EQ || Pred == ICmpInst::ICMP_NE))
146 auto *I = dyn_cast<BinaryOperator>(U.get());
147 return match(U.getUser(),
148 m_Intrinsic<Intrinsic::abs>(
149 m_Specific(U.get()), m_ConstantInt(Flag))) &&
150 ((!IsCopyable && I && !I->hasNoSignedWrap()) ||
153 (BO->getOpcode() == Instruction::FSub && ValWithUses->
hasUseList() &&
156 return match(U.getUser(),
157 m_Intrinsic<Intrinsic::fabs>(m_Specific(U.get())));
159 return I->isCommutative();
167 "The instruction is not commutative.");
171 switch (BO->getOpcode()) {
172 case Instruction::Sub:
173 case Instruction::FSub:
179 return I->isCommutableOperand(
Op);
186 constexpr unsigned IntrinsicNumOperands = 2;
187 return IntrinsicNumOperands;
189 return I->getNumOperands();
204 Type *CurrentType =
IV->getType();
205 for (
unsigned I :
IV->indices()) {
207 Index *= ST->getNumElements();
208 CurrentType = ST->getElementType(
I);
210 Index *= AT->getNumElements();
211 CurrentType = AT->getElementType();
230 if (auto *CI = dyn_cast<CmpInst>(V))
231 return BasePred == CI->getPredicate();
232 if (auto *I = dyn_cast<Instruction>(V))
233 return I->getOpcode() == Opcode;
234 return isa<PoisonValue>(V);
239 unsigned Opcode = E->getOpcode();
240 assert((Opcode == Instruction::ExtractElement ||
241 Opcode == Instruction::ExtractValue) &&
242 "Expected extractelement or extractvalue instruction.");
243 if (Opcode == Instruction::ExtractElement) {
249 unsigned Idx = CI->getZExtValue();
257 if (EI->getNumIndices() != 1)
259 return *EI->idx_begin();
265 const unsigned E = Indices.
size();
267 for (
unsigned I = 0;
I < E; ++
I)
268 Mask[Indices[
I]] =
I;
272 assert(!Mask.empty() &&
"Expected non-empty mask.");
276 for (
unsigned I = 0, E = Prev.
size();
I < E; ++
I)
278 Scalars[Mask[
I]] = Prev[
I];
282 assert(!VL.
empty() &&
"Expected non-empty list of values.");
284 return all_of(VL, [&](
Value *V) {
return V->getType() == Ty; });
290 static_assert(std::is_same_v<T, InsertElementInst> ||
291 std::is_same_v<T, ExtractElementInst>,
298 constexpr bool IsInsert = std::is_same_v<T, InsertElementInst>;
299 Type *VecTy = IsInsert ? IE->getType() : IE->getOperand(0)->getType();
306 if (CI->getValue().uge(VT->getNumElements()))
309 Index *= VT->getNumElements();
310 Index += CI->getZExtValue();
316template std::optional<unsigned>
318template std::optional<unsigned>
327 auto *IO = dyn_cast<Instruction>(V);
330 return isa<PHINode>(IO) || IO->getParent() != I->getParent();
339 return !
I->mayReadOrWriteMemory() && !
I->hasNUsesOrMore(
UsesLimit) &&
341 auto *IU = dyn_cast<Instruction>(U);
344 return IU->getParent() != I->getParent() || isa<PHINode>(IU);
353 return !VL.
empty() &&
366 I * VecTyNumElements, VecTyNumElements)))
368 : Mask[
I] * VecTyNumElements + J;
378 unsigned SVNumElements =
380 unsigned ShuffleMaskSize = SV->getShuffleMask().size();
381 if (SVNumElements % ShuffleMaskSize != 0)
383 unsigned GroupSize = SVNumElements / ShuffleMaskSize;
384 if (GroupSize == 0 || (VL.
size() % GroupSize) != 0)
386 unsigned NumGroup = 0;
387 for (
size_t I = 0, E = VL.
size();
I != E;
I += GroupSize) {
389 Value *Src = SV->getOperand(0);
395 if (SV->getOperand(0) != Src)
398 if (!SV->isExtractSubvectorMask(Index))
400 ExpectedIndex.
set(Index / ShuffleMaskSize);
404 if (!ExpectedIndex.
all())
408 assert(NumGroup == (VL.
size() / GroupSize) &&
"Unexpected number of groups");
415 unsigned SVNumElements =
418 unsigned AccumulateLength = 0;
419 for (
Value *V : VL) {
421 for (
int M : SV->getShuffleMask())
423 : AccumulateLength + M);
424 AccumulateLength += SVNumElements;
445template <
bool IsPoisonOnly>
448 using T = std::conditional_t<IsPoisonOnly, PoisonValue, UndefValue>;
482 for (
unsigned I = 0, E = VecTy->getNumElements();
I != E; ++
I) {
483 if (
Constant *Elem =
C->getAggregateElement(
I))
503 case Instruction::Load: {
507 case Instruction::Store: {
509 return (
SI->getPointerOperand() == Scalar);
511 case Instruction::Call: {
515 return isVectorIntrinsicWithScalarOpAtArg(ID, Arg.index(), TTI) &&
516 Arg.value().get() == Scalar;
534 return LI->isSimple();
536 return SI->isSimple();
538 return !
MI->isVolatile();
543 bool ExtendingManyInputs) {
547 (!ExtendingManyInputs || SubMask.
size() > Mask.size() ||
550 "SubMask with many inputs support must be larger than the mask.");
552 Mask.append(SubMask.
begin(), SubMask.
end());
556 int TermValue = std::min(Mask.size(), SubMask.
size());
557 for (
int I = 0, E = SubMask.
size();
I < E; ++
I) {
559 (!ExtendingManyInputs &&
560 (SubMask[
I] >= TermValue || Mask[SubMask[
I]] >= TermValue)))
562 NewMask[
I] = Mask[SubMask[
I]];
568 const size_t Sz = Order.
size();
571 for (
unsigned I = 0;
I < Sz; ++
I) {
573 UnusedIndices.
reset(Order[
I]);
575 MaskedIndices.
set(
I);
577 if (MaskedIndices.
none())
580 "Non-synced masked/available indices.");
584 assert(Idx >= 0 &&
"Indices must be synced.");
592 unsigned Opcode0,
unsigned Opcode1) {
599 OpcodeMask.
set(Lane * ScalarTyNumElements,
600 Lane * ScalarTyNumElements + ScalarTyNumElements);
607 "Expected scalar constants.");
610 std::fill_n(NewVal.begin() +
I * VF, VF, V);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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]
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.
This is an important base class in LLVM.
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 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.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
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)
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.
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)
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)
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.