Index: include/llvm/Analysis/ScalarEvolutionExpander.h =================================================================== --- include/llvm/Analysis/ScalarEvolutionExpander.h +++ include/llvm/Analysis/ScalarEvolutionExpander.h @@ -276,7 +276,12 @@ /// /// Note that this function does not perform an exhaustive search. I.e if it /// didn't find any value it does not mean that there is no such value. - Value *findExistingExpansion(const SCEV *S, const Instruction *At, Loop *L); + /// + /// \p OnlyCheckIsNull is used to indicate that we only care whether there + /// is an existing value to be reused, and will not insert the return value + /// into the IR. + Value *findExistingExpansion(const SCEV *S, const Instruction *At, Loop *L, + bool OnlyCheckIsNull = true); private: LLVMContext &getContext() const { return SE.getContext(); } Index: lib/Analysis/ScalarEvolutionExpander.cpp =================================================================== --- lib/Analysis/ScalarEvolutionExpander.cpp +++ lib/Analysis/ScalarEvolutionExpander.cpp @@ -1893,8 +1893,8 @@ return NumElim; } -Value *SCEVExpander::findExistingExpansion(const SCEV *S, - const Instruction *At, Loop *L) { +Value *SCEVExpander::findExistingExpansion(const SCEV *S, const Instruction *At, + Loop *L, bool OnlyCheckIsNull) { using namespace llvm::PatternMatch; SmallVector ExitingBlocks; @@ -1920,8 +1920,11 @@ // Use expand's logic which is used for reusing a previous Value in // ExprValueMap. - if (Value *Val = FindValueInExprValueMap(S, At).first) - return Val; + ScalarEvolution::ValueOffsetPair VO = FindValueInExprValueMap(S, At); + // When VO.second is not zero, the returned value VO.first doesn't equal + // to S and can only be used when OnlyCheckIsNull is true. + if (!VO.second || OnlyCheckIsNull) + return VO.first; // There is potential to make this significantly smarter, but this simple // heuristic already gets some interesting cases. Index: lib/Transforms/Scalar/IndVarSimplify.cpp =================================================================== --- lib/Transforms/Scalar/IndVarSimplify.cpp +++ lib/Transforms/Scalar/IndVarSimplify.cpp @@ -481,7 +481,8 @@ Type *ResultTy) { // Before expanding S into an expensive LLVM expression, see if we can use an // already existing value as the expansion for S. - if (Value *ExistingValue = Rewriter.findExistingExpansion(S, InsertPt, L)) + if (Value *ExistingValue = + Rewriter.findExistingExpansion(S, InsertPt, L, false)) if (ExistingValue->getType() == ResultTy) return ExistingValue; Index: test/Analysis/ScalarEvolution/pr28705.ll =================================================================== --- test/Analysis/ScalarEvolution/pr28705.ll +++ test/Analysis/ScalarEvolution/pr28705.ll @@ -0,0 +1,41 @@ +; PR28705 +; RUN: opt < %s -indvars -debug-only=indvars -S | FileCheck %s + +; Check IndVarSimplify replaces the exitval use of the induction var "%inc.i.i" +; with "%.sroa.speculated + 1". +; +; CHECK-LABEL: @foo( +; CHECK: %[[EXIT:.+]] = sub i32 %.sroa.speculated, -1 +; CHECK: %DB.sroa.9.0.lcssa = phi i32 [ 1, %entry ], [ %[[EXIT]], %loopexit ] +; +define void @foo(i32 %sub.ptr.div.i, i8* %ref.i1174) local_unnamed_addr { +entry: + %cmp.i1137 = icmp ugt i32 %sub.ptr.div.i, 3 + %.sroa.speculated = select i1 %cmp.i1137, i32 3, i32 %sub.ptr.div.i + %cmp6483126 = icmp eq i32 %.sroa.speculated, 0 + br i1 %cmp6483126, label %XZ.exit, label %for.body650.lr.ph + +for.body650.lr.ph: + br label %for.body650 + +loopexit: + %inc.i.i.lcssa = phi i32 [ %inc.i.i, %for.body650 ] + br label %XZ.exit + +XZ.exit: + %DB.sroa.9.0.lcssa = phi i32 [ 1, %entry ], [ %inc.i.i.lcssa, %loopexit ] + br label %end + +for.body650: + %I641.03128 = phi i32 [ 0, %for.body650.lr.ph ], [ %inc655, %for.body650 ] + %DB.sroa.9.03127 = phi i32 [ 1, %for.body650.lr.ph ], [ %inc.i.i, %for.body650 ] + %arrayidx.i.i1105 = getelementptr inbounds i8, i8* %ref.i1174, i32 %DB.sroa.9.03127 + store i8 7, i8* %arrayidx.i.i1105, align 1 + %inc.i.i = add i32 %DB.sroa.9.03127, 1 + %inc655 = add i32 %I641.03128, 1 + %cmp648 = icmp eq i32 %inc655, %.sroa.speculated + br i1 %cmp648, label %loopexit, label %for.body650 + +end: + ret void +}