diff --git a/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp b/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp --- a/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp +++ b/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp @@ -910,60 +910,27 @@ assert(isLoopCounter(IndVar, L, SE)); assert(ExitCount->getType()->isIntegerTy() && "exit count must be integer"); const SCEVAddRecExpr *AR = cast(SE->getSCEV(IndVar)); - const SCEV *IVInit = AR->getStart(); assert(AR->getStepRecurrence(*SE)->isOne() && "only handles unit stride"); - // IVInit may be a pointer while ExitCount is an integer when FindLoopCounter - // finds a valid pointer IV. - if (IndVar->getType()->isPointerTy()) { - const SCEVAddRecExpr *ARBase = UsePostInc ? AR->getPostIncExpr(*SE) : AR; - const SCEV *IVLimit = ARBase->evaluateAtIteration(ExitCount, *SE); - assert(SE->isLoopInvariant(IVLimit, L) && - "Computed iteration count is not loop invariant!"); - return Rewriter.expandCodeFor(IVLimit, IndVar->getType(), - ExitingBB->getTerminator()); - } else { - // In any other case, convert both IVInit and ExitCount to integers before - // comparing. This may result in SCEV expansion of pointers, but in practice - // SCEV will fold the pointer arithmetic away as such: - // BECount = (IVEnd - IVInit - 1) => IVLimit = IVInit (postinc). - // - // Valid Cases: (1) both integers is most common; (2) both may be pointers - // for simple memset-style loops. - // - // IVInit integer and ExitCount pointer would only occur if a canonical IV - // were generated on top of case #2, which is not expected. - - // For unit stride, IVCount = Start + ExitCount with 2's complement - // overflow. - - // For integer IVs, truncate the IV before computing IVInit + BECount, - // unless we know apriori that the limit must be a constant when evaluated - // in the bitwidth of the IV. We prefer (potentially) keeping a truncate - // of the IV in the loop over a (potentially) expensive expansion of the - // widened exit count add(zext(add)) expression. - if (SE->getTypeSizeInBits(IVInit->getType()) - > SE->getTypeSizeInBits(ExitCount->getType())) { - if (isa(IVInit) && isa(ExitCount)) - ExitCount = SE->getZeroExtendExpr(ExitCount, IVInit->getType()); - else - IVInit = SE->getTruncateExpr(IVInit, ExitCount->getType()); - } - - const SCEV *IVLimit = SE->getAddExpr(IVInit, ExitCount); - - if (UsePostInc) - IVLimit = SE->getAddExpr(IVLimit, SE->getOne(IVLimit->getType())); - - // Expand the code for the iteration count. - assert(SE->isLoopInvariant(IVLimit, L) && - "Computed iteration count is not loop invariant!"); - // Ensure that we generate the same type as IndVar, or a smaller integer - // type. In the presence of null pointer values, we have an integer type - // SCEV expression (IVInit) for a pointer type IV value (IndVar). - return Rewriter.expandCodeFor(IVLimit, ExitCount->getType(), - ExitingBB->getTerminator()); + // For integer IVs, truncate the IV before computing the limit unless we + // know apriori that the limit must be a constant when evaluated in the + // bitwidth of the IV. We prefer (potentially) keeping a truncate of the + // IV in the loop over a (potentially) expensive expansion of the widened + // exit count add(zext(add)) expression. + if (IndVar->getType()->isIntegerTy() && + SE->getTypeSizeInBits(AR->getType()) > + SE->getTypeSizeInBits(ExitCount->getType())) { + const SCEV *IVInit = AR->getStart(); + if (!isa(IVInit) || !isa(ExitCount)) + AR = cast(SE->getTruncateExpr(AR, ExitCount->getType())); } + + const SCEVAddRecExpr *ARBase = UsePostInc ? AR->getPostIncExpr(*SE) : AR; + const SCEV *IVLimit = ARBase->evaluateAtIteration(ExitCount, *SE); + assert(SE->isLoopInvariant(IVLimit, L) && + "Computed iteration count is not loop invariant!"); + return Rewriter.expandCodeFor(IVLimit, ARBase->getType(), + ExitingBB->getTerminator()); } /// This method rewrites the exit condition of the loop to be a canonical !=