diff --git a/llvm/include/llvm/Analysis/ScalarEvolutionExpander.h b/llvm/include/llvm/Analysis/ScalarEvolutionExpander.h --- a/llvm/include/llvm/Analysis/ScalarEvolutionExpander.h +++ b/llvm/include/llvm/Analysis/ScalarEvolutionExpander.h @@ -176,18 +176,19 @@ /// Return true for expressions that can't be evaluated at runtime /// within given \b Budget. /// - /// At is an optional parameter which specifies point in code where user is - /// going to expand this expression. Sometimes this knowledge can lead to a - /// more accurate cost estimation. + /// At is a parameter which specifies point in code where user is going to + /// expand this expression. Sometimes this knowledge can lead to + /// a less pessimistic cost estimation. bool isHighCostExpansion(const SCEV *Expr, Loop *L, unsigned Budget, const TargetTransformInfo *TTI, - const Instruction *At = nullptr) { + const Instruction *At) { assert(TTI && "This function requires TTI to be provided."); + assert(At && "This function requires At instruction to be provided."); if (!TTI) // In assert-less builds, avoid crashing return true; // by always claiming to be high-cost. SmallPtrSet Processed; int BudgetRemaining = Budget * TargetTransformInfo::TCC_Basic; - return isHighCostExpansionHelper(Expr, L, At, BudgetRemaining, *TTI, + return isHighCostExpansionHelper(Expr, L, *At, BudgetRemaining, *TTI, Processed); } @@ -331,7 +332,7 @@ /// Recursive helper function for isHighCostExpansion. bool isHighCostExpansionHelper(const SCEV *S, Loop *L, - const Instruction *At, int &BudgetRemaining, + const Instruction &At, int &BudgetRemaining, const TargetTransformInfo &TTI, SmallPtrSetImpl &Processed); diff --git a/llvm/lib/Analysis/ScalarEvolutionExpander.cpp b/llvm/lib/Analysis/ScalarEvolutionExpander.cpp --- a/llvm/lib/Analysis/ScalarEvolutionExpander.cpp +++ b/llvm/lib/Analysis/ScalarEvolutionExpander.cpp @@ -2136,7 +2136,7 @@ } bool SCEVExpander::isHighCostExpansionHelper( - const SCEV *S, Loop *L, const Instruction *At, int &BudgetRemaining, + const SCEV *S, Loop *L, const Instruction &At, int &BudgetRemaining, const TargetTransformInfo &TTI, SmallPtrSetImpl &Processed) { if (BudgetRemaining < 0) return true; // Already run out of budget, give up. @@ -2147,7 +2147,7 @@ // If we can find an existing value for this scev available at the point "At" // then consider the expression cheap. - if (At && getRelatedExistingExpansion(S, At, L)) + if (getRelatedExistingExpansion(S, &At, L)) return false; // Consider the expression to be free. switch (S->getSCEVType()) { @@ -2198,18 +2198,12 @@ // UDiv from the user's code. If we can't find a UDiv in the code with some // simple searching, we need to account for it's cost. - BasicBlock *ExitingBB = L->getExitingBlock(); - if (At || ExitingBB) { - if (!At) - At = &ExitingBB->back(); - - // At the beginning of this function we already tried to find existing - // value for plain 'S'. Now try to lookup 'S + 1' since it is common - // pattern involving division. This is just a simple search heuristic. - if (getRelatedExistingExpansion( - SE.getAddExpr(S, SE.getConstant(S->getType(), 1)), At, L)) - return false; // Consider it to be free. - } + // At the beginning of this function we already tried to find existing + // value for plain 'S'. Now try to lookup 'S + 1' since it is common + // pattern involving division. This is just a simple search heuristic. + if (getRelatedExistingExpansion( + SE.getAddExpr(S, SE.getConstant(S->getType(), 1)), &At, L)) + return false; // Consider it to be free. // Need to count the cost of this UDiv. BudgetRemaining -= TTI.getOperationCost(Instruction::UDiv, S->getType()); 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 @@ -2726,6 +2726,9 @@ // If we have a trip count expression, rewrite the loop's exit condition // using it. if (!DisableLFTR) { + BasicBlock *PreHeader = L->getLoopPreheader(); + BranchInst *PreHeaderBR = cast(PreHeader->getTerminator()); + SmallVector ExitingBlocks; L->getExitingBlocks(ExitingBlocks); for (BasicBlock *ExitingBB : ExitingBlocks) { @@ -2760,7 +2763,7 @@ // Avoid high cost expansions. Note: This heuristic is questionable in // that our definition of "high cost" is not exactly principled. if (Rewriter.isHighCostExpansion(ExitCount, L, SCEVCheapExpansionBudget, - TTI)) + TTI, PreHeaderBR)) continue; // Check preconditions for proper SCEVExpander operation. SCEV does not diff --git a/llvm/test/Transforms/IndVarSimplify/elim-extend.ll b/llvm/test/Transforms/IndVarSimplify/elim-extend.ll --- a/llvm/test/Transforms/IndVarSimplify/elim-extend.ll +++ b/llvm/test/Transforms/IndVarSimplify/elim-extend.ll @@ -140,8 +140,8 @@ ; CHECK-NEXT: store i8 0, i8* [[ADR2]] ; CHECK-NEXT: [[ADR3:%.*]] = getelementptr i8, i8* [[ADDRESS]], i64 [[INDVARS_IV_NEXT]] ; CHECK-NEXT: store i8 0, i8* [[ADR3]] -; CHECK-NEXT: [[INNERCMP:%.*]] = icmp sgt i64 [[TMP0]], [[INDVARS_IV_NEXT]] -; CHECK-NEXT: br i1 [[INNERCMP]], label [[INNERLOOP]], label [[INNEREXIT:%.*]] +; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[TMP0]] +; CHECK-NEXT: br i1 [[EXITCOND]], label [[INNERLOOP]], label [[INNEREXIT:%.*]] ; CHECK: innerexit: ; CHECK-NEXT: [[TMP4:%.*]] = trunc i64 [[TMP0]] to i32 ; CHECK-NEXT: br label [[OUTERMERGE]] @@ -153,8 +153,8 @@ ; CHECK-NEXT: [[ADR5:%.*]] = getelementptr i8, i8* [[ADDRESS]], i64 [[OFS5]] ; CHECK-NEXT: store i8 0, i8* [[ADR5]] ; CHECK-NEXT: [[INDVARS_IV_NEXT2]] = add nuw nsw i64 [[INDVARS_IV1]], 1 -; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT2]], [[WIDE_TRIP_COUNT]] -; CHECK-NEXT: br i1 [[EXITCOND]], label [[OUTERLOOP]], label [[RETURN:%.*]] +; CHECK-NEXT: [[EXITCOND4:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT2]], [[WIDE_TRIP_COUNT]] +; CHECK-NEXT: br i1 [[EXITCOND4]], label [[OUTERLOOP]], label [[RETURN:%.*]] ; CHECK: return: ; CHECK-NEXT: ret void ;