Index: lib/Analysis/ScalarEvolution.cpp =================================================================== --- lib/Analysis/ScalarEvolution.cpp +++ lib/Analysis/ScalarEvolution.cpp @@ -4809,6 +4809,50 @@ return PHISCEV; } } + + } else if (isa(BEValue) || isa(BEValue)) { + // Okay, now we are going to check that Loop's condition operand is increasing. + BranchInst *BR = dyn_cast(L->getLoopLatch()->getTerminator()); + + // If it has conditional branch. + if (BR && BR->isConditional()) { + ICmpInst *ICI = dyn_cast(BR->getCondition()); + + // Now we are checking that BEValueV is increasing ICI's operand. + Instruction *AddExpr = dyn_cast(BEValueV); + Value *LHS = ICI->getOperand(0); + Value *RHS = ICI->getOperand(1); + + // We are not finding a constant. we are finding expression that we increasing. + if (isa(RHS)) + std::swap(LHS, RHS); + + // It can be select instruction. + // that selected condition should same so we can analyze. + if (SelectInst* SI = dyn_cast(AddExpr)) { + if (AddExpr->getOperand(0) != ICI) + return nullptr; + + AddExpr = dyn_cast(AddExpr->getOperand(1)); + } + + // Check that we are increasing is ICI's operand. + // AddExpr's first operand is target. + if (AddExpr && AddExpr->getOperand(0) == RHS) { + // Yes its increasing ICI's operand. now we can assume that this loop can exit. + const SCEV* SCEVStart = getSCEV(StartValueV); + const SCEV* SCEVStep; + + // AddExpr's operand can be constant. it means it probably not increasing constant 1 + // so we are going to just evolute constant variable. + if (Constant* ST = dyn_cast(AddExpr->getOperand(1))) + SCEVStep = getSCEV(ST); + else + SCEVStep = getOne(AddExpr->getType()); + + return getAddRecExpr(SCEVStart, SCEVStep, L, SCEV::NoWrapFlags::FlagAnyWrap); + } + } } else { // Otherwise, this could be a loop like this: // i = 0; for (j = 1; ..; ++j) { .... i = j; } @@ -6126,6 +6170,11 @@ case Instruction::PHI: return createNodeForPHI(cast(U)); + case Instruction::Switch: { + SwitchInst* SI = dyn_cast(U); + return getUnknown(V); + } + case Instruction::Select: // U can also be a select constant expr, which let fall through. Since // createNodeForSelect only works for a condition that is an `ICmpInst`, and