diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp --- a/llvm/lib/Analysis/ScalarEvolution.cpp +++ b/llvm/lib/Analysis/ScalarEvolution.cpp @@ -5735,8 +5735,14 @@ if (auto *BEInst = dyn_cast(BEValueV)) { assert(isLoopInvariant(Accum, L) && "Accum is defined outside L, but is not invariant?"); - if (isAddRecNeverPoison(BEInst, L)) - (void)getAddRecExpr(getAddExpr(StartVal, Accum), Accum, L, Flags); + if (isAddRecNeverPoison(BEInst, L)) { + auto *S = getAddRecExpr(getAddExpr(StartVal, Accum), Accum, L, Flags); + if (auto *AR = dyn_cast(S)) { + setNoWrapFlags(const_cast(AR), + (SCEV::NoWrapFlags)(AR->getNoWrapFlags() | + proveNoWrapViaConstantRanges(AR))); + } + } } return PHISCEV; @@ -5864,8 +5870,16 @@ // know that it is *undefined behavior* for BEValueV to // overflow. if (auto *BEInst = dyn_cast(BEValueV)) - if (isLoopInvariant(Accum, L) && isAddRecNeverPoison(BEInst, L)) - (void)getAddRecExpr(getAddExpr(StartVal, Accum), Accum, L, Flags); + if (isLoopInvariant(Accum, L) && isAddRecNeverPoison(BEInst, L)) { + auto *S = + getAddRecExpr(getAddExpr(StartVal, Accum), Accum, L, Flags); + if (auto *AR = dyn_cast(S)) { + setNoWrapFlags( + const_cast(AR), + (SCEV::NoWrapFlags)(AR->getNoWrapFlags() | + proveNoWrapViaConstantRanges(AR))); + } + } return PHISCEV; } diff --git a/llvm/test/Analysis/ScalarEvolution/trip-count-negative-stride.ll b/llvm/test/Analysis/ScalarEvolution/trip-count-negative-stride.ll --- a/llvm/test/Analysis/ScalarEvolution/trip-count-negative-stride.ll +++ b/llvm/test/Analysis/ScalarEvolution/trip-count-negative-stride.ll @@ -106,10 +106,10 @@ define void @ult_129_unknown_start(i8 %start) mustprogress { ; CHECK-LABEL: 'ult_129_unknown_start' ; CHECK-NEXT: Determining loop execution counts for: @ult_129_unknown_start -; CHECK-NEXT: Loop %for.body: backedge-taken count is 0 -; CHECK-NEXT: Loop %for.body: constant max backedge-taken count is 0 -; CHECK-NEXT: Loop %for.body: symbolic max backedge-taken count is 0 -; CHECK-NEXT: Loop %for.body: Predicated backedge-taken count is 0 +; CHECK-NEXT: Loop %for.body: backedge-taken count is (((127 + (-1 * (1 umin (127 + (-1 * %start) + (-128 umax (-127 + %start))))) + (-1 * %start) + (-128 umax (-127 + %start))) /u -127) + (1 umin (127 + (-1 * %start) + (-128 umax (-127 + %start))))) +; CHECK-NEXT: Loop %for.body: constant max backedge-taken count is 1 +; CHECK-NEXT: Loop %for.body: symbolic max backedge-taken count is (((127 + (-1 * (1 umin (127 + (-1 * %start) + (-128 umax (-127 + %start))))) + (-1 * %start) + (-128 umax (-127 + %start))) /u -127) + (1 umin (127 + (-1 * %start) + (-128 umax (-127 + %start))))) +; CHECK-NEXT: Loop %for.body: Predicated backedge-taken count is (((127 + (-1 * (1 umin (127 + (-1 * %start) + (-128 umax (-127 + %start))))) + (-1 * %start) + (-128 umax (-127 + %start))) /u -127) + (1 umin (127 + (-1 * %start) + (-128 umax (-127 + %start))))) ; CHECK-NEXT: Predicates: ; CHECK: Loop %for.body: Trip multiple is 1 ;