Index: llvm/lib/Transforms/Scalar/IndVarSimplify.cpp =================================================================== --- llvm/lib/Transforms/Scalar/IndVarSimplify.cpp +++ llvm/lib/Transforms/Scalar/IndVarSimplify.cpp @@ -2375,6 +2375,15 @@ // backedge branches to the loop header. This is one less than the // number of times the loop executes, so use the incremented indvar. CmpIndVar = IndVar->getIncomingValueForBlock(L->getExitingBlock()); + + // The result of the increment may be poison due to nuw/nsw flags. SCEV + // already keeps track of the correct nuw/nsw flags, so we just copy + // whatever it computed here. + if (auto *BO = dyn_cast(CmpIndVar)) { + const SCEVAddRecExpr *AR = cast(SE->getSCEV(CmpIndVar)); + BO->setHasNoUnsignedWrap(AR->hasNoUnsignedWrap()); + BO->setHasNoSignedWrap(AR->hasNoSignedWrap()); + } } Value *ExitCnt = genLoopLimit(IndVar, IVCount, L, Rewriter, SE); Index: llvm/test/Transforms/IndVarSimplify/pr31181.ll =================================================================== --- llvm/test/Transforms/IndVarSimplify/pr31181.ll +++ llvm/test/Transforms/IndVarSimplify/pr31181.ll @@ -15,7 +15,7 @@ ; CHECK: loop: ; CHECK-NEXT: [[STOREMERGE:%.*]] = phi i32 [ -2, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[LOOP]] ] ; CHECK-NEXT: store i32 [[STOREMERGE]], i32* @a -; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[STOREMERGE]], 1 +; CHECK-NEXT: [[INC]] = add nsw i32 [[STOREMERGE]], 1 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[INC]], 0 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]] ; CHECK: exit: @@ -42,7 +42,7 @@ ; CHECK: loop: ; CHECK-NEXT: [[STOREMERGE:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[LOOP]] ] ; CHECK-NEXT: store i32 [[STOREMERGE]], i32* @a -; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[STOREMERGE]], 1 +; CHECK-NEXT: [[INC]] = add nuw i32 [[STOREMERGE]], 1 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[INC]], -2147483648 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]] ; CHECK: exit: @@ -128,7 +128,7 @@ ; CHECK: loop: ; CHECK-NEXT: [[STOREMERGE:%.*]] = phi i32 [ [[INC:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] ; CHECK-NEXT: store i32 [[STOREMERGE]], i32* @a -; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[STOREMERGE]], 1 +; CHECK-NEXT: [[INC]] = add nuw i32 [[STOREMERGE]], 1 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[INC]], [[TMP0]] ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] ; CHECK: exit.loopexit: