29#define DEBUG_TYPE "iv-descriptors"
33 for (
const Use &
Use :
I->operands())
34 if (!Set.count(dyn_cast<Instruction>(
Use)))
72 if (!Phi->hasOneUse())
75 const APInt *M =
nullptr;
76 Instruction *
I, *J = cast<Instruction>(Phi->use_begin()->getUser());
81 int32_t Bits = (*M + 1).exactLogBase2();
98 bool IsSigned =
false;
100 uint64_t MaxBitWidth =
DL.getTypeSizeInBits(Exit->getType());
108 auto Mask = DB->getDemandedBits(Exit);
109 MaxBitWidth = Mask.getBitWidth() - Mask.countl_zero();
112 if (MaxBitWidth ==
DL.getTypeSizeInBits(Exit->getType()) && AC && DT) {
117 auto NumTypeBits =
DL.getTypeSizeInBits(Exit->getType());
118 MaxBitWidth = NumTypeBits - NumSignBits;
120 if (!Bits.isNonNegative()) {
132 return std::make_pair(
Type::getIntNTy(Exit->getContext(), MaxBitWidth),
141 Type *RecurrenceType,
143 unsigned &MinWidthCastToRecurTy) {
148 MinWidthCastToRecurTy = -1U;
150 while (!Worklist.
empty()) {
153 if (
auto *Cast = dyn_cast<CastInst>(Val)) {
154 if (Cast->getSrcTy() == RecurrenceType) {
161 if (Cast->getDestTy() == RecurrenceType) {
166 MinWidthCastToRecurTy = std::min<unsigned>(
167 MinWidthCastToRecurTy, Cast->getSrcTy()->getScalarSizeInBits());
173 for (
Value *O : cast<User>(Val)->operands())
174 if (
auto *
I = dyn_cast<Instruction>(O))
196 if (Exit != ExactFPMathInst || Exit->hasNUsesOrMore(3))
201 auto *Op0 = Exit->getOperand(0);
202 auto *Op1 = Exit->getOperand(1);
208 LLVM_DEBUG(
dbgs() <<
"LV: Found an ordered reduction: Phi: " << *Phi
209 <<
", ExitInst: " << *Exit <<
"\n");
218 if (Phi->getNumIncomingValues() != 2)
222 if (Phi->getParent() != TheLoop->
getHeader())
241 bool FoundReduxOp =
false;
247 bool FoundStartPHI =
false;
252 unsigned NumCmpSelectPatternInst = 0;
256 Type *RecurrenceType = Phi->getType();
258 unsigned MinWidthCastToRecurrenceType;
260 bool IsSigned =
false;
277 Start =
lookThroughAnd(Phi, RecurrenceType, VisitedInsts, CastInsts);
284 VisitedInsts.
insert(Start);
313 while (!Worklist.
empty()) {
318 if (
auto *SI = dyn_cast<StoreInst>(Cur)) {
320 LLVM_DEBUG(
dbgs() <<
"Store instructions are not processed without "
321 <<
"Scalar Evolution Analysis\n");
325 const SCEV *PtrScev = SE->
getSCEV(SI->getPointerOperand());
328 const SCEV *OtherScev =
331 if (OtherScev != PtrScev) {
332 LLVM_DEBUG(
dbgs() <<
"Storing reduction value to different addresses "
333 <<
"inside the loop: " << *SI->getPointerOperand()
342 LLVM_DEBUG(
dbgs() <<
"Storing reduction value to non-uniform address "
343 <<
"inside the loop: " << *SI->getPointerOperand()
359 bool IsAPhi = isa<PHINode>(Cur);
362 if (Cur != Phi && IsAPhi && Cur->
getParent() == Phi->getParent())
367 if (!Cur->
isCommutative() && !IsAPhi && !isa<SelectInst>(Cur) &&
368 !isa<ICmpInst>(Cur) && !isa<FCmpInst>(Cur) &&
378 ExactFPMathInst = ExactFPMathInst ==
nullptr
386 if (
auto *Sel = dyn_cast<SelectInst>(ReduxDesc.
getPatternInst())) {
391 if (
auto *FCmp = dyn_cast<FCmpInst>(Sel->getCondition()))
392 CurFMF |= FCmp->getFastMathFlags();
403 bool IsASelect = isa<SelectInst>(Cur);
417 if (IsAPhi && Cur != Phi && !
areAllUsesIn(Cur, VisitedInsts))
421 (isa<ICmpInst>(Cur) || isa<SelectInst>(Cur)))
422 ++NumCmpSelectPatternInst;
424 (isa<FCmpInst>(Cur) || isa<SelectInst>(Cur)))
425 ++NumCmpSelectPatternInst;
428 FoundReduxOp |= !IsAPhi && Cur != Start;
449 if (ExitInstruction == Cur)
456 if (ExitInstruction !=
nullptr || Cur == Phi)
465 ExitInstruction = Cur;
472 InstDesc IgnoredVal(
false,
nullptr);
473 if (VisitedInsts.
insert(UI).second) {
474 if (isa<PHINode>(UI)) {
478 if (SI && SI->getPointerOperand() == Cur) {
485 }
else if (!isa<PHINode>(UI) &&
486 ((!isa<FCmpInst>(UI) && !isa<ICmpInst>(UI) &&
487 !isa<SelectInst>(UI)) ||
496 FoundStartPHI =
true;
506 NumCmpSelectPatternInst != 0)
524 if (ExitInstruction &&
526 LLVM_DEBUG(
dbgs() <<
"Last store Instruction of reduction value does not "
527 "store last calculated value of the reduction: "
534 if (!ExitInstruction)
538 if (!FoundStartPHI || !FoundReduxOp || !ExitInstruction)
541 const bool IsOrdered =
570 std::tie(ComputedType, IsSigned) =
572 if (ComputedType != RecurrenceType)
590 MinWidthCastToRecurrenceType);
600 FMF, ExactFPMathInst, RecurrenceType, IsSigned,
601 IsOrdered, CastInsts, MinWidthCastToRecurrenceType);
635 if (
auto *
Select = dyn_cast<SelectInst>(*
I->user_begin()))
644 Value *NonPhi =
nullptr;
646 if (OrigPhi == dyn_cast<PHINode>(SI->getTrueValue()))
647 NonPhi = SI->getFalseValue();
648 else if (OrigPhi == dyn_cast<PHINode>(SI->getFalseValue()))
649 NonPhi = SI->getTrueValue();
701 Value *NonRdxPhi =
nullptr;
708 auto IsIncreasingLoopInduction = [&](
Value *V) {
709 Type *Ty = V->getType();
713 auto *AR = dyn_cast<SCEVAddRecExpr>(SE.
getSCEV(V));
714 if (!AR || AR->getLoop() != TheLoop)
717 const SCEV *Step = AR->getStepRecurrence(SE);
733 LLVM_DEBUG(
dbgs() <<
"LV: FindLastIV valid range is " << ValidRange
734 <<
", and the signed range of " << *AR <<
" is "
738 return ValidRange.
contains(IVRange);
745 if (!IsIncreasingLoopInduction(NonRdxPhi))
755 assert((isa<CmpInst>(
I) || isa<SelectInst>(
I) || isa<CallInst>(
I)) &&
756 "Expected a cmp or select or call instruction");
764 if (
auto *
Select = dyn_cast<SelectInst>(*
I->user_begin()))
769 if (!isa<IntrinsicInst>(
I) &&
814 CmpInst *CI = dyn_cast<CmpInst>(SI->getCondition());
819 Value *TrueVal = SI->getTrueValue();
820 Value *FalseVal = SI->getFalseValue();
823 if ((isa<PHINode>(TrueVal) && isa<PHINode>(FalseVal)) ||
824 (!isa<PHINode>(TrueVal) && !isa<PHINode>(FalseVal)))
827 Instruction *I1 = isa<PHINode>(TrueVal) ? dyn_cast<Instruction>(FalseVal)
828 : dyn_cast<Instruction>(TrueVal);
829 if (!I1 || !I1->isBinaryOp())
842 Instruction *IPhi = isa<PHINode>(Op1) ? dyn_cast<Instruction>(Op1)
843 : dyn_cast<Instruction>(Op2);
844 if (!IPhi || IPhi != FalseVal)
854 switch (
I->getOpcode()) {
857 case Instruction::PHI:
859 case Instruction::Sub:
860 case Instruction::Add:
862 case Instruction::Mul:
864 case Instruction::And:
866 case Instruction::Or:
868 case Instruction::Xor:
870 case Instruction::FDiv:
871 case Instruction::FMul:
873 I->hasAllowReassoc() ?
nullptr :
I);
874 case Instruction::FSub:
875 case Instruction::FAdd:
877 I->hasAllowReassoc() ?
nullptr :
I);
878 case Instruction::Select:
885 case Instruction::FCmp:
886 case Instruction::ICmp:
887 case Instruction::Call:
890 auto HasRequiredFMF = [&]() {
893 if (isa<FPMathOperator>(
I) &&
I->hasNoNaNs() &&
I->hasNoSignedZeros())
905 I->hasAllowReassoc() ?
nullptr :
I);
912 unsigned MaxNumUses) {
913 unsigned NumUses = 0;
914 for (
const Use &U :
I->operands()) {
915 if (Insts.
count(dyn_cast<Instruction>(U)))
917 if (NumUses > MaxNumUses)
933 F.getFnAttribute(
"no-nans-fp-math").getValueAsBool());
935 F.getFnAttribute(
"no-signed-zeros-fp-math").getValueAsBool());
939 LLVM_DEBUG(
dbgs() <<
"Found an ADD reduction PHI." << *Phi <<
"\n");
944 LLVM_DEBUG(
dbgs() <<
"Found a MUL reduction PHI." << *Phi <<
"\n");
949 LLVM_DEBUG(
dbgs() <<
"Found an OR reduction PHI." << *Phi <<
"\n");
954 LLVM_DEBUG(
dbgs() <<
"Found an AND reduction PHI." << *Phi <<
"\n");
959 LLVM_DEBUG(
dbgs() <<
"Found a XOR reduction PHI." << *Phi <<
"\n");
964 LLVM_DEBUG(
dbgs() <<
"Found a SMAX reduction PHI." << *Phi <<
"\n");
969 LLVM_DEBUG(
dbgs() <<
"Found a SMIN reduction PHI." << *Phi <<
"\n");
974 LLVM_DEBUG(
dbgs() <<
"Found a UMAX reduction PHI." << *Phi <<
"\n");
979 LLVM_DEBUG(
dbgs() <<
"Found a UMIN reduction PHI." << *Phi <<
"\n");
984 LLVM_DEBUG(
dbgs() <<
"Found an integer conditional select reduction PHI."
994 <<
"FindLastIV reduction PHI." << *Phi <<
"\n");
999 LLVM_DEBUG(
dbgs() <<
"Found an FMult reduction PHI." << *Phi <<
"\n");
1004 LLVM_DEBUG(
dbgs() <<
"Found an FAdd reduction PHI." << *Phi <<
"\n");
1009 LLVM_DEBUG(
dbgs() <<
"Found a float MAX reduction PHI." << *Phi <<
"\n");
1014 LLVM_DEBUG(
dbgs() <<
"Found a float MIN reduction PHI." << *Phi <<
"\n");
1019 LLVM_DEBUG(
dbgs() <<
"Found a float conditional select reduction PHI."
1020 <<
" PHI." << *Phi <<
"\n");
1025 LLVM_DEBUG(
dbgs() <<
"Found an FMulAdd reduction PHI." << *Phi <<
"\n");
1030 LLVM_DEBUG(
dbgs() <<
"Found a float MAXIMUM reduction PHI." << *Phi <<
"\n");
1035 LLVM_DEBUG(
dbgs() <<
"Found a float MINIMUM reduction PHI." << *Phi <<
"\n");
1046 if (Phi->getParent() != TheLoop->
getHeader() ||
1047 Phi->getNumIncomingValues() != 2)
1054 if (!Preheader || !Latch)
1058 if (Phi->getBasicBlockIndex(Preheader) < 0 ||
1059 Phi->getBasicBlockIndex(Latch) < 0)
1064 auto *Previous = dyn_cast<Instruction>(Phi->getIncomingValueForBlock(Latch));
1071 while (
auto *PrevPhi = dyn_cast_or_null<PHINode>(Previous)) {
1072 if (PrevPhi->getParent() != Phi->getParent())
1074 if (!SeenPhis.
insert(PrevPhi).second)
1076 Previous = dyn_cast<Instruction>(PrevPhi->getIncomingValueForBlock(Latch));
1079 if (!Previous || !TheLoop->
contains(Previous) || isa<PHINode>(Previous))
1091 auto TryToPushSinkCandidate = [&](
Instruction *SinkCandidate) {
1093 if (Previous == SinkCandidate)
1096 if (!Seen.
insert(SinkCandidate).second)
1102 if (SinkCandidate->getParent() != PhiBB ||
1103 SinkCandidate->mayHaveSideEffects() ||
1104 SinkCandidate->mayReadFromMemory() || SinkCandidate->isTerminator())
1109 if (isa<PHINode>(SinkCandidate))
1119 while (!WorkList.
empty()) {
1122 if (!TryToPushSinkCandidate(cast<Instruction>(
User)))
1133 return Instruction::Add;
1135 return Instruction::Mul;
1137 return Instruction::Or;
1139 return Instruction::And;
1141 return Instruction::Xor;
1143 return Instruction::FMul;
1146 return Instruction::FAdd;
1153 return Instruction::ICmp;
1160 return Instruction::FCmp;
1186 unsigned ExpectedUses = 1;
1187 if (RedOp == Instruction::ICmp || RedOp == Instruction::FCmp)
1193 if (isa<PHINode>(UI))
1195 if (RedOp == Instruction::ICmp || RedOp == Instruction::FCmp) {
1198 if (isa<SelectInst>(UI))
1207 if (RedOp == Instruction::ICmp || RedOp == Instruction::FCmp) {
1216 return Cur->getOpcode() == RedOp;
1220 unsigned ExtraPhiUses = 0;
1222 if (
auto ExitPhi = dyn_cast<PHINode>(LoopExitInstr)) {
1223 if (ExitPhi->getNumIncomingValues() != 2)
1226 Instruction *Inc0 = dyn_cast<Instruction>(ExitPhi->getIncomingValue(0));
1227 Instruction *Inc1 = dyn_cast<Instruction>(ExitPhi->getIncomingValue(1));
1232 else if (Inc1 == Phi)
1245 if (!isCorrectOpcode(RdxInstr) || !LoopExitInstr->
hasNUses(2))
1250 if (!Phi->hasNUses(ExpectedUses + ExtraPhiUses))
1257 while (Cur != RdxInstr) {
1258 if (!Cur || !isCorrectOpcode(Cur) || !Cur->
hasNUses(ExpectedUses))
1262 Cur = getNextInstruction(Cur);
1266 return ReductionOperations;
1272 : StartValue(Start), IK(K), Step(Step), InductionBinOp(BOp) {
1273 assert(IK != IK_NoInduction &&
"Not an induction");
1277 assert(StartValue &&
"StartValue is null");
1279 "StartValue is not a pointer for pointer induction");
1281 "StartValue is not an integer for integer induction");
1284 assert((!getConstIntStepValue() || !getConstIntStepValue()->
isZero()) &&
1285 "Step value is zero");
1288 "StepValue is not an integer");
1291 "StepValue is not FP for FpInduction");
1292 assert((IK != IK_FpInduction ||
1294 (InductionBinOp->getOpcode() == Instruction::FAdd ||
1295 InductionBinOp->getOpcode() == Instruction::FSub))) &&
1296 "Binary opcode should be specified for FP induction");
1299 for (
auto &Inst : *Casts) {
1300 RedundantCasts.push_back(Inst);
1306 if (isa<SCEVConstant>(Step))
1307 return dyn_cast<ConstantInt>(cast<SCEVConstant>(Step)->getValue());
1316 assert(Phi->getType()->isFloatingPointTy() &&
"Unexpected Phi type");
1318 if (TheLoop->
getHeader() != Phi->getParent())
1323 if (Phi->getNumIncomingValues() != 2)
1325 Value *BEValue =
nullptr, *StartValue =
nullptr;
1326 if (TheLoop->
contains(Phi->getIncomingBlock(0))) {
1327 BEValue = Phi->getIncomingValue(0);
1328 StartValue = Phi->getIncomingValue(1);
1331 "Unexpected Phi node in the loop");
1332 BEValue = Phi->getIncomingValue(1);
1333 StartValue = Phi->getIncomingValue(0);
1340 Value *Addend =
nullptr;
1341 if (BOp->
getOpcode() == Instruction::FAdd) {
1346 }
else if (BOp->
getOpcode() == Instruction::FSub)
1354 if (
auto *
I = dyn_cast<Instruction>(Addend))
1401 assert(CastInsts.
empty() &&
"CastInsts is expected to be empty.");
1402 auto *PN = cast<PHINode>(PhiScev->
getValue());
1403 assert(PSE.
getSCEV(PN) == AR &&
"Unexpected phi node SCEV expression");
1414 auto getDef = [&](
const Value *Val) ->
Value * {
1420 Value *Def =
nullptr;
1421 if (L->isLoopInvariant(Op0))
1423 else if (L->isLoopInvariant(Op1))
1433 Value *Val = PN->getIncomingValueForBlock(Latch);
1441 bool InCastSequence =
false;
1442 auto *Inst = dyn_cast<Instruction>(Val);
1446 if (!Inst || !L->contains(Inst)) {
1449 auto *AddRec = dyn_cast<SCEVAddRecExpr>(PSE.
getSCEV(Val));
1451 InCastSequence =
true;
1452 if (InCastSequence) {
1455 if (!CastInsts.
empty())
1456 if (!Inst->hasOneUse())
1463 Inst = dyn_cast<Instruction>(Val);
1466 return InCastSequence;
1472 Type *PhiTy = Phi->getType();
1486 const auto *AR = dyn_cast<SCEVAddRecExpr>(PhiScev);
1498 const auto *SymbolicPhi = dyn_cast<SCEVUnknown>(PhiScev);
1504 if (PhiScev != AR && SymbolicPhi) {
1517 Type *PhiTy = Phi->getType();
1523 const SCEV *PhiScev = Expr ? Expr : SE->
getSCEV(Phi);
1531 if (AR->
getLoop() != TheLoop) {
1535 dbgs() <<
"LV: PHI is a recurrence with respect to an outer loop.\n");
1543 &&
"Invalid Phi node, not present in loop header");
1555 const SCEVConstant *ConstStep = dyn_cast<SCEVConstant>(Step);
1561 dyn_cast<BinaryOperator>(Phi->getIncomingValueForBlock(Latch));
AMDGPU Register Bank Select
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static bool getCastsForInductionPHI(PredicatedScalarEvolution &PSE, const SCEVUnknown *PhiScev, const SCEVAddRecExpr *AR, SmallVectorImpl< Instruction * > &CastInsts)
This function is called when we suspect that the update-chain of a phi node (whose symbolic SCEV expr...
static void collectCastInstrs(Loop *TheLoop, Instruction *Exit, Type *RecurrenceType, SmallPtrSetImpl< Instruction * > &Casts, unsigned &MinWidthCastToRecurTy)
Collect cast instructions that can be ignored in the vectorizer's cost model, given a reduction exit ...
static bool checkOrderedReduction(RecurKind Kind, Instruction *ExactFPMathInst, Instruction *Exit, PHINode *Phi)
static Instruction * lookThroughAnd(PHINode *Phi, Type *&RT, SmallPtrSetImpl< Instruction * > &Visited, SmallPtrSetImpl< Instruction * > &CI)
Determines if Phi may have been type-promoted.
static std::pair< Type *, bool > computeRecurrenceType(Instruction *Exit, DemandedBits *DB, AssumptionCache *AC, DominatorTree *DT)
Compute the minimal bit width needed to represent a reduction whose exit instruction is given by Exit...
static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT, AssumptionCache *AC)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Class for arbitrary precision integers.
static APInt getSignedMinValue(unsigned numBits)
Gets minimum signed value of APInt for a specific bit width.
A cache of @llvm.assume calls within a function.
LLVM Basic Block Representation.
BinaryOps getOpcode() const
This class is the base class for the comparison instructions.
An abstraction over a floating-point predicate, and a pack of an integer predicate with samesign info...
This is the shared class of boolean and integer constants.
This class represents a range of values.
bool contains(const APInt &Val) const
Return true if the specified value is in the set.
static ConstantRange getNonEmpty(APInt Lower, APInt Upper)
Create non-empty constant range with the given bounds.
A parsed version of the target data layout string in and methods for querying it.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
Convenience struct for specifying and reasoning about fast-math flags.
bool noSignedZeros() const
void setNoSignedZeros(bool B=true)
void setNoNaNs(bool B=true)
static FastMathFlags getFast()
A struct for saving information about induction variables.
@ IK_FpInduction
Floating point induction variable.
@ IK_PtrInduction
Pointer induction var. Step = C.
@ IK_IntInduction
Integer induction variable. Step = C.
static bool isInductionPHI(PHINode *Phi, const Loop *L, ScalarEvolution *SE, InductionDescriptor &D, const SCEV *Expr=nullptr, SmallVectorImpl< Instruction * > *CastsToIgnore=nullptr)
Returns true if Phi is an induction in the loop L.
static bool isFPInductionPHI(PHINode *Phi, const Loop *L, ScalarEvolution *SE, InductionDescriptor &D)
Returns true if Phi is a floating point induction in the loop L.
InductionDescriptor()=default
Default constructor - creates an invalid induction.
ConstantInt * getConstIntStepValue() const
bool isCommutative() const LLVM_READONLY
Return true if the instruction is commutative:
FastMathFlags getFastMathFlags() const LLVM_READONLY
Convenience function for getting all the fast-math flags, which must be an operator which supports th...
static IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
bool contains(const LoopT *L) const
Return true if the specified loop is contained within in this loop.
BlockT * getLoopLatch() const
If there is a single latch block for this loop, return it.
BlockT * getHeader() const
BlockT * getLoopPreheader() const
If there is a preheader for this loop, return it.
Represents a single loop in the control flow graph.
bool isLoopInvariant(const Value *V) const
Return true if the specified value is loop invariant.
An interface layer with SCEV used to manage how we see SCEV expressions for values in the context of ...
ScalarEvolution * getSE() const
Returns the ScalarEvolution analysis used.
bool areAddRecsEqualWithPreds(const SCEVAddRecExpr *AR1, const SCEVAddRecExpr *AR2) const
Check if AR1 and AR2 are equal, while taking into account Equal predicates in Preds.
const SCEVAddRecExpr * getAsAddRec(Value *V)
Attempts to produce an AddRecExpr for V by adding additional SCEV predicates.
const SCEV * getSCEV(Value *V)
Returns the SCEV expression of V, in the context of the current SCEV predicate.
This POD struct holds information about a potential recurrence operation.
RecurKind getRecKind() const
Instruction * getPatternInst() const
bool isRecurrence() const
Instruction * getExactFPMathInst() const
The RecurrenceDescriptor is used to identify recurrences variables in a loop.
static bool isFPMinMaxRecurrenceKind(RecurKind Kind)
Returns true if the recurrence kind is a floating-point min/max kind.
static bool isFMulAddIntrinsic(Instruction *I)
Returns true if the instruction is a call to the llvm.fmuladd intrinsic.
static bool isFixedOrderRecurrence(PHINode *Phi, Loop *TheLoop, DominatorTree *DT)
Returns true if Phi is a fixed-order recurrence.
unsigned getOpcode() const
static bool hasMultipleUsesOf(Instruction *I, SmallPtrSetImpl< Instruction * > &Insts, unsigned MaxNumUses)
Returns true if instruction I has multiple uses in Insts.
static bool isReductionPHI(PHINode *Phi, Loop *TheLoop, RecurrenceDescriptor &RedDes, DemandedBits *DB=nullptr, AssumptionCache *AC=nullptr, DominatorTree *DT=nullptr, ScalarEvolution *SE=nullptr)
Returns true if Phi is a reduction in TheLoop.
static bool areAllUsesIn(Instruction *I, SmallPtrSetImpl< Instruction * > &Set)
Returns true if all uses of the instruction I is within the Set.
SmallVector< Instruction *, 4 > getReductionOpChain(PHINode *Phi, Loop *L) const
Attempts to find a chain of operations from Phi to LoopExitInst that can be treated as a set of reduc...
static bool isAnyOfRecurrenceKind(RecurKind Kind)
Returns true if the recurrence kind is of the form select(cmp(),x,y) where one of (x,...
static InstDesc isFindLastIVPattern(Loop *TheLoop, PHINode *OrigPhi, Instruction *I, ScalarEvolution &SE)
Returns a struct describing whether the instruction is either a Select(ICmp(A, B),...
static InstDesc isAnyOfPattern(Loop *Loop, PHINode *OrigPhi, Instruction *I, InstDesc &Prev)
Returns a struct describing whether the instruction is either a Select(ICmp(A, B),...
static bool isFindLastIVRecurrenceKind(RecurKind Kind)
Returns true if the recurrence kind is of the form select(cmp(),x,y) where one of (x,...
static InstDesc isConditionalRdxPattern(RecurKind Kind, Instruction *I)
Returns a struct describing if the instruction is a Select(FCmp(X, Y), (Z = X op PHINode),...
RecurKind getRecurrenceKind() const
StoreInst * IntermediateStore
Reductions may store temporary or final result to an invariant address.
static InstDesc isRecurrenceInstr(Loop *L, PHINode *Phi, Instruction *I, RecurKind Kind, InstDesc &Prev, FastMathFlags FuncFMF, ScalarEvolution *SE)
Returns a struct describing if the instruction 'I' can be a recurrence variable of type 'Kind' for a ...
static bool isFloatingPointRecurrenceKind(RecurKind Kind)
Returns true if the recurrence kind is a floating point kind.
static InstDesc isMinMaxPattern(Instruction *I, RecurKind Kind, const InstDesc &Prev)
Returns a struct describing if the instruction is a llvm.
static bool AddReductionVar(PHINode *Phi, RecurKind Kind, Loop *TheLoop, FastMathFlags FuncFMF, RecurrenceDescriptor &RedDes, DemandedBits *DB=nullptr, AssumptionCache *AC=nullptr, DominatorTree *DT=nullptr, ScalarEvolution *SE=nullptr)
Returns true if Phi is a reduction of type Kind and adds it to the RecurrenceDescriptor.
static bool isIntegerRecurrenceKind(RecurKind Kind)
Returns true if the recurrence kind is an integer kind.
static bool isIntMinMaxRecurrenceKind(RecurKind Kind)
Returns true if the recurrence kind is an integer min/max kind.
static bool isMinMaxRecurrenceKind(RecurKind Kind)
Returns true if the recurrence kind is any min/max kind.
This node represents a polynomial recurrence on the trip count of the specified loop.
const SCEV * getStepRecurrence(ScalarEvolution &SE) const
Constructs and returns the recurrence indicating how much this expression steps by.
const Loop * getLoop() const
This class represents a constant integer value.
This means that we are dealing with an entirely unknown SCEV value, and only represent it as its LLVM...
This class represents an analyzed expression in the program.
Type * getType() const
Return the LLVM type of this SCEV expression.
The main scalar evolution driver.
const SCEV * getSCEV(Value *V)
Return a SCEV expression for the full generality of the specified expression.
ConstantRange getSignedRange(const SCEV *S)
Determine the signed range for a particular SCEV.
bool isLoopInvariant(const SCEV *S, const Loop *L)
Return true if the value of the given SCEV is unchanging in the specified loop.
bool isKnownPositive(const SCEV *S)
Test if the given expression is known to be positive.
bool isSCEVable(Type *Ty) const
Test if values of the given type are analyzable within the SCEV framework.
const SCEV * getUnknown(Value *V)
This class represents the LLVM 'select' instruction.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An instruction for storing to memory.
Value * getValueOperand()
Value * getPointerOperand()
The instances of the Type class are immutable: once they are created, they are never changed.
unsigned getIntegerBitWidth() const
bool isPointerTy() const
True if this is an instance of PointerType.
bool isFloatTy() const
Return true if this is 'float', a 32-bit IEEE fp type.
static IntegerType * getIntNTy(LLVMContext &C, unsigned N)
bool isHalfTy() const
Return true if this is 'half', a 16-bit IEEE fp type.
bool isDoubleTy() const
Return true if this is 'double', a 64-bit IEEE fp type.
bool isFloatingPointTy() const
Return true if this is one of the floating-point types.
bool isIntegerTy() const
True if this is an instance of IntegerType.
A Use represents the edge between a Value definition and its users.
Value * getOperand(unsigned i) const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
bool hasOneUse() const
Return true if there is exactly one use of this value.
iterator_range< user_iterator > users()
bool hasNUses(unsigned N) const
Return true if this Value has exactly N uses.
const ParentTy * getParent() const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
BinaryOp_match< LHS, RHS, Instruction::And > m_And(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::Add > m_Add(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::FSub > m_FSub(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::FMul > m_FMul(const LHS &L, const RHS &R)
bool match(Val *V, const Pattern &P)
bind_ty< Instruction > m_Instruction(Instruction *&I)
Match an instruction, capturing it if we match.
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
ThreeOps_match< Cond, LHS, RHS, Instruction::Select > m_Select(const Cond &C, const LHS &L, const RHS &R)
Matches SelectInst.
match_combine_or< MaxMin_match< FCmpInst, LHS, RHS, ofmin_pred_ty >, MaxMin_match< FCmpInst, LHS, RHS, ufmin_pred_ty > > m_OrdOrUnordFMin(const LHS &L, const RHS &R)
Match an 'ordered' or 'unordered' floating point minimum function.
MaxMin_match< ICmpInst, LHS, RHS, smin_pred_ty > m_SMin(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::FAdd > m_FAdd(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::Mul > m_Mul(const LHS &L, const RHS &R)
OneUse_match< T > m_OneUse(const T &SubPattern)
MaxMin_match< ICmpInst, LHS, RHS, umax_pred_ty > m_UMax(const LHS &L, const RHS &R)
class_match< CmpInst > m_Cmp()
Matches any compare instruction and ignore it.
match_combine_or< MaxMin_match< FCmpInst, LHS, RHS, ofmax_pred_ty >, MaxMin_match< FCmpInst, LHS, RHS, ufmax_pred_ty > > m_OrdOrUnordFMax(const LHS &L, const RHS &R)
Match an 'ordered' or 'unordered' floating point maximum function.
MaxMin_match< ICmpInst, LHS, RHS, smax_pred_ty > m_SMax(const LHS &L, const RHS &R)
apint_match m_APInt(const APInt *&Res)
Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt.
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
BinaryOp_match< LHS, RHS, Instruction::Sub > m_Sub(const LHS &L, const RHS &R)
MaxMin_match< ICmpInst, LHS, RHS, umin_pred_ty > m_UMin(const LHS &L, const RHS &R)
match_combine_or< LTy, RTy > m_CombineOr(const LTy &L, const RTy &R)
Combine two pattern matchers matching L || R.
This is an optimization pass for GlobalISel generic memory operations.
T bit_ceil(T Value)
Returns the smallest integral power of two no smaller than Value if Value is nonzero.
SelectPatternResult matchSelectPattern(Value *V, Value *&LHS, Value *&RHS, Instruction::CastOps *CastOp=nullptr, unsigned Depth=0)
Pattern match integer [SU]MIN, [SU]MAX and ABS idioms, returning the kind and providing the out param...
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
RecurKind
These are the kinds of recurrences that we support.
@ UMin
Unsigned integer min implemented in terms of select(cmp()).
@ IFindLastIV
FindLast reduction with select(icmp(),x,y) where one of (x,y) is increasing loop induction,...
@ FAnyOf
Any_of reduction with select(fcmp(),x,y) where one of (x,y) is loop invariant, and both x and y are i...
@ Or
Bitwise or logical OR of integers.
@ FMinimum
FP min with llvm.minimum semantics.
@ Mul
Product of integers.
@ Xor
Bitwise or logical XOR of integers.
@ FMax
FP max implemented in terms of select(cmp()).
@ FMaximum
FP max with llvm.maximum semantics.
@ FMulAdd
Sum of float products with llvm.fmuladd(a * b + sum).
@ SMax
Signed integer max implemented in terms of select(cmp()).
@ And
Bitwise or logical AND of integers.
@ FFindLastIV
FindLast reduction with select(fcmp(),x,y) where one of (x,y) is increasing loop induction,...
@ SMin
Signed integer min implemented in terms of select(cmp()).
@ FMin
FP min implemented in terms of select(cmp()).
@ IAnyOf
Any_of reduction with select(icmp(),x,y) where one of (x,y) is loop invariant, and both x and y are i...
@ UMax
Unsigned integer max implemented in terms of select(cmp()).
void computeKnownBits(const Value *V, KnownBits &Known, const DataLayout &DL, unsigned Depth=0, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true)
Determine which bits of V are known to be either zero or one and return them in the KnownZero/KnownOn...
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
unsigned ComputeNumSignBits(const Value *Op, const DataLayout &DL, unsigned Depth=0, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true)
Return the number of times the sign bit of the register is replicated into the other bits.
static bool isMinOrMax(SelectPatternFlavor SPF)
When implementing this min/max pattern as fcmp; select, does the fcmp have to be ordered?