; RUN: opt < %s -disable-output "-passes=print" -scalar-evolution-max-iterations=0 -scalar-evolution-classify-expressions=0 2>&1 | FileCheck %s define void @slt(i16 %a, i16 %b, i1 %c) { ; CHECK-LABEL: 'slt' ; CHECK-NEXT: Determining loop execution counts for: @slt ; CHECK-NEXT: Loop %loop: backedge-taken count is (19 + (-1 * %count)) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i16 18 ; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (19 + (-1 * %count)) ; CHECK-NEXT: Loop %loop: Trip multiple is 1 entry: br i1 %c, label %b1, label %b2 b1: %cmp1 = icmp slt i16 %a, 1 br i1 %cmp1, label %exit, label %preheader b2: %cmp2 = icmp slt i16 %b, 4 br i1 %cmp2, label %exit, label %preheader preheader: %count = phi i16 [ %a, %b1 ], [ %b, %b2 ] %cmp3 = icmp sle i16 %count, 19 br i1 %cmp3, label %loop, label %exit loop: %iv = phi i16 [ %iv.next, %loop ], [ %count, %preheader ] %iv.next = add i16 %iv, 1 %exitcond = icmp eq i16 %iv.next, 20 br i1 %exitcond, label %exit, label %loop exit: ret void } define void @ult(i16 %a, i16 %b, i1 %c) { ; CHECK-LABEL: 'ult' ; CHECK-NEXT: Determining loop execution counts for: @ult ; CHECK-NEXT: Loop %loop: backedge-taken count is (21 + (-1 * %count)) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i16 19 ; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (21 + (-1 * %count)) ; CHECK-NEXT: Loop %loop: Trip multiple is 1 entry: br i1 %c, label %b1, label %b2 b1: %cmp1 = icmp ult i16 %a, 2 br i1 %cmp1, label %exit, label %preheader b2: %cmp2 = icmp ult i16 %b, 5 br i1 %cmp2, label %exit, label %preheader preheader: %count = phi i16 [ %a, %b1 ], [ %b, %b2 ] %cmp3 = icmp ule i16 %count, 20 br i1 %cmp3, label %loop, label %exit loop: %iv = phi i16 [ %iv.next, %loop ], [ %count, %preheader ] %iv.next = add i16 %iv, 1 %exitcond = icmp eq i16 %iv.next, 22 br i1 %exitcond, label %exit, label %loop exit: ret void } define void @sgt(i16 %a, i16 %b, i1 %c) { ; CHECK-LABEL: 'sgt' ; CHECK-NEXT: Determining loop execution counts for: @sgt ; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %count) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i16 9 ; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %count) ; CHECK-NEXT: Loop %loop: Trip multiple is 1 entry: br i1 %c, label %b1, label %b2 b1: %cmp1 = icmp sgt i16 %a, 10 br i1 %cmp1, label %exit, label %preheader b2: %cmp2 = icmp sgt i16 %b, 8 br i1 %cmp2, label %exit, label %preheader preheader: %count = phi i16 [ %a, %b1 ], [ %b, %b2 ] %cmp3 = icmp sge i16 %count, 1 br i1 %cmp3, label %loop, label %exit loop: %iv = phi i16 [ %iv.next, %loop ], [ %count, %preheader ] %iv.next = add i16 %iv, -1 %exitcond = icmp eq i16 %iv.next, 0 br i1 %exitcond, label %exit, label %loop exit: ret void } define void @ugt(i16 %a, i16 %b, i1 %c) { ; CHECK-LABEL: 'ugt' ; CHECK-NEXT: Determining loop execution counts for: @ugt ; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %count) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i16 10 ; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %count) ; CHECK-NEXT: Loop %loop: Trip multiple is 1 entry: br i1 %c, label %b1, label %b2 b1: %cmp1 = icmp ugt i16 %a, 11 br i1 %cmp1, label %exit, label %preheader b2: %cmp2 = icmp ugt i16 %b, 7 br i1 %cmp2, label %exit, label %preheader preheader: %count = phi i16 [ %a, %b1 ], [ %b, %b2 ] %cmp3 = icmp ne i16 %count, 0 br i1 %cmp3, label %loop, label %exit loop: %iv = phi i16 [ %iv.next, %loop ], [ %count, %preheader ] %iv.next = add i16 %iv, -1 %exitcond = icmp eq i16 %iv.next, 0 br i1 %exitcond, label %exit, label %loop exit: ret void } define void @three_incoming(i16 %a, i16 %b, i1 %c, i1 %d) { ; CHECK-LABEL: 'three_incoming' ; CHECK-NEXT: Determining loop execution counts for: @three_incoming ; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %count) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i16 11 ; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %count) ; CHECK-NEXT: Loop %loop: Trip multiple is 1 entry: br i1 %c, label %b1, label %entry2 entry2: br i1 %d, label %b2, label %b3 b1: %cmp1 = icmp ugt i16 %a, 10 br i1 %cmp1, label %exit, label %preheader b2: %cmp2 = icmp ugt i16 %b, 8 br i1 %cmp2, label %exit, label %preheader b3: %cmp3 = icmp ugt i16 %b, 12 br i1 %cmp3, label %exit, label %preheader preheader: %count = phi i16 [ %a, %b1 ], [ %b, %b2 ], [ %b, %b3 ] %cmp4 = icmp ne i16 %count, 0 br i1 %cmp4, label %loop, label %exit loop: %iv = phi i16 [ %iv.next, %loop ], [ %count, %preheader ] %iv.next = add i16 %iv, -1 %exitcond = icmp eq i16 %iv.next, 0 br i1 %exitcond, label %exit, label %loop exit: ret void } define void @mixed(i16 %a, i16 %b, i1 %c) { ; CHECK-LABEL: 'mixed' ; CHECK-NEXT: Determining loop execution counts for: @mixed ; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %count) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i16 -2 ; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %count) ; CHECK-NEXT: Loop %loop: Trip multiple is 1 entry: br i1 %c, label %b1, label %b2 b1: %cmp1 = icmp ugt i16 %a, 10 br i1 %cmp1, label %exit, label %preheader b2: %cmp2 = icmp sgt i16 %b, 8 br i1 %cmp2, label %exit, label %preheader preheader: %count = phi i16 [ %a, %b1 ], [ %b, %b2 ] %cmp3 = icmp ne i16 %count, 0 br i1 %cmp3, label %loop, label %exit loop: %iv = phi i16 [ %iv.next, %loop ], [ %count, %preheader ] %iv.next = add i16 %iv, -1 %exitcond = icmp eq i16 %iv.next, 0 br i1 %exitcond, label %exit, label %loop exit: ret void } define void @one_constant(i16 %a, i16 %b, i1 %c, i16 %d) { ; CHECK-LABEL: 'one_constant' ; CHECK-NEXT: Determining loop execution counts for: @one_constant ; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %count) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i16 -2 ; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %count) ; CHECK-NEXT: Loop %loop: Trip multiple is 1 entry: br i1 %c, label %b1, label %b2 b1: %cmp1 = icmp ugt i16 %a, 10 br i1 %cmp1, label %exit, label %preheader b2: %cmp2 = icmp ugt i16 %b, %d br i1 %cmp2, label %exit, label %preheader preheader: %count = phi i16 [ %a, %b1 ], [ %b, %b2 ] %cmp3 = icmp ne i16 %count, 0 br i1 %cmp3, label %loop, label %exit loop: %iv = phi i16 [ %iv.next, %loop ], [ %count, %preheader ] %iv.next = add i16 %iv, -1 %exitcond = icmp eq i16 %iv.next, 0 br i1 %exitcond, label %exit, label %loop exit: ret void } define void @epilogue(i64 %count) { ; CHECK-LABEL: 'epilogue' ; CHECK-NEXT: Determining loop execution counts for: @epilogue ; CHECK-NEXT: Loop %epilogue: backedge-taken count is (-1 + %count.epilogue) ; CHECK-NEXT: Loop %epilogue: constant max backedge-taken count is i64 6 ; CHECK-NEXT: Loop %epilogue: symbolic max backedge-taken count is (-1 + %count.epilogue) ; CHECK-NEXT: Loop %epilogue: Trip multiple is 1 ; CHECK-NEXT: Loop %while.body: backedge-taken count is ((-8 + %count) /u 8) ; CHECK-NEXT: Loop %while.body: constant max backedge-taken count is i64 2305843009213693951 ; CHECK-NEXT: Loop %while.body: symbolic max backedge-taken count is ((-8 + %count) /u 8) ; CHECK-NEXT: Loop %while.body: Trip multiple is 1 entry: %cmp = icmp ugt i64 %count, 7 br i1 %cmp, label %while.body, label %epilogue.preheader while.body: %iv = phi i64 [ %sub, %while.body ], [ %count, %entry ] %sub = add i64 %iv, -8 %exitcond.not = icmp ugt i64 %sub, 7 br i1 %exitcond.not, label %while.body, label %while.loopexit while.loopexit: %sub.exit = phi i64 [ %sub, %while.body ] br label %epilogue.preheader epilogue.preheader: %count.epilogue = phi i64 [ %count, %entry ], [ %sub.exit, %while.loopexit ] %epilogue.cmp = icmp eq i64 %count.epilogue, 0 br i1 %epilogue.cmp, label %exit, label %epilogue epilogue: %iv.epilogue = phi i64 [ %dec, %epilogue ], [ %count.epilogue, %epilogue.preheader ] %dec = add i64 %iv.epilogue, -1 %exitcond.epilogue = icmp eq i64 %dec, 0 br i1 %exitcond.epilogue, label %exit, label %epilogue exit: ret void } declare void @llvm.assume(i1) ; Checks that the presence of assumptions does not interfere with ; exiting loop guard collection via following loop predecessors. define void @pr120442(i1 %c.1, i1 %c.2) { ; CHECK-LABEL: 'pr120442' ; CHECK-NEXT: Determining loop execution counts for: @pr120442 ; CHECK-NEXT: Loop %inner.header: backedge-taken count is i32 0 ; CHECK-NEXT: Loop %inner.header: constant max backedge-taken count is i32 0 ; CHECK-NEXT: Loop %inner.header: symbolic max backedge-taken count is i32 0 ; CHECK-NEXT: Loop %inner.header: Trip multiple is 1 entry: call void @llvm.assume(i1 %c.1) call void @llvm.assume(i1 %c.2) br label %outer.header outer.header: %phi7 = phi i32 [ 0, %bb ], [ 0, %entry ] br label %inner.header bb: br i1 false, label %outer.header, label %bb inner.header: %phi = phi i32 [ %add, %inner.header ], [ 0, %outer.header ] %add = add i32 %phi, 1 %icmp = icmp ugt i32 %add, 0 br i1 %icmp, label %exit, label %inner.header exit: ret void } ; Checks correct traversal for loops without a unique predecessor ; outside the loop. define void @pr120615() { ; CHECK-LABEL: pr120615 ; CHECK-NEXT: Determining loop execution counts for: @pr120615 ; CHECK-NEXT: Loop %header: backedge-taken count is i32 0 ; CHECK-NEXT: Loop %header: constant max backedge-taken count is i32 0 ; CHECK-NEXT: Loop %header: symbolic max backedge-taken count is i32 0 ; CHECK-NEXT: Loop %header: Trip multiple is 1 entry: br label %header bb: br label %header header: %0 = phi i32 [ %1, %header ], [ 0, %bb ], [ 0, %entry ] %1 = add i32 %0, 1 %icmp = icmp slt i32 %0, 0 br i1 %icmp, label %header, label %exit exit: ret void } ; Checks correct traversal for loops without a unique predecessor ; outside the loop. define void @pr122913() { ; CHECK-LABEL: pr122913 ; CHECK-NEXT: Determining loop execution counts for: @pr122913 ; CHECK-NEXT: Loop %header: backedge-taken count is i1 false ; CHECK-NEXT: Loop %header: constant max backedge-taken count is i1 false ; CHECK-NEXT: Loop %header: symbolic max backedge-taken count is i1 false ; CHECK-NEXT: Loop %header: Trip multiple is 1 entry: br i1 1, label %bb, label %header bb: br i1 1, label %exit, label %header header: %0 = phi i32 [ %1, %body ], [ 0, %bb ], [ 0, %entry ] br label %body body: %1 = add i32 %0, 1 %2 = icmp ult i32 %1, 0 br i1 %2, label %header, label %exit exit: ret void } define void @hang_due_to_unreachable_phi_inblock() personality ptr null { bb: br label %bb6 self-loop: ; preds = %self-loop %dead = invoke ptr null() to label %self-loop unwind label %bb4 bb4: ; preds = %self-loop %i5 = landingpad { ptr, i32 } cleanup br label %bb6 bb6: ; preds = %bb4, %bb %i7 = phi ptr [ null, %bb4 ], [ null, %bb ] br label %bb8 bb8: ; preds = %bb8, %bb6 %i9 = phi ptr [ null, %bb8 ], [ null, %bb6 ] %i11 = icmp eq ptr %i9, null br i1 %i11, label %bb12, label %bb8 bb12: ; preds = %bb8, %bb6 ret void }