diff --git a/llvm/include/llvm/Analysis/ScalarEvolution.h b/llvm/include/llvm/Analysis/ScalarEvolution.h index 2765f1286d8bc..234c05f48d8ed 100644 --- a/llvm/include/llvm/Analysis/ScalarEvolution.h +++ b/llvm/include/llvm/Analysis/ScalarEvolution.h @@ -1942,7 +1942,9 @@ class ScalarEvolution { /// true. Utility function used by isImpliedCondOperands. Tries to get /// cases like "X `sgt` 0 => X - 1 `sgt` -1". bool isImpliedCondOperandsViaRanges(ICmpInst::Predicate Pred, const SCEV *LHS, - const SCEV *RHS, const SCEV *FoundLHS, + const SCEV *RHS, + ICmpInst::Predicate FoundPred, + const SCEV *FoundLHS, const SCEV *FoundRHS); /// Return true if the condition denoted by \p LHS \p Pred \p RHS is implied diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp index 3a3d41dac7857..a8b22e18acd42 100644 --- a/llvm/lib/Analysis/ScalarEvolution.cpp +++ b/llvm/lib/Analysis/ScalarEvolution.cpp @@ -11753,6 +11753,9 @@ bool ScalarEvolution::isImpliedCondBalancedTypes( if (isImpliedCondOperands(FoundPred, LHS, RHS, FoundLHS, FoundRHS, CtxI)) return true; + if (isImpliedCondOperandsViaRanges(Pred, LHS, RHS, FoundPred, FoundLHS, FoundRHS)) + return true; + // Otherwise assume the worst. return false; } @@ -12010,7 +12013,7 @@ bool ScalarEvolution::isImpliedViaMerge(ICmpInst::Predicate Pred, auto ProvedEasily = [&](const SCEV *S1, const SCEV *S2) { return isKnownViaNonRecursiveReasoning(Pred, S1, S2) || - isImpliedCondOperandsViaRanges(Pred, S1, S2, FoundLHS, FoundRHS) || + isImpliedCondOperandsViaRanges(Pred, S1, S2, Pred, FoundLHS, FoundRHS) || isImpliedViaOperations(Pred, S1, S2, FoundLHS, FoundRHS, Depth); }; @@ -12112,7 +12115,7 @@ bool ScalarEvolution::isImpliedCondOperands(ICmpInst::Predicate Pred, const SCEV *FoundLHS, const SCEV *FoundRHS, const Instruction *CtxI) { - if (isImpliedCondOperandsViaRanges(Pred, LHS, RHS, FoundLHS, FoundRHS)) + if (isImpliedCondOperandsViaRanges(Pred, LHS, RHS, Pred, FoundLHS, FoundRHS)) return true; if (isImpliedCondOperandsViaNoOverflow(Pred, LHS, RHS, FoundLHS, FoundRHS)) @@ -12464,6 +12467,7 @@ ScalarEvolution::isImpliedCondOperandsHelper(ICmpInst::Predicate Pred, bool ScalarEvolution::isImpliedCondOperandsViaRanges(ICmpInst::Predicate Pred, const SCEV *LHS, const SCEV *RHS, + ICmpInst::Predicate FoundPred, const SCEV *FoundLHS, const SCEV *FoundRHS) { if (!isa(RHS) || !isa(FoundRHS)) @@ -12478,9 +12482,9 @@ bool ScalarEvolution::isImpliedCondOperandsViaRanges(ICmpInst::Predicate Pred, const APInt &ConstFoundRHS = cast(FoundRHS)->getAPInt(); // `FoundLHSRange` is the range we know `FoundLHS` to be in by virtue of the - // antecedent "`FoundLHS` `Pred` `FoundRHS`". + // antecedent "`FoundLHS` `FoundPred` `FoundRHS`". ConstantRange FoundLHSRange = - ConstantRange::makeExactICmpRegion(Pred, ConstFoundRHS); + ConstantRange::makeExactICmpRegion(FoundPred, ConstFoundRHS); // Since `LHS` is `FoundLHS` + `Addend`, we can compute a range for `LHS`: ConstantRange LHSRange = FoundLHSRange.add(ConstantRange(*Addend)); diff --git a/llvm/test/Analysis/ScalarEvolution/trip-count-negative-stride.ll b/llvm/test/Analysis/ScalarEvolution/trip-count-negative-stride.ll index 710f47649b1db..f43dfe35d39bf 100644 --- a/llvm/test/Analysis/ScalarEvolution/trip-count-negative-stride.ll +++ b/llvm/test/Analysis/ScalarEvolution/trip-count-negative-stride.ll @@ -601,10 +601,10 @@ declare void @llvm.assume(i1) define void @step_is_neg_addrec_slt_8(i64 %n) { ; CHECK-LABEL: 'step_is_neg_addrec_slt_8' ; CHECK-NEXT: Determining loop execution counts for: @step_is_neg_addrec_slt_8 -; CHECK-NEXT: Loop %inner: backedge-taken count is (7 /u {0,+,-1}<%outer.header>) +; CHECK-NEXT: Loop %inner: backedge-taken count is (7 /u {0,+,-1}<%outer.header>) ; CHECK-NEXT: Loop %inner: constant max backedge-taken count is 8 -; CHECK-NEXT: Loop %inner: symbolic max backedge-taken count is (7 /u {0,+,-1}<%outer.header>) -; CHECK-NEXT: Loop %inner: Predicated backedge-taken count is (7 /u {0,+,-1}<%outer.header>) +; CHECK-NEXT: Loop %inner: symbolic max backedge-taken count is (7 /u {0,+,-1}<%outer.header>) +; CHECK-NEXT: Loop %inner: Predicated backedge-taken count is (7 /u {0,+,-1}<%outer.header>) ; CHECK-NEXT: Predicates: ; CHECK-NEXT: Loop %inner: Trip multiple is 1 ; CHECK-NEXT: Loop %outer.header: backedge-taken count is 0 diff --git a/llvm/test/CodeGen/BPF/loop-exit-cond.ll b/llvm/test/CodeGen/BPF/loop-exit-cond.ll index a134ed1f7ebcd..7666d961753ac 100644 --- a/llvm/test/CodeGen/BPF/loop-exit-cond.ll +++ b/llvm/test/CodeGen/BPF/loop-exit-cond.ll @@ -44,8 +44,8 @@ define dso_local i32 @test(i32 %len, ptr %data) #0 { ; CHECK-NEXT: call void @foo(ptr nonnull @.str, i32 [[I_05]], ptr nonnull [[D]]) #[[ATTR3]] ; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 8, ptr nonnull [[D]]) #[[ATTR3]] ; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I_05]], 1 -; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[INC]], [[LEN]] -; CHECK-NEXT: br i1 [[CMP1]], label [[FOR_BODY]], label [[IF_END]], !llvm.loop [[LOOP8:![0-9]+]] +; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i32 [[INC]], [[LEN]] +; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[IF_END]], label [[FOR_BODY]], !llvm.loop [[LOOP8:![0-9]+]] ; CHECK: if.end: ; CHECK-NEXT: ret i32 0 ; diff --git a/llvm/test/Transforms/HardwareLoops/ARM/fp-emulation.ll b/llvm/test/Transforms/HardwareLoops/ARM/fp-emulation.ll index 51fa9158f7619..01adc37ba5318 100644 --- a/llvm/test/Transforms/HardwareLoops/ARM/fp-emulation.ll +++ b/llvm/test/Transforms/HardwareLoops/ARM/fp-emulation.ll @@ -8,12 +8,11 @@ define void @test_fptosi(i32 %n, ptr %g, ptr %d) { ; CHECK-FP-NEXT: entry: ; CHECK-FP-NEXT: [[N_OFF:%.*]] = add i32 [[N]], -1 ; CHECK-FP-NEXT: [[TMP0:%.*]] = icmp ult i32 [[N_OFF]], 500 -; CHECK-FP-NEXT: [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[N]], i32 1) ; CHECK-FP-NEXT: br i1 [[TMP0]], label [[WHILE_BODY_LR_PH:%.*]], label [[CLEANUP:%.*]] ; CHECK-FP: while.body.lr.ph: ; CHECK-FP-NEXT: [[TMP1:%.*]] = load ptr, ptr [[D]], align 4 ; CHECK-FP-NEXT: [[TMP2:%.*]] = load ptr, ptr [[G]], align 4 -; CHECK-FP-NEXT: [[TMP3:%.*]] = call i32 @llvm.start.loop.iterations.i32(i32 [[UMAX]]) +; CHECK-FP-NEXT: [[TMP3:%.*]] = call i32 @llvm.start.loop.iterations.i32(i32 [[N]]) ; CHECK-FP-NEXT: br label [[WHILE_BODY:%.*]] ; CHECK-FP: while.body: ; CHECK-FP-NEXT: [[I_012:%.*]] = phi i32 [ 0, [[WHILE_BODY_LR_PH]] ], [ [[INC:%.*]], [[IF_END4:%.*]] ] @@ -111,12 +110,11 @@ define void @test_fptoui(i32 %n, ptr %g, ptr %d) { ; CHECK-FP-NEXT: entry: ; CHECK-FP-NEXT: [[N_OFF:%.*]] = add i32 [[N]], -1 ; CHECK-FP-NEXT: [[TMP0:%.*]] = icmp ult i32 [[N_OFF]], 500 -; CHECK-FP-NEXT: [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[N]], i32 1) ; CHECK-FP-NEXT: br i1 [[TMP0]], label [[WHILE_BODY_LR_PH:%.*]], label [[CLEANUP:%.*]] ; CHECK-FP: while.body.lr.ph: ; CHECK-FP-NEXT: [[TMP1:%.*]] = load ptr, ptr [[D]], align 4 ; CHECK-FP-NEXT: [[TMP2:%.*]] = load ptr, ptr [[G]], align 4 -; CHECK-FP-NEXT: [[TMP3:%.*]] = call i32 @llvm.start.loop.iterations.i32(i32 [[UMAX]]) +; CHECK-FP-NEXT: [[TMP3:%.*]] = call i32 @llvm.start.loop.iterations.i32(i32 [[N]]) ; CHECK-FP-NEXT: br label [[WHILE_BODY:%.*]] ; CHECK-FP: while.body: ; CHECK-FP-NEXT: [[I_012:%.*]] = phi i32 [ 0, [[WHILE_BODY_LR_PH]] ], [ [[INC:%.*]], [[IF_END4:%.*]] ] @@ -214,12 +212,11 @@ define void @load_store_float(i32 %n, ptr %d, ptr %g) { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[N_OFF:%.*]] = add i32 [[N]], -1 ; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[N_OFF]], 500 -; CHECK-NEXT: [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[N]], i32 1) ; CHECK-NEXT: br i1 [[TMP0]], label [[WHILE_BODY_LR_PH:%.*]], label [[CLEANUP:%.*]] ; CHECK: while.body.lr.ph: ; CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[D]], align 4 ; CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[G]], align 4 -; CHECK-NEXT: [[TMP3:%.*]] = call i32 @llvm.start.loop.iterations.i32(i32 [[UMAX]]) +; CHECK-NEXT: [[TMP3:%.*]] = call i32 @llvm.start.loop.iterations.i32(i32 [[N]]) ; CHECK-NEXT: br label [[WHILE_BODY:%.*]] ; CHECK: while.body: ; CHECK-NEXT: [[I_012:%.*]] = phi i32 [ 0, [[WHILE_BODY_LR_PH]] ], [ [[INC:%.*]], [[IF_END4:%.*]] ] @@ -284,12 +281,11 @@ define void @fp_add(i32 %n, ptr %d, ptr %g) { ; CHECK-FP-NEXT: entry: ; CHECK-FP-NEXT: [[N_OFF:%.*]] = add i32 [[N]], -1 ; CHECK-FP-NEXT: [[TMP0:%.*]] = icmp ult i32 [[N_OFF]], 500 -; CHECK-FP-NEXT: [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[N]], i32 1) ; CHECK-FP-NEXT: br i1 [[TMP0]], label [[WHILE_BODY_LR_PH:%.*]], label [[CLEANUP:%.*]] ; CHECK-FP: while.body.lr.ph: ; CHECK-FP-NEXT: [[TMP1:%.*]] = load ptr, ptr [[D]], align 4 ; CHECK-FP-NEXT: [[TMP2:%.*]] = load ptr, ptr [[G]], align 4 -; CHECK-FP-NEXT: [[TMP3:%.*]] = call i32 @llvm.start.loop.iterations.i32(i32 [[UMAX]]) +; CHECK-FP-NEXT: [[TMP3:%.*]] = call i32 @llvm.start.loop.iterations.i32(i32 [[N]]) ; CHECK-FP-NEXT: br label [[WHILE_BODY:%.*]] ; CHECK-FP: while.body: ; CHECK-FP-NEXT: [[I_012:%.*]] = phi i32 [ 0, [[WHILE_BODY_LR_PH]] ], [ [[INC:%.*]], [[IF_END4:%.*]] ] diff --git a/llvm/test/Transforms/IRCE/variable-loop-bounds.ll b/llvm/test/Transforms/IRCE/variable-loop-bounds.ll index 43d450b938afe..a46bb0f570846 100644 --- a/llvm/test/Transforms/IRCE/variable-loop-bounds.ll +++ b/llvm/test/Transforms/IRCE/variable-loop-bounds.ll @@ -942,7 +942,6 @@ for.inc: ; preds = %for.body, %if.else br i1 %cmp, label %for.body, label %for.cond.cleanup } -;; Negative test define void @signed_var_imm_dec_eq(ptr nocapture %a, ptr nocapture readonly %b, ptr nocapture readonly %c, i32 %M) { ; CHECK-LABEL: define void @signed_var_imm_dec_eq( ; CHECK-SAME: ptr nocapture [[A:%.*]], ptr nocapture readonly [[B:%.*]], ptr nocapture readonly [[C:%.*]], i32 [[M:%.*]]) { @@ -950,31 +949,108 @@ define void @signed_var_imm_dec_eq(ptr nocapture %a, ptr nocapture readonly %b, ; CHECK-NEXT: [[CMP14:%.*]] = icmp slt i32 [[M]], 1024 ; CHECK-NEXT: br i1 [[CMP14]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_COND_CLEANUP:%.*]] ; CHECK: for.body.preheader: -; CHECK-NEXT: br label [[FOR_BODY:%.*]] +; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[M]], 1 +; CHECK-NEXT: [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[TMP0]], i32 1024) +; CHECK-NEXT: [[EXIT_PRELOOP_AT:%.*]] = add nsw i32 [[SMAX]], -1 +; CHECK-NEXT: [[SMAX1:%.*]] = call i32 @llvm.smax.i32(i32 [[TMP0]], i32 0) +; CHECK-NEXT: [[EXIT_MAINLOOP_AT:%.*]] = add nsw i32 [[SMAX1]], -1 +; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 1024, [[EXIT_PRELOOP_AT]] +; CHECK-NEXT: br i1 [[TMP1]], label [[FOR_BODY_PRELOOP_PREHEADER:%.*]], label [[PRELOOP_PSEUDO_EXIT:%.*]] +; CHECK: for.body.preloop.preheader: +; CHECK-NEXT: br label [[FOR_BODY_PRELOOP:%.*]] +; CHECK: for.cond.cleanup.loopexit.loopexit: +; CHECK-NEXT: br label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]] ; CHECK: for.cond.cleanup.loopexit: ; CHECK-NEXT: br label [[FOR_COND_CLEANUP]] ; CHECK: for.cond.cleanup: ; CHECK-NEXT: ret void +; CHECK: mainloop: +; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[INDVAR_END:%.*]], [[EXIT_MAINLOOP_AT]] +; CHECK-NEXT: br i1 [[TMP2]], label [[FOR_BODY_PREHEADER3:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]] +; CHECK: for.body.preheader3: +; CHECK-NEXT: br label [[FOR_BODY:%.*]] ; CHECK: for.body: -; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[DEC:%.*]], [[FOR_INC:%.*]] ], [ 1024, [[FOR_BODY_PREHEADER]] ] +; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[DEC:%.*]], [[FOR_INC:%.*]] ], [ [[IV_PRELOOP_COPY:%.*]], [[FOR_BODY_PREHEADER3]] ] ; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[IV]], 1024 ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[IV]] -; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 4 +; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[ARRAYIDX]], align 4 ; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[IV]] -; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX2]], align 4 -; CHECK-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP1]], [[TMP0]] +; CHECK-NEXT: [[TMP4:%.*]] = load i32, ptr [[ARRAYIDX2]], align 4 +; CHECK-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP4]], [[TMP3]] ; CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[IV]] -; CHECK-NEXT: br i1 [[CMP1]], label [[FOR_INC]], label [[IF_ELSE:%.*]] +; CHECK-NEXT: br i1 true, label [[FOR_INC]], label [[IF_ELSE:%.*]] ; CHECK: if.else: -; CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX3]], align 4 -; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP2]], [[MUL]] +; CHECK-NEXT: [[TMP5:%.*]] = load i32, ptr [[ARRAYIDX3]], align 4 +; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP5]], [[MUL]] ; CHECK-NEXT: br label [[FOR_INC]] ; CHECK: for.inc: ; CHECK-NEXT: [[STOREMERGE:%.*]] = phi i32 [ [[ADD]], [[IF_ELSE]] ], [ [[MUL]], [[FOR_BODY]] ] ; CHECK-NEXT: store i32 [[STOREMERGE]], ptr [[ARRAYIDX3]], align 4 ; CHECK-NEXT: [[DEC]] = add nsw i32 [[IV]], -1 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[DEC]], [[M]] -; CHECK-NEXT: br i1 [[CMP]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]], label [[FOR_BODY]] +; CHECK-NEXT: [[TMP6:%.*]] = icmp sgt i32 [[DEC]], [[EXIT_MAINLOOP_AT]] +; CHECK-NEXT: [[TMP7:%.*]] = xor i1 [[TMP6]], true +; CHECK-NEXT: br i1 [[TMP7]], label [[MAIN_EXIT_SELECTOR:%.*]], label [[FOR_BODY]] +; CHECK: main.exit.selector: +; CHECK-NEXT: [[DEC_LCSSA:%.*]] = phi i32 [ [[DEC]], [[FOR_INC]] ] +; CHECK-NEXT: [[TMP8:%.*]] = icmp sgt i32 [[DEC_LCSSA]], [[M]] +; CHECK-NEXT: br i1 [[TMP8]], label [[MAIN_PSEUDO_EXIT]], label [[FOR_COND_CLEANUP_LOOPEXIT]] +; CHECK: main.pseudo.exit: +; CHECK-NEXT: [[IV_COPY:%.*]] = phi i32 [ [[IV_PRELOOP_COPY]], [[MAINLOOP:%.*]] ], [ [[DEC_LCSSA]], [[MAIN_EXIT_SELECTOR]] ] +; CHECK-NEXT: [[INDVAR_END2:%.*]] = phi i32 [ [[INDVAR_END]], [[MAINLOOP]] ], [ [[DEC_LCSSA]], [[MAIN_EXIT_SELECTOR]] ] +; CHECK-NEXT: br label [[POSTLOOP:%.*]] +; CHECK: for.body.preloop: +; CHECK-NEXT: [[IV_PRELOOP:%.*]] = phi i32 [ [[DEC_PRELOOP:%.*]], [[FOR_INC_PRELOOP:%.*]] ], [ 1024, [[FOR_BODY_PRELOOP_PREHEADER]] ] +; CHECK-NEXT: [[CMP1_PRELOOP:%.*]] = icmp slt i32 [[IV_PRELOOP]], 1024 +; CHECK-NEXT: [[ARRAYIDX_PRELOOP:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[IV_PRELOOP]] +; CHECK-NEXT: [[TMP9:%.*]] = load i32, ptr [[ARRAYIDX_PRELOOP]], align 4 +; CHECK-NEXT: [[ARRAYIDX2_PRELOOP:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[IV_PRELOOP]] +; CHECK-NEXT: [[TMP10:%.*]] = load i32, ptr [[ARRAYIDX2_PRELOOP]], align 4 +; CHECK-NEXT: [[MUL_PRELOOP:%.*]] = mul nsw i32 [[TMP10]], [[TMP9]] +; CHECK-NEXT: [[ARRAYIDX3_PRELOOP:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[IV_PRELOOP]] +; CHECK-NEXT: br i1 [[CMP1_PRELOOP]], label [[FOR_INC_PRELOOP]], label [[IF_ELSE_PRELOOP:%.*]] +; CHECK: if.else.preloop: +; CHECK-NEXT: [[TMP11:%.*]] = load i32, ptr [[ARRAYIDX3_PRELOOP]], align 4 +; CHECK-NEXT: [[ADD_PRELOOP:%.*]] = add nsw i32 [[TMP11]], [[MUL_PRELOOP]] +; CHECK-NEXT: br label [[FOR_INC_PRELOOP]] +; CHECK: for.inc.preloop: +; CHECK-NEXT: [[STOREMERGE_PRELOOP:%.*]] = phi i32 [ [[ADD_PRELOOP]], [[IF_ELSE_PRELOOP]] ], [ [[MUL_PRELOOP]], [[FOR_BODY_PRELOOP]] ] +; CHECK-NEXT: store i32 [[STOREMERGE_PRELOOP]], ptr [[ARRAYIDX3_PRELOOP]], align 4 +; CHECK-NEXT: [[DEC_PRELOOP]] = add nsw i32 [[IV_PRELOOP]], -1 +; CHECK-NEXT: [[CMP_PRELOOP:%.*]] = icmp eq i32 [[DEC_PRELOOP]], [[M]] +; CHECK-NEXT: [[TMP12:%.*]] = icmp sgt i32 [[DEC_PRELOOP]], [[EXIT_PRELOOP_AT]] +; CHECK-NEXT: [[TMP13:%.*]] = xor i1 [[TMP12]], true +; CHECK-NEXT: br i1 [[TMP13]], label [[PRELOOP_EXIT_SELECTOR:%.*]], label [[FOR_BODY_PRELOOP]], !llvm.loop [[LOOP15:![0-9]+]], !loop_constrainer.loop.clone !5 +; CHECK: preloop.exit.selector: +; CHECK-NEXT: [[DEC_PRELOOP_LCSSA:%.*]] = phi i32 [ [[DEC_PRELOOP]], [[FOR_INC_PRELOOP]] ] +; CHECK-NEXT: [[TMP14:%.*]] = icmp sgt i32 [[DEC_PRELOOP_LCSSA]], [[M]] +; CHECK-NEXT: br i1 [[TMP14]], label [[PRELOOP_PSEUDO_EXIT]], label [[FOR_COND_CLEANUP_LOOPEXIT]] +; CHECK: preloop.pseudo.exit: +; CHECK-NEXT: [[IV_PRELOOP_COPY]] = phi i32 [ 1024, [[FOR_BODY_PREHEADER]] ], [ [[DEC_PRELOOP_LCSSA]], [[PRELOOP_EXIT_SELECTOR]] ] +; CHECK-NEXT: [[INDVAR_END]] = phi i32 [ 1024, [[FOR_BODY_PREHEADER]] ], [ [[DEC_PRELOOP_LCSSA]], [[PRELOOP_EXIT_SELECTOR]] ] +; CHECK-NEXT: br label [[MAINLOOP]] +; CHECK: postloop: +; CHECK-NEXT: br label [[FOR_BODY_POSTLOOP:%.*]] +; CHECK: for.body.postloop: +; CHECK-NEXT: [[IV_POSTLOOP:%.*]] = phi i32 [ [[DEC_POSTLOOP:%.*]], [[FOR_INC_POSTLOOP:%.*]] ], [ [[IV_COPY]], [[POSTLOOP]] ] +; CHECK-NEXT: [[CMP1_POSTLOOP:%.*]] = icmp slt i32 [[IV_POSTLOOP]], 1024 +; CHECK-NEXT: [[ARRAYIDX_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[IV_POSTLOOP]] +; CHECK-NEXT: [[TMP15:%.*]] = load i32, ptr [[ARRAYIDX_POSTLOOP]], align 4 +; CHECK-NEXT: [[ARRAYIDX2_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[IV_POSTLOOP]] +; CHECK-NEXT: [[TMP16:%.*]] = load i32, ptr [[ARRAYIDX2_POSTLOOP]], align 4 +; CHECK-NEXT: [[MUL_POSTLOOP:%.*]] = mul nsw i32 [[TMP16]], [[TMP15]] +; CHECK-NEXT: [[ARRAYIDX3_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[IV_POSTLOOP]] +; CHECK-NEXT: br i1 [[CMP1_POSTLOOP]], label [[FOR_INC_POSTLOOP]], label [[IF_ELSE_POSTLOOP:%.*]] +; CHECK: if.else.postloop: +; CHECK-NEXT: [[TMP17:%.*]] = load i32, ptr [[ARRAYIDX3_POSTLOOP]], align 4 +; CHECK-NEXT: [[ADD_POSTLOOP:%.*]] = add nsw i32 [[TMP17]], [[MUL_POSTLOOP]] +; CHECK-NEXT: br label [[FOR_INC_POSTLOOP]] +; CHECK: for.inc.postloop: +; CHECK-NEXT: [[STOREMERGE_POSTLOOP:%.*]] = phi i32 [ [[ADD_POSTLOOP]], [[IF_ELSE_POSTLOOP]] ], [ [[MUL_POSTLOOP]], [[FOR_BODY_POSTLOOP]] ] +; CHECK-NEXT: store i32 [[STOREMERGE_POSTLOOP]], ptr [[ARRAYIDX3_POSTLOOP]], align 4 +; CHECK-NEXT: [[DEC_POSTLOOP]] = add nsw i32 [[IV_POSTLOOP]], -1 +; CHECK-NEXT: [[CMP_POSTLOOP:%.*]] = icmp eq i32 [[DEC_POSTLOOP]], [[M]] +; CHECK-NEXT: br i1 [[CMP_POSTLOOP]], label [[FOR_COND_CLEANUP_LOOPEXIT_LOOPEXIT:%.*]], label [[FOR_BODY_POSTLOOP]], !llvm.loop [[LOOP16:![0-9]+]], !loop_constrainer.loop.clone !5 ; entry: %cmp14 = icmp slt i32 %M, 1024 diff --git a/llvm/test/Transforms/IndVarSimplify/X86/loop-invariant-conditions.ll b/llvm/test/Transforms/IndVarSimplify/X86/loop-invariant-conditions.ll index 4543ec220dbee..24ba862eebc42 100644 --- a/llvm/test/Transforms/IndVarSimplify/X86/loop-invariant-conditions.ll +++ b/llvm/test/Transforms/IndVarSimplify/X86/loop-invariant-conditions.ll @@ -109,8 +109,7 @@ define void @test3(i64 %start) { ; CHECK-NEXT: br i1 [[CMP]], label [[BACKEDGE]], label [[FOR_END:%.*]] ; CHECK: backedge: ; CHECK-NEXT: call void @foo() -; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i64 [[START]], -1 -; CHECK-NEXT: br i1 [[CMP1]], label [[FOR_END]], label [[LOOP]] +; CHECK-NEXT: br i1 false, label [[FOR_END]], label [[LOOP]] ; CHECK: for.end: ; CHECK-NEXT: ret void ; @@ -136,17 +135,15 @@ for.end: ; preds = %if.end, %entry define void @test3.next(i64 %start) { ; CHECK-LABEL: @test3.next( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[TMP0:%.*]] = add nsw i64 [[START:%.*]], 1 ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: -; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[START]], [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ] +; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ] ; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], 25 ; CHECK-NEXT: br i1 [[CMP]], label [[BACKEDGE]], label [[FOR_END:%.*]] ; CHECK: backedge: ; CHECK-NEXT: call void @foo() -; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i64 [[TMP0]], 0 -; CHECK-NEXT: br i1 [[CMP1]], label [[FOR_END]], label [[LOOP]] +; CHECK-NEXT: br i1 false, label [[FOR_END]], label [[LOOP]] ; CHECK: for.end: ; CHECK-NEXT: ret void ; @@ -181,8 +178,7 @@ define void @test4(i64 %start) { ; CHECK-NEXT: br i1 [[CMP]], label [[BACKEDGE]], label [[FOR_END:%.*]] ; CHECK: backedge: ; CHECK-NEXT: call void @foo() -; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i64 [[START]], -1 -; CHECK-NEXT: br i1 [[CMP1]], label [[LOOP]], label [[FOR_END]] +; CHECK-NEXT: br i1 true, label [[LOOP]], label [[FOR_END]] ; CHECK: for.end: ; CHECK-NEXT: ret void ; @@ -208,17 +204,15 @@ for.end: ; preds = %if.end, %entry define void @test4.next(i64 %start) { ; CHECK-LABEL: @test4.next( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[TMP0:%.*]] = add nsw i64 [[START:%.*]], 1 ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: -; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[START]], [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ] +; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ] ; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], 25 ; CHECK-NEXT: br i1 [[CMP]], label [[BACKEDGE]], label [[FOR_END:%.*]] ; CHECK: backedge: ; CHECK-NEXT: call void @foo() -; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i64 [[TMP0]], 0 -; CHECK-NEXT: br i1 [[CMP1]], label [[LOOP]], label [[FOR_END]] +; CHECK-NEXT: br i1 true, label [[LOOP]], label [[FOR_END]] ; CHECK: for.end: ; CHECK-NEXT: ret void ; @@ -246,14 +240,12 @@ define void @test5(i64 %start) { ; CHECK-NEXT: entry: ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: -; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ] -; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw i64 [[INDVARS_IV]], 1 +; CHECK-NEXT: [[INDVARS_IV_NEXT:%.*]] = add nuw i64 [[START:%.*]], 1 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], 25 -; CHECK-NEXT: br i1 [[CMP]], label [[BACKEDGE]], label [[FOR_END:%.*]] +; CHECK-NEXT: br i1 [[CMP]], label [[BACKEDGE:%.*]], label [[FOR_END:%.*]] ; CHECK: backedge: ; CHECK-NEXT: call void @foo() -; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i64 [[START]], 100 -; CHECK-NEXT: br i1 [[CMP1]], label [[LOOP]], label [[FOR_END]] +; CHECK-NEXT: br i1 false, label [[LOOP]], label [[FOR_END]] ; CHECK: for.end: ; CHECK-NEXT: ret void ; @@ -279,17 +271,14 @@ for.end: ; preds = %if.end, %entry define void @test5.next(i64 %start) { ; CHECK-LABEL: @test5.next( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[TMP0:%.*]] = add nuw i64 [[START:%.*]], 1 ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: -; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[START]], [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ] -; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw i64 [[INDVARS_IV]], 1 +; CHECK-NEXT: [[INDVARS_IV_NEXT:%.*]] = add nuw i64 [[START:%.*]], 1 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], 25 -; CHECK-NEXT: br i1 [[CMP]], label [[BACKEDGE]], label [[FOR_END:%.*]] +; CHECK-NEXT: br i1 [[CMP]], label [[BACKEDGE:%.*]], label [[FOR_END:%.*]] ; CHECK: backedge: ; CHECK-NEXT: call void @foo() -; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i64 [[TMP0]], 101 -; CHECK-NEXT: br i1 [[CMP1]], label [[LOOP]], label [[FOR_END]] +; CHECK-NEXT: br i1 false, label [[LOOP]], label [[FOR_END]] ; CHECK: for.end: ; CHECK-NEXT: ret void ; @@ -318,14 +307,12 @@ define void @test6(i64 %start) { ; CHECK-NEXT: entry: ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: -; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ] -; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw i64 [[INDVARS_IV]], 1 +; CHECK-NEXT: [[INDVARS_IV_NEXT:%.*]] = add nuw i64 [[START:%.*]], 1 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], 25 -; CHECK-NEXT: br i1 [[CMP]], label [[BACKEDGE]], label [[FOR_END:%.*]] +; CHECK-NEXT: br i1 [[CMP]], label [[BACKEDGE:%.*]], label [[FOR_END:%.*]] ; CHECK: backedge: ; CHECK-NEXT: call void @foo() -; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i64 [[START]], 100 -; CHECK-NEXT: br i1 [[CMP1]], label [[FOR_END]], label [[LOOP]] +; CHECK-NEXT: br i1 true, label [[FOR_END]], label [[LOOP]] ; CHECK: for.end: ; CHECK-NEXT: ret void ; @@ -351,17 +338,14 @@ for.end: ; preds = %if.end, %entry define void @test6.next(i64 %start) { ; CHECK-LABEL: @test6.next( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[TMP0:%.*]] = add nuw i64 [[START:%.*]], 1 ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: -; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[START]], [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ] -; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw i64 [[INDVARS_IV]], 1 +; CHECK-NEXT: [[INDVARS_IV_NEXT:%.*]] = add nuw i64 [[START:%.*]], 1 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], 25 -; CHECK-NEXT: br i1 [[CMP]], label [[BACKEDGE]], label [[FOR_END:%.*]] +; CHECK-NEXT: br i1 [[CMP]], label [[BACKEDGE:%.*]], label [[FOR_END:%.*]] ; CHECK: backedge: ; CHECK-NEXT: call void @foo() -; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i64 [[TMP0]], 101 -; CHECK-NEXT: br i1 [[CMP1]], label [[FOR_END]], label [[LOOP]] +; CHECK-NEXT: br i1 true, label [[FOR_END]], label [[LOOP]] ; CHECK: for.end: ; CHECK-NEXT: ret void ; @@ -564,14 +548,12 @@ define void @test4_neg(i64 %start) { ; CHECK-NEXT: entry: ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: -; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ] -; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1 +; CHECK-NEXT: [[INDVARS_IV_NEXT:%.*]] = add nsw i64 [[START:%.*]], 1 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], 25 -; CHECK-NEXT: br i1 [[CMP]], label [[BACKEDGE]], label [[FOR_END:%.*]] +; CHECK-NEXT: br i1 [[CMP]], label [[BACKEDGE:%.*]], label [[FOR_END:%.*]] ; CHECK: backedge: ; CHECK-NEXT: call void @foo() -; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i64 [[INDVARS_IV]], -1 -; CHECK-NEXT: br i1 [[CMP1]], label [[FOR_END]], label [[LOOP]] +; CHECK-NEXT: br i1 true, label [[FOR_END]], label [[LOOP]] ; CHECK: for.end: ; CHECK-NEXT: ret void ; diff --git a/llvm/test/Transforms/IndVarSimplify/canonicalize-cmp.ll b/llvm/test/Transforms/IndVarSimplify/canonicalize-cmp.ll index 2c479a711a3c5..943d1d7f7aaaa 100644 --- a/llvm/test/Transforms/IndVarSimplify/canonicalize-cmp.ll +++ b/llvm/test/Transforms/IndVarSimplify/canonicalize-cmp.ll @@ -150,7 +150,7 @@ define i32 @test_03(ptr %p, ptr %capacity_p, ptr %num_elements_p) { ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ] -; CHECK-NEXT: [[BYTES_TO_WRITE:%.*]] = sub nsw i32 [[CAPACITY]], [[IV]] +; CHECK-NEXT: [[BYTES_TO_WRITE:%.*]] = sub nuw nsw i32 [[CAPACITY]], [[IV]] ; CHECK-NEXT: [[CAPACITY_CHECK:%.*]] = icmp slt i32 [[BYTES_TO_WRITE]], 4 ; CHECK-NEXT: br i1 [[CAPACITY_CHECK]], label [[OUT_OF_BOUNDS:%.*]], label [[BACKEDGE]] ; CHECK: backedge: @@ -198,7 +198,7 @@ define i32 @test_04(ptr %p, ptr %capacity_p, ptr %num_elements_p) { ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ] -; CHECK-NEXT: [[BYTES_TO_WRITE:%.*]] = sub nsw i32 [[CAPACITY]], [[IV]] +; CHECK-NEXT: [[BYTES_TO_WRITE:%.*]] = sub nuw nsw i32 [[CAPACITY]], [[IV]] ; CHECK-NEXT: [[CAPACITY_CHECK:%.*]] = icmp sle i32 [[BYTES_TO_WRITE]], 3 ; CHECK-NEXT: br i1 [[CAPACITY_CHECK]], label [[OUT_OF_BOUNDS:%.*]], label [[BACKEDGE]] ; CHECK: backedge: diff --git a/llvm/test/Transforms/IndVarSimplify/strengthen-overflow.ll b/llvm/test/Transforms/IndVarSimplify/strengthen-overflow.ll index afa4f2ee32b24..2fd4032eec23b 100644 --- a/llvm/test/Transforms/IndVarSimplify/strengthen-overflow.ll +++ b/llvm/test/Transforms/IndVarSimplify/strengthen-overflow.ll @@ -304,7 +304,7 @@ define void @test_infer_nsw(ptr %p) { ; CHECK-NEXT: br label [[BB1:%.*]] ; CHECK: bb1: ; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ [[ADD:%.*]], [[BB2:%.*]] ], [ 0, [[BB:%.*]] ] -; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[FREEZE]], [[PHI]] +; CHECK-NEXT: [[SUB:%.*]] = sub nuw nsw i32 [[FREEZE]], [[PHI]] ; CHECK-NEXT: [[ICMP:%.*]] = icmp sgt i32 [[SUB]], 1 ; CHECK-NEXT: br i1 [[ICMP]], label [[BB2]], label [[BB3:%.*]] ; CHECK: bb2: diff --git a/llvm/test/Transforms/IndVarSimplify/trivial-checks.ll b/llvm/test/Transforms/IndVarSimplify/trivial-checks.ll index 415e49768c827..05aba4be5d54f 100644 --- a/llvm/test/Transforms/IndVarSimplify/trivial-checks.ll +++ b/llvm/test/Transforms/IndVarSimplify/trivial-checks.ll @@ -12,11 +12,11 @@ define void @test_sgt(i32 %x) { ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], [[GUARDED:%.*]] ], [ [[X]], [[LOOP_PREHEADER]] ] -; CHECK-NEXT: [[TMP:%.*]] = add i32 [[IV]], 1 +; CHECK-NEXT: [[TMP:%.*]] = add nsw i32 [[IV]], 1 ; CHECK-NEXT: [[GUARD:%.*]] = icmp sgt i32 [[TMP]], [[IV]] ; CHECK-NEXT: br i1 [[GUARD]], label [[GUARDED]], label [[FAIL:%.*]] ; CHECK: guarded: -; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], -1 +; CHECK-NEXT: [[IV_NEXT]] = add nsw i32 [[IV]], -1 ; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[IV]], 0 ; CHECK-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] ; CHECK: exit.loopexit: @@ -57,11 +57,11 @@ define void @test_sge(i32 %x) { ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], [[GUARDED:%.*]] ], [ [[X]], [[LOOP_PREHEADER]] ] -; CHECK-NEXT: [[TMP:%.*]] = add i32 [[IV]], 1 +; CHECK-NEXT: [[TMP:%.*]] = add nsw i32 [[IV]], 1 ; CHECK-NEXT: [[GUARD:%.*]] = icmp sge i32 [[TMP]], [[IV]] ; CHECK-NEXT: br i1 [[GUARD]], label [[GUARDED]], label [[FAIL:%.*]] ; CHECK: guarded: -; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], -1 +; CHECK-NEXT: [[IV_NEXT]] = add nsw i32 [[IV]], -1 ; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[IV]], 0 ; CHECK-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] ; CHECK: exit.loopexit: @@ -102,11 +102,11 @@ define void @test_ugt(i32 %x) { ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], [[GUARDED:%.*]] ], [ [[X]], [[LOOP_PREHEADER]] ] -; CHECK-NEXT: [[TMP:%.*]] = add i32 [[IV]], 1 +; CHECK-NEXT: [[TMP:%.*]] = add nsw i32 [[IV]], 1 ; CHECK-NEXT: [[GUARD:%.*]] = icmp ugt i32 [[TMP]], [[IV]] ; CHECK-NEXT: br i1 [[GUARD]], label [[GUARDED]], label [[FAIL:%.*]] ; CHECK: guarded: -; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], -1 +; CHECK-NEXT: [[IV_NEXT]] = add nsw i32 [[IV]], -1 ; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[IV]], 0 ; CHECK-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] ; CHECK: exit.loopexit: @@ -148,11 +148,11 @@ define void @test_uge(i32 %x) { ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], [[GUARDED:%.*]] ], [ [[X]], [[LOOP_PREHEADER]] ] -; CHECK-NEXT: [[TMP:%.*]] = add i32 [[IV]], 1 +; CHECK-NEXT: [[TMP:%.*]] = add nsw i32 [[IV]], 1 ; CHECK-NEXT: [[GUARD:%.*]] = icmp uge i32 [[TMP]], [[IV]] ; CHECK-NEXT: br i1 [[GUARD]], label [[GUARDED]], label [[FAIL:%.*]] ; CHECK: guarded: -; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], -1 +; CHECK-NEXT: [[IV_NEXT]] = add nsw i32 [[IV]], -1 ; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[IV]], 0 ; CHECK-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] ; CHECK: exit.loopexit: