llvm.org GIT mirror llvm / b8354dd
[ScalarEvolution] Handling for ICmp occuring in the evolution chain. Summary: If a compare instruction is same or inverse of the compare in the branch of the loop latch, then return a constant evolution node. Currently scope of evaluation is limited to SCEV computation for PHI nodes. This shall facilitate computations of loop exit counts in cases where compare appears in the evolution chain of induction variables. Will fix PR 34538 Reviewers: sanjoy, hfinkel, junryoungju Reviewed By: junryoungju Subscribers: javed.absar, llvm-commits Differential Revision: https://reviews.llvm.org/D38494 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@316054 91177308-0d34-0410-b5e6-96231b3b80d8 Jatin Bhateja 2 years ago
4 changed file(s) with 69 addition(s) and 5 deletion(s). Raw diff Collapse all Expand all
13771377 /// Helper function called from createNodeForPHI.
13781378 const SCEV *createAddRecFromPHI(PHINode *PN);
13791379
1380 /// Evaluate ICmpInst to a constant node for special patterns.
1381 const SCEV *evaluateForICmp(ICmpInst *IC);
1382
13801383 /// A helper function for createAddRecFromPHI to handle simple cases.
13811384 const SCEV *createSimpleAffineAddRec(PHINode *PN, Value *BEValueV,
13821385 Value *StartValueV);
47554755 Ops.push_back(Add->getOperand(i));
47564756 const SCEV *Accum = getAddExpr(Ops);
47574757
4758 bool InvariantF = isLoopInvariant(Accum, L);
4759
4760 if (!InvariantF && Accum->getSCEVType() == scZeroExtend) {
4761 const SCEV *Op = dyn_cast(Accum)->getOperand();
4762 const SCEVUnknown *Un = dyn_cast(Op);
4763 if (Un && Un->getValue() && isa(Un->getValue()) &&
4764 dyn_cast(Un->getValue())->getOpcode() ==
4765 Instruction::ICmp) {
4766 const SCEV *ICmpSC = evaluateForICmp(cast(Un->getValue()));
4767 bool IsConstSC = ICmpSC->getSCEVType() == scConstant;
4768 Accum =
4769 IsConstSC ? getZeroExtendExpr(ICmpSC, Accum->getType()) : Accum;
4770 InvariantF = IsConstSC ? true : false;
4771 }
4772 }
4773
47584774 // This is not a valid addrec if the step amount is varying each
47594775 // loop iteration, but is not itself an addrec in this loop.
4760 if (isLoopInvariant(Accum, L) ||
4761 (isa(Accum) &&
4762 cast(Accum)->getLoop() == L)) {
4776 if (InvariantF || (isa(Accum) &&
4777 cast(Accum)->getLoop() == L)) {
47634778 SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap;
47644779
47654780 if (auto BO = MatchBinaryOp(BEValueV, DT)) {
64416456 LoopWorklist.append(CurrL->begin(), CurrL->end());
64426457 }
64436458 }
6459
6460
6461 const SCEV *ScalarEvolution::evaluateForICmp(ICmpInst *IC) {
6462 BasicBlock *Latch = nullptr;
6463 const Loop *L = LI.getLoopFor(IC->getParent());
6464
6465 // If compare instruction is same or inverse of the compare in the
6466 // branch of the loop latch, then return a constant evolution
6467 // node. This shall facilitate computations of loop exit counts
6468 // in cases where compare appears in the evolution chain of induction
6469 // variables.
6470 if (L && (Latch = L->getLoopLatch())) {
6471 BranchInst *BI = dyn_cast(Latch->getTerminator());
6472 if (BI && BI->isConditional() && BI->getCondition() == IC) {
6473 if (BI->getSuccessor(0) != L->getHeader())
6474 return getZero(Type::getInt1Ty(getContext()));
6475 else
6476 return getOne(Type::getInt1Ty(getContext()));
6477 }
6478 }
6479
6480 return getUnknown(IC);
6481 }
6482
64446483
64456484 void ScalarEvolution::forgetValue(Value *V) {
64466485 Instruction *I = dyn_cast(V);
29722972 // Ignore users that are part of a SCEV expression. This way we only
29732973 // consider leaf IV Users. This effectively rediscovers a portion of
29742974 // IVUsers analysis but in program order this time.
2975 if (SE.isSCEVable(I.getType()) && !isa(SE.getSCEV(&I)))
2976 continue;
2975 if (SE.isSCEVable(I.getType())) {
2976 const SCEV *SI = SE.getSCEV(&I);
2977 if (!isa(SI) && !isa(SI))
2978 continue;
2979 }
29772980
29782981 // Remove this instruction from any NearUsers set it may be in.
29792982 for (unsigned ChainIdx = 0, NChains = IVChainVec.size();
0 ; RUN: opt -S -scalar-evolution -loop-deletion -simplifycfg -analyze < %s | FileCheck %s --check-prefix=CHECK-ANALYSIS
1
2 define i32 @foo() local_unnamed_addr #0 {
3 ; CHECK-ANALYSIS: Loop %do.body: backedge-taken count is 10000
4 ; CHECK-ANALYSIS: Loop %do.body: max backedge-taken count is 10000
5 ; CHECK-ANALYSIS: Loop %do.body: Predicated backedge-taken count is 10000
6 entry:
7 br label %do.body
8
9 do.body: ; preds = %do.body, %entry
10 %start.0 = phi i32 [ 0, %entry ], [ %inc.start.0, %do.body ]
11 %cmp = icmp slt i32 %start.0, 10000
12 %inc = zext i1 %cmp to i32
13 %inc.start.0 = add nsw i32 %start.0, %inc
14 br i1 %cmp, label %do.body, label %do.end
15
16 do.end: ; preds = %do.body
17 ret i32 0
18 }