; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 4 ; RUN: opt < %s -disable-output "-passes=print" -scalar-evolution-classify-expressions=0 2>&1 | FileCheck %s ; ScalarEvolution should be able to compute trip count of the loop by proving ; that this is not an infinite loop with side effects. ; We should have a conservative estimate for the max backedge taken count for ; loops with unknown stride. target datalayout = "e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128" define void @foo1(ptr nocapture %A, i32 %n, i32 %s) mustprogress { ; ; CHECK-LABEL: 'foo1' ; CHECK-NEXT: Determining loop execution counts for: @foo1 ; CHECK-NEXT: Loop %for.body: backedge-taken count is ((-1 + (%n smax %s)) /u %s) ; CHECK-NEXT: Loop %for.body: constant max backedge-taken count is i32 -1 ; CHECK-NEXT: Loop %for.body: symbolic max backedge-taken count is ((-1 + (%n smax %s)) /u %s) ; CHECK-NEXT: Loop %for.body: Trip multiple is 1 ; entry: %cmp4 = icmp sgt i32 %n, 0 br i1 %cmp4, label %for.body, label %for.end for.body: ; preds = %entry, %for.body %i.05 = phi i32 [ %add, %for.body ], [ 0, %entry ] %arrayidx = getelementptr inbounds i32, ptr %A, i32 %i.05 %0 = load i32, ptr %arrayidx, align 4 %inc = add nsw i32 %0, 1 store i32 %inc, ptr %arrayidx, align 4 %add = add nsw i32 %i.05, %s %cmp = icmp slt i32 %add, %n br i1 %cmp, label %for.body, label %for.end for.end: ; preds = %for.body, %entry ret void } ; Check that we are able to compute trip count of a loop without an entry guard. ; We should have a conservative estimate for the max backedge taken count for ; loops with unknown stride. define void @foo2(ptr nocapture %A, i32 %n, i32 %s) mustprogress { ; ; CHECK-LABEL: 'foo2' ; CHECK-NEXT: Determining loop execution counts for: @foo2 ; CHECK-NEXT: Loop %for.body: backedge-taken count is ((((-1 * (1 umin ((-1 * %s) + (%n smax %s)))) + (-1 * %s) + (%n smax %s)) /u (1 umax %s)) + (1 umin ((-1 * %s) + (%n smax %s)))) ; CHECK-NEXT: Loop %for.body: constant max backedge-taken count is i32 -1 ; CHECK-NEXT: Loop %for.body: symbolic max backedge-taken count is ((((-1 * (1 umin ((-1 * %s) + (%n smax %s)))) + (-1 * %s) + (%n smax %s)) /u (1 umax %s)) + (1 umin ((-1 * %s) + (%n smax %s)))) ; CHECK-NEXT: Loop %for.body: Trip multiple is 1 ; entry: br label %for.body for.body: ; preds = %entry, %for.body %i.05 = phi i32 [ %add, %for.body ], [ 0, %entry ] %arrayidx = getelementptr inbounds i32, ptr %A, i32 %i.05 %0 = load i32, ptr %arrayidx, align 4 %inc = add nsw i32 %0, 1 store i32 %inc, ptr %arrayidx, align 4 %add = add nsw i32 %i.05, %s %cmp = icmp slt i32 %add, %n br i1 %cmp, label %for.body, label %for.end for.end: ; preds = %for.body, %entry ret void } ; Check that without mustprogress we don't make assumptions about infinite ; loops being UB. define void @foo3(ptr nocapture %A, i32 %n, i32 %s) { ; ; CHECK-LABEL: 'foo3' ; CHECK-NEXT: Determining loop execution counts for: @foo3 ; CHECK-NEXT: Loop %for.body: Unpredictable backedge-taken count. ; CHECK-NEXT: Loop %for.body: Unpredictable constant max backedge-taken count. ; CHECK-NEXT: Loop %for.body: Unpredictable symbolic max backedge-taken count. ; entry: br label %for.body for.body: ; preds = %entry, %for.body %i.05 = phi i32 [ %add, %for.body ], [ 0, %entry ] %arrayidx = getelementptr inbounds i32, ptr %A, i32 %i.05 %0 = load i32, ptr %arrayidx, align 4 %inc = add nsw i32 %0, 1 store i32 %inc, ptr %arrayidx, align 4 %add = add nsw i32 %i.05, %s %cmp = icmp slt i32 %add, %n br i1 %cmp, label %for.body, label %for.end for.end: ; preds = %for.body, %entry ret void } ; Same as foo2, but with mustprogress on loop, not function define void @foo4(ptr nocapture %A, i32 %n, i32 %s) { ; ; CHECK-LABEL: 'foo4' ; CHECK-NEXT: Determining loop execution counts for: @foo4 ; CHECK-NEXT: Loop %for.body: backedge-taken count is ((((-1 * (1 umin ((-1 * %s) + (%n smax %s)))) + (-1 * %s) + (%n smax %s)) /u (1 umax %s)) + (1 umin ((-1 * %s) + (%n smax %s)))) ; CHECK-NEXT: Loop %for.body: constant max backedge-taken count is i32 -1 ; CHECK-NEXT: Loop %for.body: symbolic max backedge-taken count is ((((-1 * (1 umin ((-1 * %s) + (%n smax %s)))) + (-1 * %s) + (%n smax %s)) /u (1 umax %s)) + (1 umin ((-1 * %s) + (%n smax %s)))) ; CHECK-NEXT: Loop %for.body: Trip multiple is 1 ; entry: br label %for.body for.body: ; preds = %entry, %for.body %i.05 = phi i32 [ %add, %for.body ], [ 0, %entry ] %arrayidx = getelementptr inbounds i32, ptr %A, i32 %i.05 %0 = load i32, ptr %arrayidx, align 4 %inc = add nsw i32 %0, 1 store i32 %inc, ptr %arrayidx, align 4 %add = add nsw i32 %i.05, %s %cmp = icmp slt i32 %add, %n br i1 %cmp, label %for.body, label %for.end, !llvm.loop !8 for.end: ; preds = %for.body, %entry ret void } ; A more complex case with pre-increment compare instead of post-increment. ; We should have a conservative estimate for the max backedge taken count for ; loops with unknown stride. define void @foo5(ptr nocapture %A, i32 %n, i32 %s, i32 %start) mustprogress { ; ; CHECK-LABEL: 'foo5' ; CHECK-NEXT: Determining loop execution counts for: @foo5 ; CHECK-NEXT: Loop %for.body: backedge-taken count is ((((-1 * (1 umin ((-1 * %start) + (%n smax %start)))) + (-1 * %start) + (%n smax %start)) /u (1 umax %s)) + (1 umin ((-1 * %start) + (%n smax %start)))) ; CHECK-NEXT: Loop %for.body: constant max backedge-taken count is i32 -1 ; CHECK-NEXT: Loop %for.body: symbolic max backedge-taken count is ((((-1 * (1 umin ((-1 * %start) + (%n smax %start)))) + (-1 * %start) + (%n smax %start)) /u (1 umax %s)) + (1 umin ((-1 * %start) + (%n smax %start)))) ; CHECK-NEXT: Loop %for.body: Trip multiple is 1 ; entry: br label %for.body for.body: ; preds = %entry, %for.body %i.05 = phi i32 [ %add, %for.body ], [ %start, %entry ] %arrayidx = getelementptr inbounds i32, ptr %A, i32 %i.05 %0 = load i32, ptr %arrayidx, align 4 %inc = add nsw i32 %0, 1 store i32 %inc, ptr %arrayidx, align 4 %add = add nsw i32 %i.05, %s %cmp = icmp slt i32 %i.05, %n br i1 %cmp, label %for.body, label %for.end for.end: ; preds = %for.body, %entry ret void } ; FIXME: Currently we are more conservative for known zero stride than ; for unknown but potentially zero stride. ; Note that this function is well defined only when %n <=s 0 define void @zero_stride(ptr nocapture %A, i32 %n) { ; ; CHECK-LABEL: 'zero_stride' ; CHECK-NEXT: Determining loop execution counts for: @zero_stride ; CHECK-NEXT: Loop %for.body: Unpredictable backedge-taken count. ; CHECK-NEXT: Loop %for.body: Unpredictable constant max backedge-taken count. ; CHECK-NEXT: Loop %for.body: Unpredictable symbolic max backedge-taken count. ; entry: br label %for.body for.body: ; preds = %entry, %for.body %i.05 = phi i32 [ %add, %for.body ], [ 0, %entry ] %arrayidx = getelementptr inbounds i32, ptr %A, i32 %i.05 %0 = load i32, ptr %arrayidx, align 4 %inc = add nsw i32 %0, 1 store i32 %inc, ptr %arrayidx, align 4 %add = add nsw i32 %i.05, 0 %cmp = icmp slt i32 %add, %n br i1 %cmp, label %for.body, label %for.end, !llvm.loop !8 for.end: ; preds = %for.body, %entry ret void } ; Note that this function will always execute undefined behavior and thus ; any value is valid for a backedge taken count. define void @zero_stride_ub(ptr nocapture %A) { ; ; CHECK-LABEL: 'zero_stride_ub' ; CHECK-NEXT: Determining loop execution counts for: @zero_stride_ub ; CHECK-NEXT: Loop %for.body: Unpredictable backedge-taken count. ; CHECK-NEXT: Loop %for.body: Unpredictable constant max backedge-taken count. ; CHECK-NEXT: Loop %for.body: Unpredictable symbolic max backedge-taken count. ; entry: br label %for.body for.body: ; preds = %entry, %for.body %i.05 = phi i32 [ %add, %for.body ], [ 0, %entry ] %arrayidx = getelementptr inbounds i32, ptr %A, i32 %i.05 %0 = load i32, ptr %arrayidx, align 4 %inc = add nsw i32 %0, 1 store i32 %inc, ptr %arrayidx, align 4 %add = add nsw i32 %i.05, 0 %cmp = icmp slt i32 %add, 2 br i1 %cmp, label %for.body, label %for.end, !llvm.loop !8 for.end: ; preds = %for.body, %entry ret void } ; When %zero = 0, this loop is only well defined if %n < 0 and thus BTC = 0. define void @zero_stride_symbolic(ptr nocapture %A, i32 %n, i32 %zero) { ; ; CHECK-LABEL: 'zero_stride_symbolic' ; CHECK-NEXT: Determining loop execution counts for: @zero_stride_symbolic ; CHECK-NEXT: Loop %for.body: backedge-taken count is ((((-1 * (1 umin ((-1 * %zero) + (%n smax %zero)))) + (-1 * %zero) + (%n smax %zero)) /u (1 umax %zero)) + (1 umin ((-1 * %zero) + (%n smax %zero)))) ; CHECK-NEXT: Loop %for.body: constant max backedge-taken count is i32 -1 ; CHECK-NEXT: Loop %for.body: symbolic max backedge-taken count is ((((-1 * (1 umin ((-1 * %zero) + (%n smax %zero)))) + (-1 * %zero) + (%n smax %zero)) /u (1 umax %zero)) + (1 umin ((-1 * %zero) + (%n smax %zero)))) ; CHECK-NEXT: Loop %for.body: Trip multiple is 1 ; entry: br label %for.body for.body: ; preds = %entry, %for.body %i.05 = phi i32 [ %add, %for.body ], [ 0, %entry ] %arrayidx = getelementptr inbounds i32, ptr %A, i32 %i.05 %0 = load i32, ptr %arrayidx, align 4 %inc = add nsw i32 %0, 1 store i32 %inc, ptr %arrayidx, align 4 %add = add nsw i32 %i.05, %zero %cmp = icmp slt i32 %add, %n br i1 %cmp, label %for.body, label %for.end, !llvm.loop !8 for.end: ; preds = %for.body, %entry ret void } define void @zero_stride_varying_rhs(ptr nocapture %A, ptr %n_p, i32 %zero) { ; ; CHECK-LABEL: 'zero_stride_varying_rhs' ; CHECK-NEXT: Determining loop execution counts for: @zero_stride_varying_rhs ; CHECK-NEXT: Loop %for.body: Unpredictable backedge-taken count. ; CHECK-NEXT: Loop %for.body: Unpredictable constant max backedge-taken count. ; CHECK-NEXT: Loop %for.body: Unpredictable symbolic max backedge-taken count. ; entry: br label %for.body for.body: ; preds = %entry, %for.body %i.05 = phi i32 [ %add, %for.body ], [ 0, %entry ] %arrayidx = getelementptr inbounds i32, ptr %A, i32 %i.05 %0 = load i32, ptr %arrayidx, align 4 %inc = add nsw i32 %0, 1 store i32 %inc, ptr %arrayidx, align 4 %add = add nsw i32 %i.05, %zero %n = load i32, ptr %n_p %cmp = icmp slt i32 %add, %n br i1 %cmp, label %for.body, label %for.end, !llvm.loop !8 for.end: ; preds = %for.body, %entry ret void } define void @ne_nsw_pos_step(ptr nocapture %A, i32 %n, i32 %s) mustprogress { ; ; CHECK-LABEL: 'ne_nsw_pos_step' ; CHECK-NEXT: Determining loop execution counts for: @ne_nsw_pos_step ; CHECK-NEXT: Loop %for.body: backedge-taken count is (((-1 * %s) + %n) /u %s) ; CHECK-NEXT: Loop %for.body: constant max backedge-taken count is i32 -1 ; CHECK-NEXT: Loop %for.body: symbolic max backedge-taken count is (((-1 * %s) + %n) /u %s) ; CHECK-NEXT: Loop %for.body: Trip multiple is 1 ; entry: %pos_step = icmp sgt i32 %s, 0 call void @llvm.assume(i1 %pos_step) %cmp4 = icmp sgt i32 %n, 0 br i1 %cmp4, label %for.body, label %for.end for.body: ; preds = %entry, %for.body %i.05 = phi i32 [ %add, %for.body ], [ 0, %entry ] %arrayidx = getelementptr inbounds i32, ptr %A, i32 %i.05 %0 = load i32, ptr %arrayidx, align 4 %inc = add nsw i32 %0, 1 store i32 %inc, ptr %arrayidx, align 4 %add = add nsw i32 %i.05, %s %cmp = icmp ne i32 %add, %n br i1 %cmp, label %for.body, label %for.end for.end: ; preds = %for.body, %entry ret void } define void @ne_nsw_neg_step(ptr nocapture %A, i32 %n, i32 %s) mustprogress { ; ; CHECK-LABEL: 'ne_nsw_neg_step' ; CHECK-NEXT: Determining loop execution counts for: @ne_nsw_neg_step ; CHECK-NEXT: Loop %for.body: backedge-taken count is (((-1 * %n) + %s) /u (-1 * %s)) ; CHECK-NEXT: Loop %for.body: constant max backedge-taken count is i32 -2 ; CHECK-NEXT: Loop %for.body: symbolic max backedge-taken count is (((-1 * %n) + %s) /u (-1 * %s)) ; CHECK-NEXT: Loop %for.body: Trip multiple is 1 ; entry: %neg_step = icmp slt i32 %s, 0 call void @llvm.assume(i1 %neg_step) %cmp4 = icmp sgt i32 %n, 0 br i1 %cmp4, label %for.body, label %for.end for.body: ; preds = %entry, %for.body %i.05 = phi i32 [ %add, %for.body ], [ 0, %entry ] %arrayidx = getelementptr inbounds i32, ptr %A, i32 %i.05 %0 = load i32, ptr %arrayidx, align 4 %inc = add nsw i32 %0, 1 store i32 %inc, ptr %arrayidx, align 4 %add = add nsw i32 %i.05, %s %cmp = icmp ne i32 %add, %n br i1 %cmp, label %for.body, label %for.end for.end: ; preds = %for.body, %entry ret void } define void @ne_nsw_nonneg_step(ptr nocapture %A, i32 %n, i32 %s) mustprogress { ; ; CHECK-LABEL: 'ne_nsw_nonneg_step' ; CHECK-NEXT: Determining loop execution counts for: @ne_nsw_nonneg_step ; CHECK-NEXT: Loop %for.body: backedge-taken count is (((-1 * %s) + %n) /u %s) ; CHECK-NEXT: Loop %for.body: constant max backedge-taken count is i32 -1 ; CHECK-NEXT: Loop %for.body: symbolic max backedge-taken count is (((-1 * %s) + %n) /u %s) ; CHECK-NEXT: Loop %for.body: Trip multiple is 1 ; entry: %nonneg_step = icmp sge i32 %s, 0 call void @llvm.assume(i1 %nonneg_step) %cmp4 = icmp sgt i32 %n, 0 br i1 %cmp4, label %for.body, label %for.end for.body: ; preds = %entry, %for.body %i.05 = phi i32 [ %add, %for.body ], [ 0, %entry ] %arrayidx = getelementptr inbounds i32, ptr %A, i32 %i.05 %0 = load i32, ptr %arrayidx, align 4 %inc = add nsw i32 %0, 1 store i32 %inc, ptr %arrayidx, align 4 %add = add nsw i32 %i.05, %s %cmp = icmp ne i32 %add, %n br i1 %cmp, label %for.body, label %for.end for.end: ; preds = %for.body, %entry ret void } define void @ne_nsw_unknown_step(ptr nocapture %A, i32 %n, i32 %s) mustprogress { ; ; CHECK-LABEL: 'ne_nsw_unknown_step' ; CHECK-NEXT: Determining loop execution counts for: @ne_nsw_unknown_step ; CHECK-NEXT: Loop %for.body: Unpredictable backedge-taken count. ; CHECK-NEXT: Loop %for.body: Unpredictable constant max backedge-taken count. ; CHECK-NEXT: Loop %for.body: Unpredictable symbolic max backedge-taken count. ; entry: %cmp4 = icmp sgt i32 %n, 0 br i1 %cmp4, label %for.body, label %for.end for.body: ; preds = %entry, %for.body %i.05 = phi i32 [ %add, %for.body ], [ 0, %entry ] %arrayidx = getelementptr inbounds i32, ptr %A, i32 %i.05 %0 = load i32, ptr %arrayidx, align 4 %inc = add nsw i32 %0, 1 store i32 %inc, ptr %arrayidx, align 4 %add = add nsw i32 %i.05, %s %cmp = icmp ne i32 %add, %n br i1 %cmp, label %for.body, label %for.end for.end: ; preds = %for.body, %entry ret void } define void @ne_nuw_pos_step(ptr nocapture %A, i32 %n, i32 %s) mustprogress { ; ; CHECK-LABEL: 'ne_nuw_pos_step' ; CHECK-NEXT: Determining loop execution counts for: @ne_nuw_pos_step ; CHECK-NEXT: Loop %for.body: backedge-taken count is (((-1 * %s) + %n) /u %s) ; CHECK-NEXT: Loop %for.body: constant max backedge-taken count is i32 -1 ; CHECK-NEXT: Loop %for.body: symbolic max backedge-taken count is (((-1 * %s) + %n) /u %s) ; CHECK-NEXT: Loop %for.body: Trip multiple is 1 ; entry: %pos_step = icmp sgt i32 %s, 0 call void @llvm.assume(i1 %pos_step) %cmp4 = icmp sgt i32 %n, 0 br i1 %cmp4, label %for.body, label %for.end for.body: ; preds = %entry, %for.body %i.05 = phi i32 [ %add, %for.body ], [ 0, %entry ] %arrayidx = getelementptr inbounds i32, ptr %A, i32 %i.05 %0 = load i32, ptr %arrayidx, align 4 %inc = add nuw i32 %0, 1 store i32 %inc, ptr %arrayidx, align 4 %add = add nuw i32 %i.05, %s %cmp = icmp ne i32 %add, %n br i1 %cmp, label %for.body, label %for.end for.end: ; preds = %for.body, %entry ret void } define void @ne_nuw_neg_step(ptr nocapture %A, i32 %n, i32 %s) mustprogress { ; ; CHECK-LABEL: 'ne_nuw_neg_step' ; CHECK-NEXT: Determining loop execution counts for: @ne_nuw_neg_step ; CHECK-NEXT: Loop %for.body: backedge-taken count is (((-1 * %n) + %s) /u (-1 * %s)) ; CHECK-NEXT: Loop %for.body: constant max backedge-taken count is i32 -2 ; CHECK-NEXT: Loop %for.body: symbolic max backedge-taken count is (((-1 * %n) + %s) /u (-1 * %s)) ; CHECK-NEXT: Loop %for.body: Trip multiple is 1 ; entry: %neg_step = icmp slt i32 %s, 0 call void @llvm.assume(i1 %neg_step) %cmp4 = icmp sgt i32 %n, 0 br i1 %cmp4, label %for.body, label %for.end for.body: ; preds = %entry, %for.body %i.05 = phi i32 [ %add, %for.body ], [ 0, %entry ] %arrayidx = getelementptr inbounds i32, ptr %A, i32 %i.05 %0 = load i32, ptr %arrayidx, align 4 %inc = add nuw i32 %0, 1 store i32 %inc, ptr %arrayidx, align 4 %add = add nuw i32 %i.05, %s %cmp = icmp ne i32 %add, %n br i1 %cmp, label %for.body, label %for.end for.end: ; preds = %for.body, %entry ret void } define void @ne_nuw_nonneg_step(ptr nocapture %A, i32 %n, i32 %s) mustprogress { ; ; CHECK-LABEL: 'ne_nuw_nonneg_step' ; CHECK-NEXT: Determining loop execution counts for: @ne_nuw_nonneg_step ; CHECK-NEXT: Loop %for.body: backedge-taken count is (((-1 * %s) + %n) /u %s) ; CHECK-NEXT: Loop %for.body: constant max backedge-taken count is i32 -1 ; CHECK-NEXT: Loop %for.body: symbolic max backedge-taken count is (((-1 * %s) + %n) /u %s) ; CHECK-NEXT: Loop %for.body: Trip multiple is 1 ; entry: %nonneg_step = icmp sge i32 %s, 0 call void @llvm.assume(i1 %nonneg_step) %cmp4 = icmp sgt i32 %n, 0 br i1 %cmp4, label %for.body, label %for.end for.body: ; preds = %entry, %for.body %i.05 = phi i32 [ %add, %for.body ], [ 0, %entry ] %arrayidx = getelementptr inbounds i32, ptr %A, i32 %i.05 %0 = load i32, ptr %arrayidx, align 4 %inc = add nuw i32 %0, 1 store i32 %inc, ptr %arrayidx, align 4 %add = add nuw i32 %i.05, %s %cmp = icmp ne i32 %add, %n br i1 %cmp, label %for.body, label %for.end for.end: ; preds = %for.body, %entry ret void } define void @ne_nuw_unknown_step(ptr nocapture %A, i32 %n, i32 %s) mustprogress { ; ; CHECK-LABEL: 'ne_nuw_unknown_step' ; CHECK-NEXT: Determining loop execution counts for: @ne_nuw_unknown_step ; CHECK-NEXT: Loop %for.body: Unpredictable backedge-taken count. ; CHECK-NEXT: Loop %for.body: Unpredictable constant max backedge-taken count. ; CHECK-NEXT: Loop %for.body: Unpredictable symbolic max backedge-taken count. ; entry: %cmp4 = icmp sgt i32 %n, 0 br i1 %cmp4, label %for.body, label %for.end for.body: ; preds = %entry, %for.body %i.05 = phi i32 [ %add, %for.body ], [ 0, %entry ] %arrayidx = getelementptr inbounds i32, ptr %A, i32 %i.05 %0 = load i32, ptr %arrayidx, align 4 %inc = add nuw i32 %0, 1 store i32 %inc, ptr %arrayidx, align 4 %add = add nuw i32 %i.05, %s %cmp = icmp ne i32 %add, %n br i1 %cmp, label %for.body, label %for.end for.end: ; preds = %for.body, %entry ret void } declare void @llvm.assume(i1) !8 = distinct !{!8, !9} !9 = !{!"llvm.loop.mustprogress"}