llvm.org GIT mirror llvm / 5afa924
[SCEV] 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. 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: sanjoy, junryoungju Subscribers: javed.absar, llvm-commits Differential Revision: https://reviews.llvm.org/D38494 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@318050 91177308-0d34-0410-b5e6-96231b3b80d8 Jatin Bhateja 2 years ago
3 changed file(s) with 127 addition(s) and 8 deletion(s). Raw diff Collapse all Expand all
40794079 bool Valid = true;
40804080 };
40814081
4082 /// This class evaluates the compare condition by matching it against the
4083 /// condition of loop latch. If there is a match we assume a true value
4084 /// for the condition while building SCEV nodes.
4085 class SCEVBackedgeConditionFolder
4086 : public SCEVRewriteVisitor {
4087 public:
4088 static const SCEV *rewrite(const SCEV *S, const Loop *L,
4089 ScalarEvolution &SE) {
4090 bool IsPosBECond;
4091 Value *BECond = nullptr;
4092 if (BasicBlock *Latch = L->getLoopLatch()) {
4093 BranchInst *BI = dyn_cast(Latch->getTerminator());
4094 if (BI && BI->isConditional() &&
4095 BI->getSuccessor(0) != BI->getSuccessor(1)) {
4096 BECond = BI->getCondition();
4097 IsPosBECond = BI->getSuccessor(0) == L->getHeader();
4098 } else {
4099 return S;
4100 }
4101 }
4102 SCEVBackedgeConditionFolder Rewriter(L, BECond, IsPosBECond, SE);
4103 return Rewriter.visit(S);
4104 }
4105
4106 const SCEV *visitUnknown(const SCEVUnknown *Expr) {
4107 const SCEV *Result = Expr;
4108 bool InvariantF = SE.isLoopInvariant(Expr, L);
4109
4110 if (!InvariantF) {
4111 Instruction *I = cast(Expr->getValue());
4112 switch (I->getOpcode()) {
4113 case Instruction::Select: {
4114 SelectInst *SI = cast(I);
4115 Optional Res =
4116 compareWithBackedgeCondition(SI->getCondition());
4117 if (Res.hasValue()) {
4118 bool IsOne = cast(Res.getValue())->getValue()->isOne();
4119 Result = SE.getSCEV(IsOne ? SI->getTrueValue() : SI->getFalseValue());
4120 }
4121 break;
4122 }
4123 default: {
4124 Optional Res = compareWithBackedgeCondition(I);
4125 if (Res.hasValue())
4126 Result = Res.getValue();
4127 break;
4128 }
4129 }
4130 }
4131 return Result;
4132 }
4133
4134 private:
4135 explicit SCEVBackedgeConditionFolder(const Loop *L, Value *BECond,
4136 bool IsPosBECond, ScalarEvolution &SE)
4137 : SCEVRewriteVisitor(SE), L(L), BackedgeCond(BECond),
4138 IsPositiveBECond(IsPosBECond) {}
4139
4140 Optional compareWithBackedgeCondition(Value *IC);
4141
4142 const Loop *L;
4143 /// Loop back condition.
4144 Value *BackedgeCond = nullptr;
4145 /// Set to true if loop back is on positive branch condition.
4146 bool IsPositiveBECond;
4147 };
4148
4149 Optional
4150 SCEVBackedgeConditionFolder::compareWithBackedgeCondition(Value *IC) {
4151
4152 // If value matches the backedge condition for loop latch,
4153 // then return a constant evolution node based on loopback
4154 // branch taken.
4155 if (BackedgeCond == IC)
4156 return IsPositiveBECond ? SE.getOne(Type::getInt1Ty(SE.getContext()))
4157 : SE.getZero(Type::getInt1Ty(SE.getContext()));
4158 return None;
4159 }
4160
40824161 class SCEVShiftRewriter : public SCEVRewriteVisitor {
40834162 public:
40844163 SCEVShiftRewriter(const Loop *L, ScalarEvolution &SE)
47524831 SmallVector Ops;
47534832 for (unsigned i = 0, e = Add->getNumOperands(); i != e; ++i)
47544833 if (i != FoundIndex)
4755 Ops.push_back(Add->getOperand(i));
4834 Ops.push_back(SCEVBackedgeConditionFolder::rewrite(Add->getOperand(i),
4835 L, *this));
47564836 const SCEV *Accum = getAddExpr(Ops);
47574837
47584838 // This is not a valid addrec if the step amount is varying each
47784858 // indices form a positive value.
47794859 if (GEP->isInBounds() && GEP->getOperand(0) == PN) {
47804860 Flags = setFlags(Flags, SCEV::FlagNW);
4781
4861
47824862 const SCEV *Ptr = getSCEV(GEP->getPointerOperand());
47834863 if (isKnownPositive(getMinusSCEV(getSCEV(GEP), Ptr)))
47844864 Flags = setFlags(Flags, SCEV::FlagNUW);
47854865 }
4786
4866
47874867 // We cannot transfer nuw and nsw flags from subtraction
47884868 // operations -- sub nuw X, Y is not the same as add nuw X, -Y
47894869 // for instance.
47904870 }
4791
4871
47924872 const SCEV *StartVal = getSCEV(StartValueV);
47934873 const SCEV *PHISCEV = getAddRecExpr(StartVal, Accum, L, Flags);
4794
4874
47954875 // Okay, for the entire analysis of this edge we assumed the PHI
47964876 // to be symbolic. We now need to go back and purge all of the
47974877 // entries for the scalars that use the symbolic expression.
47984878 forgetSymbolicName(PN, SymbolicName);
47994879 ValueExprMap[SCEVCallbackVH(PN, this)] = PHISCEV;
4800
4880
48014881 // We can add Flags to the post-inc expression only if we
48024882 // know that it is *undefined behavior* for BEValueV to
48034883 // overflow.
48044884 if (auto *BEInst = dyn_cast(BEValueV))
48054885 if (isLoopInvariant(Accum, L) && isAddRecNeverPoison(BEInst, L))
48064886 (void)getAddRecExpr(getAddExpr(StartVal, Accum), Accum, L, Flags);
4807
4887
48084888 return PHISCEV;
48094889 }
48104890 }
29692969 // consider leaf IV Users. This effectively rediscovers a portion of
29702970 // IVUsers analysis but in program order this time.
29712971 if (SE.isSCEVable(I.getType()) && !isa(SE.getSCEV(&I)))
2972 continue;
2972 continue;
29732973
29742974 // Remove this instruction from any NearUsers set it may be in.
29752975 for (unsigned ChainIdx = 0, NChains = IVChainVec.size();
0 ; RUN: opt -scalar-evolution -loop-deletion -simplifycfg -analyze < %s | FileCheck %s --check-prefix=CHECK-ANALYSIS-1
1 ; RUN: opt -analyze -scalar-evolution < %s | FileCheck %s --check-prefix=CHECK-ANALYSIS-2
2
3 define i32 @pr34538() local_unnamed_addr #0 {
4 ; CHECK-ANALYSIS-1: Loop %do.body: backedge-taken count is 10000
5 ; CHECK-ANALYSIS-1: Loop %do.body: max backedge-taken count is 10000
6 ; CHECK-ANALYSIS-1: Loop %do.body: Predicated backedge-taken count is 10000
7 entry:
8 br label %do.body
9
10 do.body: ; preds = %do.body, %entry
11 %start.0 = phi i32 [ 0, %entry ], [ %inc.start.0, %do.body ]
12 %cmp = icmp slt i32 %start.0, 10000
13 %inc = zext i1 %cmp to i32
14 %inc.start.0 = add nsw i32 %start.0, %inc
15 br i1 %cmp, label %do.body, label %do.end
16
17 do.end: ; preds = %do.body
18 ret i32 0
19 }
20
21
22 define i32 @foo() {
23 entry:
24 br label %do.body
25
26 do.body: ; preds = %do.body, %entry
27 %start.0 = phi i32 [ 0, %entry ], [ %inc.start.0, %do.body ]
28 %cmp = icmp slt i32 %start.0, 10000
29 %select_ext = select i1 %cmp, i32 2 , i32 1
30 %inc.start.0 = add nsw i32 %start.0, %select_ext
31 br i1 %cmp, label %do.body, label %do.end
32
33 do.end: ; preds = %do.body
34 ret i32 0
35 ; CHECK-ANALYSIS-2: Loop %do.body: backedge-taken count is 5000
36 ; CHECK-ANALYSIS-2: Loop %do.body: max backedge-taken count is 5000
37 ; CHECK-ANALYSIS-2: Loop %do.body: Predicated backedge-taken count is 5000
38 }