Index: llvm/lib/Transforms/Scalar/IndVarSimplify.cpp =================================================================== --- llvm/lib/Transforms/Scalar/IndVarSimplify.cpp +++ llvm/lib/Transforms/Scalar/IndVarSimplify.cpp @@ -2401,32 +2401,15 @@ Instruction * const IncVar = cast(IndVar->getIncomingValueForBlock(L->getLoopLatch())); - // Initialize CmpIndVar to the preincremented IV. - Value *CmpIndVar = IndVar; - bool UsePostInc = false; - - // If the exiting block is the same as the backedge block, we prefer to - // compare against the post-incremented value, otherwise we must compare - // against the preincremented value. - if (ExitingBB == L->getLoopLatch()) { - // For pointer IVs, we chose to not strip inbounds which requires us not - // to add a potentially UB introducing use. We need to either a) show - // the loop test we're modifying is already in post-inc form, or b) show - // that adding a use must not introduce UB. - bool SafeToPostInc = - IndVar->getType()->isIntegerTy() || - isLoopExitTestBasedOn(IncVar, ExitingBB) || - mustExecuteUBIfPoisonOnPathTo(IncVar, ExitingBB->getTerminator(), DT); - if (SafeToPostInc) { - UsePostInc = true; - CmpIndVar = IncVar; - } - } + // If the old loop exit test was based on the post-inc IV, use it, otherwise + // stick with the pre-inc form and leave the conversion to post-inc form to + // LSR. Converting to post-inc now may require dropping poison flags. + bool UsePostInc = ExitingBB == L->getLoopLatch() && + isLoopExitTestBasedOn(IncVar, ExitingBB); + Value *CmpIndVar = UsePostInc ? IncVar : IndVar; // It may be necessary to drop nowrap flags on the incrementing instruction - // if either LFTR moves from a pre-inc check to a post-inc check (in which - // case the increment might have previously been poison on the last iteration - // only) or if LFTR switches to a different IV that was previously dynamically + // if LFTR switches to a different IV that was previously dynamically // dead (and as such may be arbitrarily poison). We remove any nowrap flags // that SCEV didn't infer for the post-inc addrec (even if we use a pre-inc // check), because the pre-inc addrec flags may be adopted from the original Index: llvm/test/Transforms/IndVarSimplify/2011-11-01-lftrptr.ll =================================================================== --- llvm/test/Transforms/IndVarSimplify/2011-11-01-lftrptr.ll +++ llvm/test/Transforms/IndVarSimplify/2011-11-01-lftrptr.ll @@ -149,14 +149,13 @@ ; PTR64-NEXT: [[TMP1:%.*]] = add i32 [[EI]], -1 ; PTR64-NEXT: [[TMP2:%.*]] = sub i32 [[TMP1]], [[BI]] ; PTR64-NEXT: [[TMP3:%.*]] = zext i32 [[TMP2]] to i64 -; PTR64-NEXT: [[TMP4:%.*]] = add nuw nsw i64 [[TMP3]], 1 -; PTR64-NEXT: [[TMP5:%.*]] = inttoptr i64 [[TMP4]] to i8* +; PTR64-NEXT: [[TMP4:%.*]] = inttoptr i64 [[TMP3]] to i8* ; PTR64-NEXT: br label [[LOOP:%.*]] ; PTR64: loop: ; PTR64-NEXT: [[P_01_US_US:%.*]] = phi i8* [ null, [[PREHEADER]] ], [ [[GEP:%.*]], [[LOOP]] ] ; PTR64-NEXT: [[GEP]] = getelementptr inbounds i8, i8* [[P_01_US_US]], i64 1 ; PTR64-NEXT: [[SNEXT:%.*]] = load i8, i8* [[GEP]] -; PTR64-NEXT: [[EXITCOND:%.*]] = icmp ne i8* [[GEP]], [[TMP5]] +; PTR64-NEXT: [[EXITCOND:%.*]] = icmp ne i8* [[P_01_US_US]], [[TMP4]] ; PTR64-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] ; PTR64: exit.loopexit: ; PTR64-NEXT: [[SNEXT_LCSSA:%.*]] = phi i8 [ [[SNEXT]], [[LOOP]] ] @@ -171,16 +170,18 @@ ; PTR32-NEXT: [[BI:%.*]] = ptrtoint i8* [[BUF:%.*]] to i32 ; PTR32-NEXT: [[EI:%.*]] = ptrtoint i8* [[END:%.*]] to i32 ; PTR32-NEXT: [[CNT:%.*]] = sub i32 [[EI]], [[BI]] -; PTR32-NEXT: [[CNT1:%.*]] = inttoptr i32 [[CNT]] to i8* ; PTR32-NEXT: [[GUARD:%.*]] = icmp ult i32 0, [[CNT]] ; PTR32-NEXT: br i1 [[GUARD]], label [[PREHEADER:%.*]], label [[EXIT:%.*]] ; PTR32: preheader: +; PTR32-NEXT: [[TMP1:%.*]] = add i32 [[EI]], -1 +; PTR32-NEXT: [[TMP2:%.*]] = sub i32 [[TMP1]], [[BI]] +; PTR32-NEXT: [[TMP3:%.*]] = inttoptr i32 [[TMP2]] to i8* ; PTR32-NEXT: br label [[LOOP:%.*]] ; PTR32: loop: ; PTR32-NEXT: [[P_01_US_US:%.*]] = phi i8* [ null, [[PREHEADER]] ], [ [[GEP:%.*]], [[LOOP]] ] ; PTR32-NEXT: [[GEP]] = getelementptr inbounds i8, i8* [[P_01_US_US]], i64 1 ; PTR32-NEXT: [[SNEXT:%.*]] = load i8, i8* [[GEP]] -; PTR32-NEXT: [[EXITCOND:%.*]] = icmp ne i8* [[GEP]], [[CNT1]] +; PTR32-NEXT: [[EXITCOND:%.*]] = icmp ne i8* [[P_01_US_US]], [[TMP3]] ; PTR32-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] ; PTR32: exit.loopexit: ; PTR32-NEXT: [[SNEXT_LCSSA:%.*]] = phi i8 [ [[SNEXT]], [[LOOP]] ] Index: llvm/test/Transforms/IndVarSimplify/drop-exact.ll =================================================================== --- llvm/test/Transforms/IndVarSimplify/drop-exact.ll +++ llvm/test/Transforms/IndVarSimplify/drop-exact.ll @@ -24,7 +24,7 @@ ; CHECK-NEXT: [[TMP26:%.*]] = zext i32 [[TMP20]] to i64 ; CHECK-NEXT: store i64 [[TMP26]], i64* [[P1:%.*]], align 4 ; CHECK-NEXT: [[TMP42]] = add nuw nsw i32 [[TMP14]], 1 -; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i32 [[TMP42]], 719 +; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i32 [[TMP14]], 718 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[BB7:%.*]], label [[BB12]] ; bb: @@ -71,7 +71,7 @@ ; CHECK-NEXT: [[TMP26:%.*]] = zext i32 [[TMP20]] to i64 ; CHECK-NEXT: store i64 [[TMP26]], i64* [[P1:%.*]], align 4 ; CHECK-NEXT: [[TMP42]] = add nuw nsw i32 [[TMP14]], 1 -; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i32 [[TMP42]], 719 +; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i32 [[TMP14]], 718 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[BB7:%.*]], label [[BB12]] ; bb: Index: llvm/test/Transforms/IndVarSimplify/eliminate-comparison.ll =================================================================== --- llvm/test/Transforms/IndVarSimplify/eliminate-comparison.ll +++ llvm/test/Transforms/IndVarSimplify/eliminate-comparison.ll @@ -335,6 +335,7 @@ ; CHECK-LABEL: @func_13( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[LEN:%.*]] = load i32, i32* [[LEN_PTR:%.*]], !range !0 +; CHECK-NEXT: [[LEN_SUB_1:%.*]] = add i32 [[LEN]], -1 ; CHECK-NEXT: [[LEN_IS_ZERO:%.*]] = icmp eq i32 [[LEN]], 0 ; CHECK-NEXT: br i1 [[LEN_IS_ZERO]], label [[LEAVE:%.*]], label [[LOOP_PREHEADER:%.*]] ; CHECK: loop.preheader: @@ -346,7 +347,7 @@ ; CHECK-NEXT: br i1 true, label [[BE]], label [[LEAVE_LOOPEXIT:%.*]] ; CHECK: be: ; CHECK-NEXT: call void @side_effect() -; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[IV_INC]], [[LEN]] +; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[IV]], [[LEN_SUB_1]] ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LEAVE_LOOPEXIT]] ; CHECK: leave.loopexit: ; CHECK-NEXT: br label [[LEAVE]] @@ -379,6 +380,7 @@ ; CHECK-LABEL: @func_14( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[LEN:%.*]] = load i32, i32* [[LEN_PTR:%.*]], !range !0 +; CHECK-NEXT: [[LEN_SUB_1:%.*]] = add i32 [[LEN]], -1 ; CHECK-NEXT: [[LEN_IS_ZERO:%.*]] = icmp eq i32 [[LEN]], 0 ; CHECK-NEXT: [[LEN_IS_INT_MIN:%.*]] = icmp eq i32 [[LEN]], -2147483648 ; CHECK-NEXT: [[NO_ENTRY:%.*]] = or i1 [[LEN_IS_ZERO]], [[LEN_IS_INT_MIN]] @@ -392,7 +394,7 @@ ; CHECK-NEXT: br i1 true, label [[BE]], label [[LEAVE_LOOPEXIT:%.*]] ; CHECK: be: ; CHECK-NEXT: call void @side_effect() -; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[IV_INC]], [[LEN]] +; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[IV]], [[LEN_SUB_1]] ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LEAVE_LOOPEXIT]] ; CHECK: leave.loopexit: ; CHECK-NEXT: br label [[LEAVE]] @@ -439,7 +441,7 @@ ; CHECK-NEXT: br i1 true, label [[BE]], label [[LEAVE_LOOPEXIT:%.*]] ; CHECK: be: ; CHECK-NEXT: call void @side_effect() -; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[IV_INC]], [[LEN_ADD_1]] +; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[IV]], [[LEN]] ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LEAVE_LOOPEXIT]] ; CHECK: leave.loopexit: ; CHECK-NEXT: br label [[LEAVE]] @@ -478,7 +480,6 @@ ; CHECK-NEXT: [[ENTRY_COND:%.*]] = and i1 [[ENTRY_COND_0]], [[ENTRY_COND_1]] ; CHECK-NEXT: br i1 [[ENTRY_COND]], label [[LOOP_PREHEADER:%.*]], label [[LEAVE:%.*]] ; CHECK: loop.preheader: -; CHECK-NEXT: [[TMP0:%.*]] = add nuw nsw i32 [[LEN]], 1 ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[IV_INC:%.*]], [[BE:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] @@ -487,7 +488,7 @@ ; CHECK-NEXT: br i1 true, label [[BE]], label [[LEAVE_LOOPEXIT:%.*]] ; CHECK: be: ; CHECK-NEXT: call void @side_effect() -; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[IV_INC]], [[TMP0]] +; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[IV]], [[LEN]] ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LEAVE_LOOPEXIT]] ; CHECK: leave.loopexit: ; CHECK-NEXT: br label [[LEAVE]] Index: llvm/test/Transforms/IndVarSimplify/eliminate-trunc.ll =================================================================== --- llvm/test/Transforms/IndVarSimplify/eliminate-trunc.ll +++ llvm/test/Transforms/IndVarSimplify/eliminate-trunc.ll @@ -140,13 +140,12 @@ ; ; CHECK-LABEL: @test_05( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[N:%.*]], 1 +; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = sext i32 [[N:%.*]] to i64 ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ -2147483648, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ] ; CHECK-NEXT: [[IV_NEXT]] = add nsw i64 [[IV]], 1 -; CHECK-NEXT: [[LFTR_WIDEIV:%.*]] = trunc i64 [[IV_NEXT]] to i32 -; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[LFTR_WIDEIV]], [[TMP0]] +; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[IV]], [[WIDE_TRIP_COUNT]] ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]] ; CHECK: exit: ; CHECK-NEXT: ret void @@ -216,13 +215,12 @@ define void @test_01_unsigned(i32 %n) { ; CHECK-LABEL: @test_01_unsigned( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[N:%.*]], 1 +; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[N:%.*]] to i64 ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ] ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1 -; CHECK-NEXT: [[LFTR_WIDEIV:%.*]] = trunc i64 [[IV_NEXT]] to i32 -; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[LFTR_WIDEIV]], [[TMP0]] +; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[IV]], [[WIDE_TRIP_COUNT]] ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]] ; CHECK: exit: ; CHECK-NEXT: ret void @@ -291,13 +289,12 @@ define void @test_04_unsigned(i32 %n) { ; CHECK-LABEL: @test_04_unsigned( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[N:%.*]], 1 +; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[N:%.*]] to i64 ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ] ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1 -; CHECK-NEXT: [[LFTR_WIDEIV:%.*]] = trunc i64 [[IV_NEXT]] to i32 -; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[LFTR_WIDEIV]], [[TMP0]] +; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[IV]], [[WIDE_TRIP_COUNT]] ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]] ; CHECK: exit: ; CHECK-NEXT: ret void Index: llvm/test/Transforms/IndVarSimplify/lftr-dead-ivs.ll =================================================================== --- llvm/test/Transforms/IndVarSimplify/lftr-dead-ivs.ll +++ llvm/test/Transforms/IndVarSimplify/lftr-dead-ivs.ll @@ -141,7 +141,7 @@ ; CHECK-NEXT: [[P_0:%.*]] = phi i8* [ getelementptr inbounds ([240 x i8], [240 x i8]* @data, i64 0, i64 0), [[ENTRY:%.*]] ], [ [[TMP3:%.*]], [[LOOP]] ] ; CHECK-NEXT: [[TMP3]] = getelementptr inbounds i8, i8* [[P_0]], i64 1 ; CHECK-NEXT: store volatile i8 0, i8* [[TMP3]] -; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i8* [[TMP3]], getelementptr ([240 x i8], [240 x i8]* @data, i64 1, i64 6) +; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i8* [[P_0]], getelementptr ([240 x i8], [240 x i8]* @data, i64 1, i64 5) ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]] ; CHECK: exit: ; CHECK-NEXT: ret void @@ -170,7 +170,7 @@ ; CHECK-NEXT: [[P_0:%.*]] = phi i8* [ getelementptr inbounds ([240 x i8], [240 x i8]* @data, i64 0, i64 0), [[ENTRY:%.*]] ], [ [[TMP3:%.*]], [[LOOP]] ] ; CHECK-NEXT: [[TMP3]] = getelementptr inbounds i8, i8* [[P_0]], i64 1 ; CHECK-NEXT: [[V:%.*]] = load i8, i8* [[TMP3]] -; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i8* [[TMP3]], getelementptr ([240 x i8], [240 x i8]* @data, i64 1, i64 6) +; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i8* [[P_0]], getelementptr ([240 x i8], [240 x i8]* @data, i64 1, i64 5) ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]] ; CHECK: exit: ; CHECK-NEXT: [[V_LCSSA:%.*]] = phi i8 [ [[V]], [[LOOP]] ] @@ -233,7 +233,7 @@ ; CHECK: loop: ; CHECK-NEXT: [[I_1:%.*]] = phi i64 [ -2, [[ENTRY:%.*]] ], [ [[TMP3:%.*]], [[LOOP]] ] ; CHECK-NEXT: [[TMP3]] = add nsw i64 [[I_1]], 1 -; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[TMP3]], 244 +; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[I_1]], 243 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]] ; CHECK: exit: ; CHECK-NEXT: ret void Index: llvm/test/Transforms/IndVarSimplify/lftr-multi-exit.ll =================================================================== --- llvm/test/Transforms/IndVarSimplify/lftr-multi-exit.ll +++ llvm/test/Transforms/IndVarSimplify/lftr-multi-exit.ll @@ -288,7 +288,7 @@ ; CHECK: latch: ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1 ; CHECK-NEXT: store volatile i32 [[IV]], i32* @A -; CHECK-NEXT: [[EXITCOND1:%.*]] = icmp ne i32 [[IV_NEXT]], 999 +; CHECK-NEXT: [[EXITCOND1:%.*]] = icmp ne i32 [[IV]], 998 ; CHECK-NEXT: br i1 [[EXITCOND1]], label [[LOOP]], label [[EXIT]] ; CHECK: exit: ; CHECK-NEXT: ret void @@ -325,7 +325,7 @@ ; CHECK: latch: ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1 ; CHECK-NEXT: store volatile i32 [[IV]], i32* @A -; CHECK-NEXT: [[EXITCOND1:%.*]] = icmp ne i32 [[IV_NEXT]], 1000 +; CHECK-NEXT: [[EXITCOND1:%.*]] = icmp ne i32 [[IV]], 999 ; CHECK-NEXT: br i1 [[EXITCOND1]], label [[LOOP]], label [[EXIT]] ; CHECK: exit: ; CHECK-NEXT: ret void @@ -363,7 +363,7 @@ ; CHECK: latch: ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1 ; CHECK-NEXT: store volatile i32 [[IV]], i32* @A -; CHECK-NEXT: [[EXITCOND1:%.*]] = icmp ne i32 [[IV_NEXT]], 65 +; CHECK-NEXT: [[EXITCOND1:%.*]] = icmp ne i32 [[IV]], 64 ; CHECK-NEXT: br i1 [[EXITCOND1]], label [[LOOP]], label [[EXIT]] ; CHECK: exit: ; CHECK-NEXT: ret void @@ -438,7 +438,6 @@ define void @nested(i32 %n) { ; CHECK-LABEL: @nested( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[N:%.*]], 1 ; CHECK-NEXT: br label [[OUTER:%.*]] ; CHECK: outer: ; CHECK-NEXT: [[IV1:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV1_NEXT:%.*]], [[OUTER_LATCH:%.*]] ] @@ -452,10 +451,10 @@ ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[IV2]], 20 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[INNER_LATCH]], label [[EXIT_LOOPEXIT:%.*]] ; CHECK: inner_latch: -; CHECK-NEXT: [[EXITCOND2:%.*]] = icmp ne i32 [[IV2_NEXT]], [[TMP0]] +; CHECK-NEXT: [[EXITCOND2:%.*]] = icmp ne i32 [[IV2]], [[N:%.*]] ; CHECK-NEXT: br i1 [[EXITCOND2]], label [[INNER]], label [[OUTER_LATCH]] ; CHECK: outer_latch: -; CHECK-NEXT: [[EXITCOND3:%.*]] = icmp ne i32 [[IV1_NEXT]], 21 +; CHECK-NEXT: [[EXITCOND3:%.*]] = icmp ne i32 [[IV1]], 20 ; CHECK-NEXT: br i1 [[EXITCOND3]], label [[OUTER]], label [[EXIT_LOOPEXIT1:%.*]] ; CHECK: exit.loopexit: ; CHECK-NEXT: br label [[EXIT:%.*]] Index: llvm/test/Transforms/IndVarSimplify/lftr-pr20680.ll =================================================================== --- llvm/test/Transforms/IndVarSimplify/lftr-pr20680.ll +++ llvm/test/Transforms/IndVarSimplify/lftr-pr20680.ll @@ -145,7 +145,7 @@ ; CHECK-NEXT: br label [[FOR_INC13]] ; CHECK: for.inc13: ; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i32 [[INDVARS_IV]], 1 -; CHECK-NEXT: [[EXITCOND4:%.*]] = icmp ne i32 [[INDVARS_IV_NEXT]], 0 +; CHECK-NEXT: [[EXITCOND4:%.*]] = icmp ne i32 [[INDVARS_IV]], -1 ; CHECK-NEXT: br i1 [[EXITCOND4]], label [[FOR_COND2_PREHEADER]], label [[FOR_END15:%.*]] ; CHECK: for.end15: ; CHECK-NEXT: ret void Index: llvm/test/Transforms/IndVarSimplify/lftr-pr31181.ll =================================================================== --- llvm/test/Transforms/IndVarSimplify/lftr-pr31181.ll +++ llvm/test/Transforms/IndVarSimplify/lftr-pr31181.ll @@ -16,7 +16,7 @@ ; CHECK-NEXT: [[STOREMERGE:%.*]] = phi i32 [ -2, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[LOOP]] ] ; CHECK-NEXT: store i32 [[STOREMERGE]], i32* @a ; CHECK-NEXT: [[INC]] = add nsw i32 [[STOREMERGE]], 1 -; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[INC]], 0 +; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[STOREMERGE]], -1 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]] ; CHECK: exit: ; CHECK-NEXT: ret i32 0 @@ -43,7 +43,7 @@ ; CHECK-NEXT: [[STOREMERGE:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[LOOP]] ] ; CHECK-NEXT: store i32 [[STOREMERGE]], i32* @a ; CHECK-NEXT: [[INC]] = add nuw i32 [[STOREMERGE]], 1 -; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[INC]], -2147483648 +; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[STOREMERGE]], 2147483647 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]] ; CHECK: exit: ; CHECK-NEXT: ret i32 0 @@ -70,7 +70,7 @@ ; CHECK-NEXT: [[STOREMERGE:%.*]] = phi i32 [ -3, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[LOOP]] ] ; CHECK-NEXT: store i32 [[STOREMERGE]], i32* @a ; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[STOREMERGE]], 1 -; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[INC]], -1 +; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[STOREMERGE]], -2 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]] ; CHECK: exit: ; CHECK-NEXT: ret i32 0 @@ -98,7 +98,7 @@ ; 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: [[EXITCOND:%.*]] = icmp ne i32 [[INC]], 2147483647 +; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[STOREMERGE]], 2147483646 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]] ; CHECK: exit: ; CHECK-NEXT: ret i32 0 @@ -125,7 +125,7 @@ ; CHECK-NEXT: [[STOREMERGE:%.*]] = phi i32 [ -1, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[LOOP]] ] ; CHECK-NEXT: store i32 [[STOREMERGE]], i32* @a ; CHECK-NEXT: [[INC]] = add nsw i32 [[STOREMERGE]], 1 -; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[INC]], 10 +; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[STOREMERGE]], 9 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]] ; CHECK: exit: ; CHECK-NEXT: ret i32 0 @@ -150,13 +150,12 @@ ; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[LIM:%.*]], -1 ; CHECK-NEXT: br i1 [[C]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]] ; CHECK: loop.preheader: -; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[LIM]], 1 ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: ; CHECK-NEXT: [[STOREMERGE:%.*]] = phi i32 [ [[INC:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] ; CHECK-NEXT: store i32 [[STOREMERGE]], i32* @a ; CHECK-NEXT: [[INC]] = add nuw i32 [[STOREMERGE]], 1 -; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[INC]], [[TMP0]] +; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[STOREMERGE]], [[LIM]] ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] ; CHECK: exit.loopexit: ; CHECK-NEXT: br label [[EXIT]] @@ -195,7 +194,7 @@ ; CHECK: always_taken: ; CHECK-NEXT: [[IV_INC]] = add nsw i32 [[IV]], 1 ; CHECK-NEXT: [[IV2_INC]] = add nuw i32 [[IV2]], 1 -; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[IV2_INC]], -2147483627 +; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[IV2]], -2147483628 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_COND]], label [[FOR_END:%.*]] ; CHECK: for.end: ; CHECK-NEXT: ret i32 0 @@ -288,7 +287,7 @@ ; CHECK: always_taken: ; CHECK-NEXT: [[IV2_INC]] = add nuw nsw i32 [[IV2]], 1 ; CHECK-NEXT: [[IV_INC]] = add nsw i32 [[IV]], 1 -; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[IV2_INC]], -2147483628 +; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[IV2]], -2147483629 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_COND]], label [[FOR_END:%.*]] ; CHECK: for.end: ; CHECK-NEXT: ret i32 0 @@ -331,7 +330,7 @@ ; CHECK: always_taken: ; CHECK-NEXT: [[IV2_INC]] = add nsw i32 [[IV2]], 1 ; CHECK-NEXT: [[IV_INC]] = add nsw i32 [[IV]], 1 -; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[IV2_INC]], -2147483629 +; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[IV2]], -2147483630 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_COND]], label [[FOR_END:%.*]] ; CHECK: for.end: ; CHECK-NEXT: ret i32 0 Index: llvm/test/Transforms/IndVarSimplify/lftr-pr41998.ll =================================================================== --- llvm/test/Transforms/IndVarSimplify/lftr-pr41998.ll +++ llvm/test/Transforms/IndVarSimplify/lftr-pr41998.ll @@ -7,14 +7,14 @@ ; CHECK-LABEL: @test_int( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[TMP0:%.*]] = trunc i32 [[START:%.*]] to i3 -; CHECK-NEXT: [[TMP1:%.*]] = sub i3 0, [[TMP0]] +; CHECK-NEXT: [[TMP1:%.*]] = sub i3 -1, [[TMP0]] +; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i3 [[TMP1]] to i32 ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: ; CHECK-NEXT: [[I2:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I2_INC:%.*]], [[LOOP]] ] ; CHECK-NEXT: [[I2_INC]] = add nuw nsw i32 [[I2]], 1 ; CHECK-NEXT: store volatile i32 [[I2_INC]], i32* [[P:%.*]] -; CHECK-NEXT: [[LFTR_WIDEIV:%.*]] = trunc i32 [[I2_INC]] to i3 -; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i3 [[LFTR_WIDEIV]], [[TMP1]] +; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i32 [[I2]], [[WIDE_TRIP_COUNT]] ; CHECK-NEXT: br i1 [[EXITCOND]], label [[END:%.*]], label [[LOOP]] ; CHECK: end: ; CHECK-NEXT: ret void @@ -44,14 +44,13 @@ ; CHECK-NEXT: [[TMP0:%.*]] = trunc i32 [[START:%.*]] to i3 ; CHECK-NEXT: [[TMP1:%.*]] = sub i3 -1, [[TMP0]] ; CHECK-NEXT: [[TMP2:%.*]] = zext i3 [[TMP1]] to i64 -; CHECK-NEXT: [[TMP3:%.*]] = add nuw nsw i64 [[TMP2]], 1 -; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr [256 x i8], [256 x i8]* @data, i64 0, i64 [[TMP3]] +; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr [256 x i8], [256 x i8]* @data, i64 0, i64 [[TMP2]] ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: ; CHECK-NEXT: [[P:%.*]] = phi i8* [ getelementptr inbounds ([256 x i8], [256 x i8]* @data, i64 0, i64 0), [[ENTRY:%.*]] ], [ [[P_INC:%.*]], [[LOOP]] ] ; CHECK-NEXT: [[P_INC]] = getelementptr inbounds i8, i8* [[P]], i64 1 ; CHECK-NEXT: store volatile i8 0, i8* [[P_INC]] -; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i8* [[P_INC]], [[SCEVGEP]] +; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i8* [[P]], [[SCEVGEP]] ; CHECK-NEXT: br i1 [[EXITCOND]], label [[END:%.*]], label [[LOOP]] ; CHECK: end: ; CHECK-NEXT: ret void Index: llvm/test/Transforms/IndVarSimplify/lftr.ll =================================================================== --- llvm/test/Transforms/IndVarSimplify/lftr.ll +++ llvm/test/Transforms/IndVarSimplify/lftr.ll @@ -15,7 +15,7 @@ ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ] ; CHECK-NEXT: [[I_NEXT]] = add nuw nsw i32 [[I]], 1 ; CHECK-NEXT: store i32 [[I]], i32* @A -; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[I_NEXT]], 1001 +; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[I]], 1000 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOPEXIT:%.*]] ; CHECK: loopexit: ; CHECK-NEXT: ret i32 1000 @@ -74,7 +74,7 @@ ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 7, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ] ; CHECK-NEXT: [[I_NEXT]] = add nuw nsw i32 [[I]], 1 ; CHECK-NEXT: store i32 [[I]], i32* @A -; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[I_NEXT]], 33 +; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[I]], 32 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOPEXIT:%.*]] ; CHECK: loopexit: ; CHECK-NEXT: ret i32 32 @@ -104,7 +104,7 @@ ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 7, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ] ; CHECK-NEXT: [[I_NEXT]] = add nuw nsw i32 [[I]], 1 ; CHECK-NEXT: store i32 [[I]], i32* @A -; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[I_NEXT]], 33 +; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[I]], 32 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOPEXIT:%.*]] ; CHECK: loopexit: ; CHECK-NEXT: ret i32 32 @@ -133,7 +133,7 @@ ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 7, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ] ; CHECK-NEXT: [[I_NEXT]] = add nuw nsw i32 [[I]], 1 ; CHECK-NEXT: store i32 [[I]], i32* @A -; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[I_NEXT]], 33 +; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[I]], 32 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOPEXIT:%.*]] ; CHECK: loopexit: ; CHECK-NEXT: ret i32 32 @@ -202,13 +202,12 @@ ; CHECK: loop.preheader: ; CHECK-NEXT: [[TMP0:%.*]] = add i8 [[N]], 3 ; CHECK-NEXT: [[TMP1:%.*]] = lshr i8 [[TMP0]], 2 -; CHECK-NEXT: [[TMP2:%.*]] = add nuw nsw i8 [[TMP1]], 1 ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: ; CHECK-NEXT: [[I1:%.*]] = phi i8 [ [[I1_INC:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ] ; CHECK-NEXT: [[I1_INC]] = add nuw nsw i8 [[I1]], 1 ; CHECK-NEXT: store volatile i8 0, i8* [[A:%.*]] -; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i8 [[I1_INC]], [[TMP2]] +; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i8 [[I1]], [[TMP1]] ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] ; CHECK: exit.loopexit: ; CHECK-NEXT: br label [[EXIT]] @@ -368,10 +367,11 @@ define void @wide_trip_count_test1(float* %autoc, ; CHECK-LABEL: @wide_trip_count_test1( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[DATA_LEN:%.*]], [[SAMPLE:%.*]] -; CHECK-NEXT: [[CMP4:%.*]] = icmp eq i32 [[DATA_LEN]], [[SAMPLE]] +; CHECK-NEXT: [[CMP4:%.*]] = icmp eq i32 [[DATA_LEN:%.*]], [[SAMPLE:%.*]] ; CHECK-NEXT: br i1 [[CMP4]], label [[FOR_END:%.*]], label [[FOR_BODY_PREHEADER:%.*]] ; CHECK: for.body.preheader: +; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[DATA_LEN]], -1 +; CHECK-NEXT: [[TMP1:%.*]] = sub i32 [[TMP0]], [[SAMPLE]] ; CHECK-NEXT: br label [[FOR_BODY:%.*]] ; CHECK: for.body: ; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 68719476736, [[FOR_BODY_PREHEADER]] ] @@ -386,8 +386,8 @@ ; CHECK-NEXT: [[ADD3:%.*]] = fadd float [[TEMP2]], [[MUL]] ; CHECK-NEXT: store float [[ADD3]], float* [[ARRAYIDX2]], align 4 ; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 -; CHECK-NEXT: [[LFTR_WIDEIV:%.*]] = trunc i64 [[INDVARS_IV_NEXT]] to i32 -; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[LFTR_WIDEIV]], [[SUB]] +; CHECK-NEXT: [[LFTR_WIDEIV:%.*]] = trunc i64 [[INDVARS_IV]] to i32 +; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[LFTR_WIDEIV]], [[TMP1]] ; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY]], label [[FOR_END_LOOPEXIT:%.*]] ; CHECK: for.end.loopexit: ; CHECK-NEXT: br label [[FOR_END]]