45 case Instruction::Sub:
46 return Instruction::Add;
47 case Instruction::FSub:
48 return Instruction::FAdd;
55 if (
I->getOpcode() == Instruction::Sub)
57 if (
I->getOpcode() == Instruction::FSub)
58 return I->hasAllowReassoc();
59 return I->isAssociative();
67 switch (
I->getOpcode()) {
68 case Instruction::ExtractValue:
69 case Instruction::InsertValue:
71 case Instruction::ExtractElement:
74 case Instruction::InsertElement:
84 "ScalableVectorType is not supported.");
95 return std::min<unsigned>(PartNumElems,
Size - Part * PartNumElems);
103 OS <<
"Idx: " << Idx <<
", ";
104 OS <<
"n=" << VL.
size() <<
" [" << *VL.
front() <<
", ..]";
125 if (BB !=
II->getParent())
138 Value *FirstNonUndef =
nullptr;
139 for (
Value *V : VL) {
142 if (!FirstNonUndef) {
146 if (V != FirstNonUndef)
149 return FirstNonUndef !=
nullptr;
155 if ((LHS == Intrinsic::fma || LHS == Intrinsic::fmuladd) &&
156 (RHS == Intrinsic::fma || RHS == Intrinsic::fmuladd))
157 return Intrinsic::fma;
164 return Cmp->isCommutative();
166 return BO->isCommutative() ||
167 (BO->getOpcode() == Instruction::Sub && ValWithUses->
hasUseList() &&
174 if (match(U.getUser(),
175 m_ICmp(Pred, m_Specific(U.get()), m_Zero())) &&
176 (Pred == ICmpInst::ICMP_EQ || Pred == ICmpInst::ICMP_NE))
180 auto *I = dyn_cast<BinaryOperator>(U.get());
181 return match(U.getUser(),
182 m_Intrinsic<Intrinsic::abs>(
183 m_Specific(U.get()), m_ConstantInt(Flag))) &&
184 ((!IsCopyable && I && !I->hasNoSignedWrap()) ||
187 (BO->getOpcode() == Instruction::FSub && ValWithUses->
hasUseList() &&
190 return match(U.getUser(),
191 m_Intrinsic<Intrinsic::fabs>(m_Specific(U.get())));
193 return I->isCommutative();
201 "The instruction is not commutative.");
205 switch (BO->getOpcode()) {
206 case Instruction::Sub:
207 case Instruction::FSub:
213 return I->isCommutableOperand(
Op);
220 constexpr unsigned IntrinsicNumOperands = 2;
221 return IntrinsicNumOperands;
223 return I->getNumOperands();
238 Type *CurrentType =
IV->getType();
239 for (
unsigned I :
IV->indices()) {
241 Index *= ST->getNumElements();
242 CurrentType = ST->getElementType(
I);
244 Index *= AT->getNumElements();
245 CurrentType = AT->getElementType();
264 if (auto *CI = dyn_cast<CmpInst>(V))
265 return BasePred == CI->getPredicate();
266 if (auto *I = dyn_cast<Instruction>(V))
267 return I->getOpcode() == Opcode;
268 return isa<PoisonValue>(V);
273 unsigned Opcode = E->getOpcode();
274 assert((Opcode == Instruction::ExtractElement ||
275 Opcode == Instruction::ExtractValue) &&
276 "Expected extractelement or extractvalue instruction.");
277 if (Opcode == Instruction::ExtractElement) {
283 unsigned Idx = CI->getZExtValue();
291 if (EI->getNumIndices() != 1)
293 return *EI->idx_begin();
299 const unsigned E = Indices.
size();
301 for (
unsigned I = 0;
I < E; ++
I)
302 Mask[Indices[
I]] =
I;
306 assert(!Mask.empty() &&
"Expected non-empty mask.");
310 for (
unsigned I = 0, E = Prev.
size();
I < E; ++
I)
312 Scalars[Mask[
I]] = Prev[
I];
316 assert(!VL.
empty() &&
"Expected non-empty list of values.");
318 return all_of(VL, [&](
Value *V) {
return V->getType() == Ty; });
324 static_assert(std::is_same_v<T, InsertElementInst> ||
325 std::is_same_v<T, ExtractElementInst>,
332 constexpr bool IsInsert = std::is_same_v<T, InsertElementInst>;
333 Type *VecTy = IsInsert ? IE->getType() : IE->getOperand(0)->getType();
340 if (CI->getValue().uge(VT->getNumElements()))
343 Index *= VT->getNumElements();
344 Index += CI->getZExtValue();
350template std::optional<unsigned>
352template std::optional<unsigned>
361 auto *IO = dyn_cast<Instruction>(V);
364 return isa<PHINode>(IO) || IO->getParent() != I->getParent();
373 return !
I->mayReadOrWriteMemory() && !
I->hasNUsesOrMore(
UsesLimit) &&
375 auto *IU = dyn_cast<Instruction>(U);
378 return IU->getParent() != I->getParent() || isa<PHINode>(IU);
387 return !VL.
empty() &&
400 I * VecTyNumElements, VecTyNumElements)))
402 : Mask[
I] * VecTyNumElements + J;
412 unsigned SVNumElements =
414 unsigned ShuffleMaskSize = SV->getShuffleMask().size();
415 if (SVNumElements % ShuffleMaskSize != 0)
417 unsigned GroupSize = SVNumElements / ShuffleMaskSize;
418 if (GroupSize == 0 || (VL.
size() % GroupSize) != 0)
420 unsigned NumGroup = 0;
421 for (
size_t I = 0, E = VL.
size();
I != E;
I += GroupSize) {
423 Value *Src = SV->getOperand(0);
429 if (SV->getOperand(0) != Src)
432 if (!SV->isExtractSubvectorMask(Index))
434 ExpectedIndex.
set(Index / ShuffleMaskSize);
438 if (!ExpectedIndex.
all())
442 assert(NumGroup == (VL.
size() / GroupSize) &&
"Unexpected number of groups");
449 unsigned SVNumElements =
452 unsigned AccumulateLength = 0;
453 for (
Value *V : VL) {
455 for (
int M : SV->getShuffleMask())
457 : AccumulateLength + M);
458 AccumulateLength += SVNumElements;
479template <
bool IsPoisonOnly>
482 using T = std::conditional_t<IsPoisonOnly, PoisonValue, UndefValue>;
516 for (
unsigned I = 0, E = VecTy->getNumElements();
I != E; ++
I) {
517 if (
Constant *Elem =
C->getAggregateElement(
I))
537 case Instruction::Load: {
541 case Instruction::Store: {
543 return (
SI->getPointerOperand() == Scalar);
545 case Instruction::Call: {
549 return isVectorIntrinsicWithScalarOpAtArg(ID, Arg.index(), TTI) &&
550 Arg.value().get() == Scalar;
568 return LI->isSimple();
570 return SI->isSimple();
572 return !
MI->isVolatile();
582 uint64_t ScalarSize =
DL.getTypeStoreSize(ScalarTy);
583 Conditions.
assign(PointerOps.
size(),
nullptr);
588 APInt OffsetAP(
DL.getIndexTypeSizeInBits(
GEP->getType()), 0);
589 if (!
GEP->accumulateConstantOffset(
DL, OffsetAP) || OffsetAP.
isNegative())
592 Base =
GEP->getPointerOperand();
597 Value *
T = Sel->getTrueValue();
598 Value *
F = Sel->getFalseValue();
604 }
else if (TrueBase !=
T || FalseBase !=
F) {
611 Conditions[Idx] = Sel->getCondition();
613 return TrueBase !=
nullptr;
617 bool ExtendingManyInputs) {
621 (!ExtendingManyInputs || SubMask.
size() > Mask.size() ||
624 "SubMask with many inputs support must be larger than the mask.");
626 Mask.append(SubMask.
begin(), SubMask.
end());
630 int TermValue = std::min(Mask.size(), SubMask.
size());
631 for (
int I = 0, E = SubMask.
size();
I < E; ++
I) {
633 (!ExtendingManyInputs &&
634 (SubMask[
I] >= TermValue || Mask[SubMask[
I]] >= TermValue)))
636 NewMask[
I] = Mask[SubMask[
I]];
642 const size_t Sz = Order.
size();
645 for (
unsigned I = 0;
I < Sz; ++
I) {
647 UnusedIndices.
reset(Order[
I]);
649 MaskedIndices.
set(
I);
651 if (MaskedIndices.
none())
654 "Non-synced masked/available indices.");
658 assert(Idx >= 0 &&
"Indices must be synced.");
666 unsigned Opcode0,
unsigned Opcode1) {
673 OpcodeMask.
set(Lane * ScalarTyNumElements,
674 Lane * ScalarTyNumElements + ScalarTyNumElements);
681 "Expected scalar constants.");
684 std::fill_n(NewVal.begin() +
I * VF, VF, V);
690 case Instruction::UDiv:
691 return Intrinsic::masked_udiv;
692 case Instruction::SDiv:
693 return Intrinsic::masked_sdiv;
694 case Instruction::URem:
695 return Intrinsic::masked_urem;
696 case Instruction::SRem:
697 return Intrinsic::masked_srem;
708 constexpr unsigned MaxIndexChainLength = 3;
711 auto IsProfitableOperand = [](
const Value *V) {
715 V = Cast->getOperand(0);
718 const User *U =
I->user_back();
719 for ([[maybe_unused]]
unsigned _ :
seq<unsigned>(MaxIndexChainLength)) {
722 none_of(
I->operand_values(), IsProfitableOperand);
736 unsigned Opcode = BO->getOpcode();
737 Type *Ty = BO->getType();
741 Opcode, Ty, Idx == 1) ||
743 Opcode, Ty, Idx == 0)))
747 const User *U =
I->user_back();
759 if (!Wide || !Wide->hasOneUse())
762 if (!Narrow || !Narrow->hasOneUse())
764 Value *Src = Narrow->getOperand(0);
767 if (MustBeElidable && !(Wide->hasAllowContract() && Wide->hasNoNaNs() &&
768 Wide->hasNoInfs() && Narrow->hasAllowContract()))
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 * getBinOpAbsorber(unsigned Opcode, Type *Ty, bool AllowLHSConstant=false)
Return the absorbing element for the given binary operation, i.e.
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.
bool isOnceUsedSeed(const Instruction *I)
Returns true if I forms a vectorizable bundle on its own and its single user does not tear the vector...
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)
bool isReassocChainLink(const Instruction *I)
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)
Instruction * lookThroughCastRoundTrip(Value *V, bool MustBeElidable)
If V is a single-use fpext of a single-use fptrunc forming a round-trip back to the type of V,...
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.
unsigned getReassocCombineOpcode(unsigned Opcode)
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)
static bool isNonProfitableIndex(const Instruction *I)
Returns true if I is a part of a single-use chain, computing an address, which does not pay off the 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.