48std::pair<Constant *, unsigned>
49BinOpSameOpcodeHelper::isBinOpWithConstant(
const Instruction *
I) {
50 [[maybe_unused]]
unsigned Opcode =
I->getOpcode();
59 if (
Constant *
C = GetConstant(BinOp->getOperand(1)))
63 if (Constant *
C = GetConstant(BinOp->getOperand(0)))
68bool BinOpSameOpcodeHelper::InterchangeableInfo::trySet(
69 MaskType OpcodeInMaskForm, MaskType InterchangeableMask) {
70 if (Mask & InterchangeableMask) {
71 SeenBefore |= OpcodeInMaskForm;
72 Mask &= InterchangeableMask;
78unsigned BinOpSameOpcodeHelper::InterchangeableInfo::getOpcode()
const {
79 MaskType Candidate =
Mask & SeenBefore;
80 if (Candidate & MainOpBIT)
81 return I->getOpcode();
82 if (Candidate & ShlBIT)
83 return Instruction::Shl;
84 if (Candidate & AShrBIT)
85 return Instruction::AShr;
86 if (Candidate & MulBIT)
87 return Instruction::Mul;
88 if (Candidate & AddBIT)
89 return Instruction::Add;
90 if (Candidate & SubBIT)
91 return Instruction::Sub;
92 if (Candidate & FAddBIT)
93 return Instruction::FAdd;
94 if (Candidate & FSubBIT)
95 return Instruction::FSub;
96 if (Candidate & AndBIT)
97 return Instruction::And;
98 if (Candidate & OrBIT)
99 return Instruction::Or;
100 if (Candidate & XorBIT)
101 return Instruction::Xor;
105bool BinOpSameOpcodeHelper::InterchangeableInfo::hasCandidateOpcode(
106 unsigned Opcode)
const {
107 MaskType Candidate =
Mask & SeenBefore;
109 case Instruction::Shl:
110 return Candidate & ShlBIT;
111 case Instruction::AShr:
112 return Candidate & AShrBIT;
113 case Instruction::Mul:
114 return Candidate & MulBIT;
115 case Instruction::Add:
116 return Candidate & AddBIT;
117 case Instruction::Sub:
118 return Candidate & SubBIT;
119 case Instruction::And:
120 return Candidate & AndBIT;
121 case Instruction::Or:
122 return Candidate & OrBIT;
123 case Instruction::Xor:
124 return Candidate & XorBIT;
125 case Instruction::FAdd:
126 return Candidate & FAddBIT;
127 case Instruction::FSub:
128 return Candidate & FSubBIT;
129 case Instruction::LShr:
130 case Instruction::FMul:
131 case Instruction::SDiv:
132 case Instruction::UDiv:
133 case Instruction::FDiv:
134 case Instruction::SRem:
135 case Instruction::URem:
136 case Instruction::FRem:
145 const Instruction *To)
const {
147 unsigned FromOpcode =
I->getOpcode();
148 if (FromOpcode == ToOpcode)
151 auto [
C, Pos] = isBinOpWithConstant(
I);
152 Type *RHSType =
I->getOperand(Pos)->getType();
158 "Cannot convert the instruction.");
159 RHS = ConstantFP::get(RHSType, -CFP->getValueAPF());
162 const APInt &FromCIValue = CI->getValue();
163 unsigned FromCIValueBitWidth = FromCIValue.
getBitWidth();
164 switch (FromOpcode) {
165 case Instruction::Shl:
166 if (ToOpcode == Instruction::Add && FromCIValue.
isOne())
167 return {
I->getOperand(0),
I->getOperand(0)};
168 if (ToOpcode == Instruction::Mul) {
169 RHS = ConstantInt::get(RHSType,
173 assert(FromCIValue.
isZero() &&
"Cannot convert the instruction.");
178 case Instruction::Mul:
180 if (ToOpcode == Instruction::Shl) {
181 RHS = ConstantInt::get(
182 RHSType, APInt(FromCIValueBitWidth, FromCIValue.
logBase2()));
184 assert(FromCIValue.
isOne() &&
"Cannot convert the instruction.");
189 case Instruction::Add:
190 case Instruction::Sub:
191 if (FromCIValue.
isZero()) {
196 "Cannot convert the instruction.");
197 APInt NegatedVal = APInt(FromCIValue);
199 RHS = ConstantInt::get(RHSType, NegatedVal);
202 case Instruction::And:
208 assert(FromCIValue.
isZero() &&
"Cannot convert the instruction.");
223bool BinOpSameOpcodeHelper::isValidForAlternation(
const Instruction *
I)
const {
228bool BinOpSameOpcodeHelper::initializeAltOp(
const Instruction *
I) {
231 if (!isValidForAlternation(
I))
239 "BinOpSameOpcodeHelper only accepts BinaryOperator.");
240 unsigned Opcode =
I->getOpcode();
241 MaskType OpcodeInMaskForm;
245 case Instruction::Shl:
246 OpcodeInMaskForm = ShlBIT;
248 case Instruction::AShr:
249 OpcodeInMaskForm = AShrBIT;
251 case Instruction::Mul:
252 OpcodeInMaskForm = MulBIT;
254 case Instruction::Add:
255 OpcodeInMaskForm = AddBIT;
257 case Instruction::Sub:
258 OpcodeInMaskForm = SubBIT;
260 case Instruction::And:
261 OpcodeInMaskForm = AndBIT;
263 case Instruction::Or:
264 OpcodeInMaskForm = OrBIT;
266 case Instruction::Xor:
267 OpcodeInMaskForm = XorBIT;
269 case Instruction::FAdd:
270 OpcodeInMaskForm = FAddBIT;
272 case Instruction::FSub:
273 OpcodeInMaskForm = FSubBIT;
276 return MainOp.equal(Opcode) || (initializeAltOp(
I) && AltOp.equal(Opcode));
278 MaskType InterchangeableMask = OpcodeInMaskForm;
279 auto [
C, Pos] = isBinOpWithConstant(
I);
281 constexpr MaskType CanBeAll =
282 XorBIT | OrBIT | AndBIT | SubBIT | AddBIT | MulBIT | AShrBIT | ShlBIT;
283 const APInt &CIValue = CI->getValue();
285 case Instruction::Shl:
287 InterchangeableMask = CIValue.
isZero() ? CanBeAll : MulBIT | ShlBIT;
289 InterchangeableMask |= AddBIT;
291 case Instruction::Mul:
292 if (CIValue.
isOne()) {
293 InterchangeableMask = CanBeAll;
297 InterchangeableMask = MulBIT | ShlBIT;
299 case Instruction::Add:
300 case Instruction::Sub:
301 InterchangeableMask = CIValue.
isZero() ? CanBeAll : SubBIT | AddBIT;
303 case Instruction::And:
305 InterchangeableMask = CanBeAll;
307 case Instruction::Xor:
309 InterchangeableMask = XorBIT | OrBIT | SubBIT | AddBIT;
313 InterchangeableMask = CanBeAll;
316 }
else if (
C && Pos == 1) {
324 InterchangeableMask = FSubBIT | FAddBIT;
326 return MainOp.trySet(OpcodeInMaskForm, InterchangeableMask) ||
327 (initializeAltOp(
I) &&
328 AltOp.trySet(OpcodeInMaskForm, InterchangeableMask));
334static std::optional<std::pair<bool, APInt>>
336 const unsigned BW =
C.getBitWidth();
343 return std::make_pair(
false,
C);
345 return std::make_pair(
true,
C);
349 return std::make_pair(
false, Min);
351 return std::make_pair(
true,
C);
356 return std::make_pair(
false,
C);
358 return std::make_pair(
true, Max);
363 return std::make_pair(
true,
C);
365 return std::make_pair(
false, Max);
370 return std::make_pair(
true, Min);
372 return std::make_pair(
false,
C);
380CmpSamePredicateHelper::MaskType
382 MaskType M = getBit(Pred);
386 const auto &[IsComplement,
K] = *Family;
394 M |= IsComplement ? HiU : LoU;
396 M |= IsComplement ? LoU : HiU;
397 if (
K.isMinSignedValue())
398 M |= IsComplement ? HiS : LoS;
399 if (
K.isMaxSignedValue())
400 M |= IsComplement ? LoS : HiS;
404APInt CmpSamePredicateHelper::getFamilyConstant(
bool IsComplement,
427static std::optional<std::pair<CmpInst::Predicate, APInt>>
430 TI && TI->getType()->isIntOrIntVectorTy(1))
431 return std::make_pair(
437 return std::make_pair(CI->getPredicate(), *
C);
441CmpSamePredicateHelper::MaskType
442CmpSamePredicateHelper::getLaneMask(
const Instruction *
I) {
443 if (std::optional<std::pair<CmpInst::Predicate, APInt>> Cmp =
445 MaskType M = getFormsMask(Cmp->first, Cmp->second);
450 return getBit(CI->getPredicate());
458 std::optional<std::pair<CmpInst::Predicate, APInt>> Cmp =
462 std::optional<std::pair<bool, APInt>> Family =
464 return Family && Family->second.isZero();
469 SeenBefore |= getBit(CI->getPredicate());
470 Mask &= getLaneMask(
I);
476 MaskType Candidate = Mask & SeenBefore;
509 return ConstantInt::get(
I->getOperand(0)->getType(), 1);
511 std::optional<std::pair<bool, APInt>> Family =
513 assert(Family &&
"Expected a boundary family for a convertible compare.");
514 const auto &[IsComplement,
K] = *Family;
515 return ConstantInt::get(
I->getOperand(0)->getType(),
516 getFamilyConstant(IsComplement,
K, Pred));
526 if (
I->getOpcode() !=
Op->getOpcode())
533 IOp->getIntrinsicID()) !=
539 assert(MainOp &&
"MainOp cannot be nullptr.");
542 if (MainOp->getOpcode() == Instruction::Select &&
545 if (MainOp->getOpcode() == Instruction::ICmp &&
549 assert(AltOp &&
"AltOp cannot be nullptr.");
553 if (!
I->isBinaryOp() || !MainOp->isBinaryOp())
560 if (AltConverter.
add(
I) && AltConverter.
add(AltOp) &&
566 return Converter.hasAltOp() ? AltOp : MainOp;
570 constexpr std::array<unsigned, 8> MulDiv = {
571 Instruction::Mul, Instruction::FMul, Instruction::SDiv,
572 Instruction::UDiv, Instruction::FDiv, Instruction::SRem,
573 Instruction::URem, Instruction::FRem};
579 constexpr std::array<unsigned, 4> AddSub = {
580 Instruction::Add, Instruction::Sub, Instruction::FAdd, Instruction::FSub};
590 assert(
valid() &&
"InstructionsState is invalid.");
604 return C &&
C->getValue().getActiveBits() <=
611 if (
getOpcode() == Instruction::GetElementPtr)
613 GEP && (
GEP->getNumOperands() != 2 ||
614 GEP->getSourceElementType() !=
617 if (
I->getParent() != MainOp->getParent() &&
624 if (!
I->isBinaryOp() || !MainOp->isBinaryOp())
634 (
I->getOpcode() == Instruction::FMul ||
635 I->getOpcode() == Instruction::FAdd) &&
637 return is_contained(VL, Op);
644 (
I->getOpcode() == Instruction::FMul ||
645 I->getOpcode() == Instruction::FAdd) &&
650 bool HasFMulOrFAdd =
false;
658 HasFMulOrFAdd =
true;
660 return HasFMulOrFAdd;
664 assert(
valid() &&
"InstructionsState is invalid.");
670 auto CheckForTransformedOpcode = [](
const Instruction *RefOp,
673 case Instruction::Add:
674 switch (ExpandingOp->getOpcode()) {
675 case Instruction::Shl:
692 return CheckForTransformedOpcode(MainOp, ExpandingOp);
697 switch (
I->getOpcode()) {
698 case Instruction::Shl:
707 assert(
valid() &&
"InstructionsState is invalid.");
717 auto IsNonSchedulableCopyableElement = [
this](
Value *V) {
719 return !
I ||
isa<PHINode>(
I) ||
I->getParent() != MainOp->getParent() ||
724 !MainOp->comesBefore(
I));
727 return IsNonSchedulableCopyableElement(V);
746 if (Inst->getOpcode() == Opcode)
760 BaseOp0 == Op0 || BaseOp1 == Op1 ||
771 "Assessing comparisons of different types?");
781 return (BasePred == Pred &&
783 (BasePred == SwappedPred &&
800 (VL.
size() == 2 && InstCnt < 2))
815 unsigned AltOpcode = Opcode;
818 bool SwappedPredsCompatible = IsCmpOp && [&]() {
820 UniquePreds.
insert(BasePred);
821 UniqueNonSwappedPreds.
insert(BasePred);
822 for (
Value *V : VL) {
829 UniqueNonSwappedPreds.
insert(CurrentPred);
830 if (!UniquePreds.
contains(CurrentPred) &&
831 !UniquePreds.
contains(SwappedCurrentPred))
832 UniquePreds.
insert(CurrentPred);
837 return UniqueNonSwappedPreds.
size() > 2 && UniquePreds.
size() == 2;
843 InterchangeablePred =
855 bool AnyPoison = InstCnt != VL.
size();
865 unsigned InstOpcode =
I->getOpcode();
867 if (BinOpHelper.
add(
I))
872 Value *Op1 =
I->getOperand(0);
875 if (InstOpcode == Opcode || InstOpcode == AltOpcode)
877 if (Opcode == AltOpcode) {
880 "Cast isn't safe for alternation, logic needs to be updated!");
881 AltOpcode = InstOpcode;
888 Type *Ty0 = BaseInst->getOperand(0)->getType();
889 Type *Ty1 = Inst->getOperand(0)->getType();
891 assert(InstOpcode == Opcode &&
"Expected same CmpInst opcode.");
892 assert(InstOpcode == AltOpcode &&
893 "Alternate instructions are only supported by BinaryOperator "
901 if ((VL.
size() == 2 || SwappedPredsCompatible) &&
902 (BasePred == CurrentPred || BasePred == SwappedCurrentPred))
910 if (MainOp != AltOp) {
913 }
else if (BasePred != CurrentPred) {
916 "CmpInst isn't safe for alternation, logic needs to be updated!");
921 if (BasePred == CurrentPred || BasePred == SwappedCurrentPred ||
922 AltPred == CurrentPred || AltPred == SwappedCurrentPred)
937 }
else if (InstOpcode == Opcode) {
938 assert(InstOpcode == AltOpcode &&
939 "Alternate instructions are only supported by BinaryOperator and "
942 if (Gep->getNumOperands() != 2 ||
950 if (!LI->isSimple() || !BaseLI->isSimple())
960 if (
Call->hasOperandBundles() &&
962 !std::equal(
Call->op_begin() +
Call->getBundleOperandsStartIndex(),
963 Call->op_begin() +
Call->getBundleOperandsEndIndex(),
972 if (Mappings.
size() != BaseMappings.
size() ||
973 Mappings.
front().ISA != BaseMappings.
front().ISA ||
974 Mappings.
front().ScalarName != BaseMappings.
front().ScalarName ||
975 Mappings.
front().VectorName != BaseMappings.
front().VectorName ||
976 Mappings.
front().Shape.VF != BaseMappings.
front().Shape.VF ||
977 Mappings.
front().Shape.Parameters !=
978 BaseMappings.
front().Shape.Parameters)
992 assert(MainOp &&
"Cannot find MainOp with Opcode from BinOpHelper.");
994 assert(AltOp &&
"Cannot find AltOp with Opcode from BinOpHelper.");
1008 InterchangeablePred != BasePred) {
1013 return CI && CI->getPredicate() == InterchangeablePred;
1016 "Expected an instruction with the shared predicate.");
1020 "Incorrect implementation of allSameOpcode.");
1027 "Invalid InstructionsState.");
1031std::pair<Instruction *, SmallVector<Value *>>
1034 assert(SelectedOp &&
"Cannot convert the instruction.");
1035 if (
I->isBinaryOp()) {
1037 return std::make_pair(SelectedOp,
Converter.getOperand(SelectedOp));
1048 I, MainCI->getPredicate()))
1049 return std::make_pair(SelectedOp,
1060 assert(MainP != AltP &&
"Expected different main/alternate predicates.");
1069 assert((MainP ==
P || AltP ==
P || MainP == SwappedP || AltP == SwappedP) &&
1070 "CmpInst expected to match either main or alternate predicate or "
1072 return MainP !=
P && MainP != SwappedP;
1082 const unsigned NumLanes = VL.
size();
1094 if (!
I || !
I->hasOneUse() ||
I->getOpcode() != LaneOpcodes[Lane] ||
1105 if (GetChainLink(Lane, Columns[0][Lane]))
1107 Instruction *Link = GetChainLink(Lane, Columns[1][Lane]);
1110 std::swap(Columns[0][Lane], Columns[1][Lane]);
1114 return GetChainLink(Lane, Columns[0][Lane]) !=
nullptr;
1118 Instruction *Link = GetChainLink(Lane, Columns[0][Lane]);
1127 NewColumn[Lane] = Link->
getOperand(1 - RunningOp);
1128 Columns[0][Lane] = Link->
getOperand(RunningOp);
1130 Columns.
insert(std::next(Columns.
begin()), std::move(NewColumn));
1133 "Normalization guarantees at least one peeled level.");
1134 SubLanes.
resize(NumLanes);
1136 if (LaneOpcodes[Lane] == Instruction::Sub ||
1137 LaneOpcodes[Lane] == Instruction::FSub)
1142std::pair<Instruction *, Instruction *>
1174 "Expected different main and alt instructions.");
1175 return std::make_pair(MainOp, AltOp);
1183 "Expected extractvalue instruction state.");
1189 for (
Value *V : VL) {
1191 Aggregates.push_back(VL0->getAggregateOperand());
1195 if (
IV->getIndices() != VL0Indices ||
1198 Value *Agg =
IV->getAggregateOperand();
1202 if (AggState && AggState.
getOpcode() == Instruction::Call &&
const TargetLowering & TLI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file implements a class to represent arbitrary precision integral constant values and operations...
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
Scalar Replacement Of Aggregates
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallVector class.
This file implements the C++20 <bit> header.
static const uint32_t IV[8]
Class for arbitrary precision integers.
uint64_t getZExtValue() const
Get zero extended value.
static APInt getMaxValue(unsigned numBits)
Gets maximum unsigned value of APInt for specific bit width.
bool isAllOnes() const
Determine if all bits are set. This is true for zero-width values.
bool isZero() const
Determine if this value is zero, i.e. all bits are clear.
unsigned getBitWidth() const
Return the number of bits in the APInt.
bool ult(const APInt &RHS) const
Unsigned less than comparison.
static APInt getSignedMaxValue(unsigned numBits)
Gets maximum signed value of APInt for a specific bit width.
static APInt getSignedMinValue(unsigned numBits)
Gets minimum signed value of APInt for a specific bit width.
unsigned logBase2() const
bool isPowerOf2() const
Check if this APInt's value is a power of two greater than zero.
static APInt getZero(unsigned numBits)
Get the '0' value for the specified bit-width.
bool isOne() const
Determine if this is a value of 1.
static APInt getOneBitSet(unsigned numBits, unsigned BitNo)
Return an APInt with exactly one bit set in the result.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
Get the array size.
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
unsigned getBundleOperandsStartIndex() const
Return the index of the first bundle operand in the Use array.
bool hasOperandBundles() const
Return true if this User has any operand bundles.
This class is the base class for the comparison instructions.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ ICMP_SLT
signed less than
@ ICMP_SLE
signed less or equal
@ ICMP_UGE
unsigned greater or equal
@ ICMP_UGT
unsigned greater than
@ ICMP_SGT
signed greater than
@ ICMP_ULT
unsigned less than
@ ICMP_SGE
signed greater or equal
@ ICMP_ULE
unsigned less or equal
Predicate getSwappedPredicate() const
For example, EQ->EQ, SLE->SGE, ULT->UGT, OEQ->OEQ, ULE->UGE, OLT->OGT, etc.
Predicate getInversePredicate() const
For example, EQ -> NE, UGT -> ULE, SLT -> SGE, OEQ -> UNE, UGT -> OLE, OLT -> UGE,...
Predicate getPredicate() const
Return the predicate for this instruction.
bool isIntPredicate() const
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.
This instruction compares its operands according to the predicate given to the constructor.
LLVM_ABI bool isCommutative() const LLVM_READONLY
Return true if the instruction is commutative:
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
static bool isFMulAddIntrinsic(Instruction *I)
Returns true if the instruction is a call to the llvm.fmuladd intrinsic.
A vector that has set insertion semantics.
size_type size() const
Determine the number of elements in the SetVector.
bool contains(const_arg_type key) const
Check if the SetVector contains the given key.
bool insert(const value_type &X)
Insert a new element into the SetVector.
This is a 'bitvector' (really, a variable-sized bit array), optimized for the case when the array is ...
void resize(unsigned N, bool t=false)
Grow or shrink the bitvector.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void assign(size_type NumElts, ValueParamT Elt)
reference emplace_back(ArgTypes &&... Args)
iterator insert(iterator I, T &&Elt)
void swap(SmallVectorImpl &RHS)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
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.
bool isIntOrIntVectorTy() const
Return true if this is an integer type or a vector of integer types.
Value * getOperand(unsigned i) const
The Vector Function Database.
static SmallVector< VFInfo, 8 > getMappings(const CallInst &CI)
Retrieve all the VFInfo instances associated to the CallInst CI.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
const ParentTy * getParent() const
Helper class that determines VL can use the same opcode.
bool hasDefinedMainOpcode() const
unsigned getAltOpcode() const
bool hasDefinedAltOpcode() const
bool add(const Instruction *I)
bool hasCandidateOpcode(unsigned Opcode) const
Checks if the list of potential opcodes includes Opcode.
unsigned getMainOpcode() const
Helper class that determines whether a list of integer comparisons can share a single predicate.
static CmpInst::Predicate getSharedPredicate(ArrayRef< Value * > VL, const ICmpInst *Preferred)
Returns the predicate the whole list can share, or BAD_ICMP_PREDICATE when it cannot share a natively...
static Constant * getAdjustedConstant(const Instruction *I, CmpInst::Predicate Pred)
Returns the adjusted constant operand expressing the comparison lane I with the predicate Pred,...
CmpInst::Predicate getPredicate(const ICmpInst *Preferred) const
Returns the shared predicate, preferring the predicate of Preferred when the whole list can use it,...
static bool isBitTest(const Instruction *I)
Checks if the comparison lane I is the bit test of the single use and A, B != 0 or and A,...
bool add(const Instruction *I)
Intersects the convertible predicate set of the comparison lane I (an icmp or a trunc to i1) with the...
static bool canConvertTo(const Instruction *I, CmpInst::Predicate Pred)
Checks if the comparison lane I can be expressed with the predicate Pred by adjusting its constant op...
Main data required for vectorization of instructions.
Instruction * getMainOp() const
Instruction * getMatchingMainOpOrAltOp(Instruction *I) const
Checks if the instruction matches either the main or alternate opcode.
unsigned getAltOpcode() const
static InstructionsState invalid()
static bool isSameOperation(const Instruction *I, const Instruction *Op)
Checks if I is the same operation as Op, distinguishing calls by intrinsic ID (all calls share the Ca...
bool valid() const
Checks if the current state is valid, i.e. has non-null MainOp.
bool isExpandedBinOp(Value *V) const
Checks if the value V is a transformed instruction, compatible either with main or alternate ops.
bool isAddSubLikeOp() const
Checks if main/alt instructions are add/sub/fadd/fsub operations.
bool isExpandedOperand(Instruction *I, unsigned Idx) const
Checks if the operand at index Idx of instruction I is an expanded operand.
bool isCopyableElement(Value *V) const
Checks if the value is a copyable element.
bool isAltShuffle() const
Some of the instructions in the list have alternate opcodes.
Instruction * getAltOp() const
bool isNonSchedulable(Value *V) const
Checks if the value is non-schedulable.
bool isAddSubOrFNegLikeOp() const
Checks for an add/sub-like operation or an fneg, which models a flattened fadd reduction chain link: ...
bool isMulDivLikeOp() const
Checks if main/alt instructions are mul/div/rem/fmul/fdiv/frem operations.
unsigned getOpcode() const
The main/alternate opcodes for the list of instructions.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
OneUse_match< SubPat > m_OneUse(const SubPat &SP)
match_combine_or< Ty... > m_CombineOr(const Ty &...Ps)
Combine pattern matchers matching any of Ps patterns.
BinaryOp_match< LHS, RHS, Instruction::And > m_And(const LHS &L, const RHS &R)
ap_match< APInt > m_APInt(const APInt *&Res)
Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt.
bool match(Val *V, const Pattern &P)
cst_pred_ty< is_one > m_One()
Match an integer 1 or a vector with all elements equal to 1.
auto m_Value()
Match an arbitrary value and ignore it.
auto m_Intrinsic(const Ts &...Ops)
Match intrinsic calls like this: m_Intrinsic<Intrinsic::fabs>(m_Value(X))
BinaryOp_match< LHS, RHS, Instruction::Shl > m_Shl(const LHS &L, const RHS &R)
A private "module" namespace for types and utilities used by this pass.
static std::optional< std::pair< bool, APInt > > getCmpBoundaryFamily(CmpInst::Predicate Pred, const APInt &C)
If the comparison (Pred, X, C) is a single-element or single-complement range check,...
SmallVector< SmallVector< Value * > > scanAltAssociativeOperands(const InstructionsState &S, const TargetLibraryInfo &TLI, ArrayRef< Value * > VL, ArrayRef< Value * > Op0, ArrayRef< Value * > Op1, SmallVectorImpl< Value * > &ReassocScalars, SmallBitVector &SubLanes)
Peel the per-lane associative chains of an alternate node into operand columns.
std::pair< Instruction *, SmallVector< Value * > > convertTo(Instruction *I, const InstructionsState &S)
std::pair< Instruction *, Instruction * > getMainAltOpsNoStateVL(ArrayRef< Value * > VL)
Returns main/alternate instructions for the given VL.
bool isAlternateInstruction(Instruction *I, Instruction *MainOp, Instruction *AltOp, const TargetLibraryInfo &TLI)
Checks if the specified instruction I is an alternate operation for the given MainOp and AltOp instru...
static std::optional< std::pair< CmpInst::Predicate, APInt > > getLaneConstantCmp(const Instruction *I)
Returns the predicate and the compared constant of the comparison lane I, treating trunc X to i1 as a...
bool allSameOpcode(ArrayRef< Value * > VL)
bool isValidForAlternation(unsigned Opcode)
static bool areCompatibleCmpOps(Value *BaseOp0, Value *BaseOp1, Value *Op0, Value *Op1, const TargetLibraryInfo &TLI)
Checks if the provided operands of 2 cmp instructions are compatible, i.e.
static Instruction * findInstructionWithOpcode(ArrayRef< Value * > VL, unsigned Opcode)
Find an instruction with a specific opcode in VL.
bool hasOnlyAbsorbableCopyableFMulOrFAdds(ArrayRef< Value * > VL)
Checks if every copyable in VL is an absorbable fmul/fadd: the binops die instead of being computed a...
bool isCommutative(const Instruction *I, const Value *ValWithUses, bool IsCopyable)
bool checkEVsForVecCalls(ArrayRef< Value * > VL, const InstructionsState &S, const TargetLibraryInfo &TLI, SmallVectorImpl< unsigned > &Indices, SmallVectorImpl< Value * > &Calls)
Detects an extractvalue bundle that can be widened by vectorizing the underlying struct-returning cal...
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....
bool isFMAOrFMulAdd(const Instruction *I)
Checks if I is a call to llvm.fma or llvm.fmuladd.
InstructionsState getSameOpcode(ArrayRef< Value * > VL, const TargetLibraryInfo &TLI)
bool isAbsorbableCopyableFMulOrFAdd(const InstructionsState &S, Value *V)
Checks if V is a copyable single-use fmul/fadd, absorbable as fmuladd(a, b, -0.0) or fmuladd(1....
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.
bool isConstant(Value *V)
bool isAbsorbableFMulOrFAdd(ArrayRef< Value * > VL, Value *V)
Checks if V is a single-use fmul/fadd with operands outside VL.
static bool isCmpSameOrSwapped(const CmpInst *BaseCI, const CmpInst *CI, const TargetLibraryInfo &TLI)
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.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
auto map_to_vector(ContainerTy &&C, FuncTy &&F)
Map a range to a SmallVector with element types deduced from the mapping.
auto dyn_cast_if_present(const Y &Val)
dyn_cast_if_present<X> - Functionally identical to dyn_cast, except that a null (or none in the case ...
auto binary_search(R &&Range, T &&Value)
Provide wrappers to std::binary_search which take ranges instead of having to pass begin/end explicit...
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
auto make_isa_range(RangeT &&Range)
Return a range over Range containing only elements for which isa<T> holds, casting each of them to T.
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
iterator_range< filter_iterator< detail::IterOfRange< RangeT >, PredicateT > > make_filter_range(RangeT &&Range, PredicateT Pred)
Convenience function that takes a range of elements and a predicate, and return a new filter_iterator...
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
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...
iterator_range(Container &&) -> iterator_range< llvm::detail::IterOfRange< Container > >
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.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
LLVM_ABI bool isTriviallyVectorizable(Intrinsic::ID ID)
Identify if the intrinsic is trivially vectorizable.
constexpr detail::IsaCheckPredicate< Types... > IsaPred
Function object wrapper for the llvm::isa type check.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.