diff options
Diffstat (limited to 'llvm/lib/Transforms/Utils/LoopUtils.cpp')
-rw-r--r-- | llvm/lib/Transforms/Utils/LoopUtils.cpp | 78 |
1 files changed, 71 insertions, 7 deletions
diff --git a/llvm/lib/Transforms/Utils/LoopUtils.cpp b/llvm/lib/Transforms/Utils/LoopUtils.cpp index 7df8651ede15..7d6662c44f07 100644 --- a/llvm/lib/Transforms/Utils/LoopUtils.cpp +++ b/llvm/lib/Transforms/Utils/LoopUtils.cpp @@ -466,6 +466,19 @@ llvm::collectChildrenInLoop(DomTreeNode *N, const Loop *CurLoop) { return Worklist; } +bool llvm::isAlmostDeadIV(PHINode *PN, BasicBlock *LatchBlock, Value *Cond) { + int LatchIdx = PN->getBasicBlockIndex(LatchBlock); + Value *IncV = PN->getIncomingValue(LatchIdx); + + for (User *U : PN->users()) + if (U != Cond && U != IncV) return false; + + for (User *U : IncV->users()) + if (U != Cond && U != PN) return false; + return true; +} + + void llvm::deleteDeadLoop(Loop *L, DominatorTree *DT, ScalarEvolution *SE, LoopInfo *LI, MemorySSA *MSSA) { assert((!DT || L->isLCSSAForm(*DT)) && "Expected LCSSA!"); @@ -628,18 +641,17 @@ void llvm::deleteDeadLoop(Loop *L, DominatorTree *DT, ScalarEvolution *SE, } // After the loop has been deleted all the values defined and modified - // inside the loop are going to be unavailable. - // Since debug values in the loop have been deleted, inserting an undef - // dbg.value truncates the range of any dbg.value before the loop where the - // loop used to be. This is particularly important for constant values. + // inside the loop are going to be unavailable. Values computed in the + // loop will have been deleted, automatically causing their debug uses + // be be replaced with undef. Loop invariant values will still be available. + // Move dbg.values out the loop so that earlier location ranges are still + // terminated and loop invariant assignments are preserved. Instruction *InsertDbgValueBefore = ExitBlock->getFirstNonPHI(); assert(InsertDbgValueBefore && "There should be a non-PHI instruction in exit block, else these " "instructions will have no parent."); - for (auto *DVI : DeadDebugInst) { - DVI->setKillLocation(); + for (auto *DVI : DeadDebugInst) DVI->moveBefore(InsertDbgValueBefore); - } } // Remove the block from the reference counting scheme, so that we can @@ -880,6 +892,29 @@ bool llvm::hasIterationCountInvariantInParent(Loop *InnerLoop, return true; } +Intrinsic::ID llvm::getMinMaxReductionIntrinsicOp(RecurKind RK) { + switch (RK) { + default: + llvm_unreachable("Unknown min/max recurrence kind"); + case RecurKind::UMin: + return Intrinsic::umin; + case RecurKind::UMax: + return Intrinsic::umax; + case RecurKind::SMin: + return Intrinsic::smin; + case RecurKind::SMax: + return Intrinsic::smax; + case RecurKind::FMin: + return Intrinsic::minnum; + case RecurKind::FMax: + return Intrinsic::maxnum; + case RecurKind::FMinimum: + return Intrinsic::minimum; + case RecurKind::FMaximum: + return Intrinsic::maximum; + } +} + CmpInst::Predicate llvm::getMinMaxReductionPredicate(RecurKind RK) { switch (RK) { default: @@ -896,6 +931,9 @@ CmpInst::Predicate llvm::getMinMaxReductionPredicate(RecurKind RK) { return CmpInst::FCMP_OLT; case RecurKind::FMax: return CmpInst::FCMP_OGT; + // We do not add FMinimum/FMaximum recurrence kind here since there is no + // equivalent predicate which compares signed zeroes according to the + // semantics of the intrinsics (llvm.minimum/maximum). } } @@ -910,6 +948,14 @@ Value *llvm::createSelectCmpOp(IRBuilderBase &Builder, Value *StartVal, Value *llvm::createMinMaxOp(IRBuilderBase &Builder, RecurKind RK, Value *Left, Value *Right) { + Type *Ty = Left->getType(); + if (Ty->isIntOrIntVectorTy() || + (RK == RecurKind::FMinimum || RK == RecurKind::FMaximum)) { + // TODO: Add float minnum/maxnum support when FMF nnan is set. + Intrinsic::ID Id = getMinMaxReductionIntrinsicOp(RK); + return Builder.CreateIntrinsic(Ty, Id, {Left, Right}, nullptr, + "rdx.minmax"); + } CmpInst::Predicate Pred = getMinMaxReductionPredicate(RK); Value *Cmp = Builder.CreateCmp(Pred, Left, Right, "rdx.minmax.cmp"); Value *Select = Builder.CreateSelect(Cmp, Left, Right, "rdx.minmax.select"); @@ -1055,6 +1101,10 @@ Value *llvm::createSimpleTargetReduction(IRBuilderBase &Builder, return Builder.CreateFPMaxReduce(Src); case RecurKind::FMin: return Builder.CreateFPMinReduce(Src); + case RecurKind::FMinimum: + return Builder.CreateFPMinimumReduce(Src); + case RecurKind::FMaximum: + return Builder.CreateFPMaximumReduce(Src); default: llvm_unreachable("Unhandled opcode"); } @@ -1123,6 +1173,20 @@ bool llvm::isKnownNonNegativeInLoop(const SCEV *S, const Loop *L, SE.isLoopEntryGuardedByCond(L, ICmpInst::ICMP_SGE, S, Zero); } +bool llvm::isKnownPositiveInLoop(const SCEV *S, const Loop *L, + ScalarEvolution &SE) { + const SCEV *Zero = SE.getZero(S->getType()); + return SE.isAvailableAtLoopEntry(S, L) && + SE.isLoopEntryGuardedByCond(L, ICmpInst::ICMP_SGT, S, Zero); +} + +bool llvm::isKnownNonPositiveInLoop(const SCEV *S, const Loop *L, + ScalarEvolution &SE) { + const SCEV *Zero = SE.getZero(S->getType()); + return SE.isAvailableAtLoopEntry(S, L) && + SE.isLoopEntryGuardedByCond(L, ICmpInst::ICMP_SLE, S, Zero); +} + bool llvm::cannotBeMinInLoop(const SCEV *S, const Loop *L, ScalarEvolution &SE, bool Signed) { unsigned BitWidth = cast<IntegerType>(S->getType())->getBitWidth(); |