Index: llvm/lib/Analysis/ScalarEvolution.cpp =================================================================== --- llvm/lib/Analysis/ScalarEvolution.cpp +++ llvm/lib/Analysis/ScalarEvolution.cpp @@ -7376,6 +7376,10 @@ return getZero(CI->getType()); } + if (auto *FI = dyn_cast(ExitCond)) + return computeExitLimitFromCondImpl(Cache, L, FI->getOperand(0), ExitIfTrue, + ControlsExit, AllowPredicates); + // If it's not an integer or pointer comparison then compute it the hard way. return computeExitCountExhaustively(L, ExitCond, ExitIfTrue); } Index: llvm/test/Analysis/ScalarEvolution/trip-count.ll =================================================================== --- llvm/test/Analysis/ScalarEvolution/trip-count.ll +++ llvm/test/Analysis/ScalarEvolution/trip-count.ll @@ -121,3 +121,98 @@ leave: ret void } + +define void @frozen_condition(i32 %n) { +; CHECK-LABEL: 'frozen_condition' +; CHECK-NEXT: Determining loop execution counts for: @frozen_condition +; CHECK-NEXT: Loop %loop: backedge-taken count is %n +; CHECK-NEXT: Loop %loop: max backedge-taken count is -1 +; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is %n +; CHECK-NEXT: Predicates: +; CHECK: Loop %loop: Trip multiple is 1 +; +entry: + br label %loop + +loop: + %iv = phi i32 [ 0, %entry ], [ %iv.inc, %loop ] + %iv.inc = add nsw i32 %iv, 1 + call void @may_exit() + %becond = icmp ult i32 %iv, %n + %freeze = freeze i1 %becond + br i1 %freeze, label %loop, label %leave + +leave: + ret void +} + +define void @frozen_iv(i32 %n) { +; CHECK-LABEL: 'frozen_iv' +; CHECK-NEXT: Determining loop execution counts for: @frozen_iv +; CHECK-NEXT: Loop %loop: Unpredictable backedge-taken count. +; CHECK-NEXT: Loop %loop: Unpredictable max backedge-taken count. +; CHECK-NEXT: Loop %loop: Unpredictable predicated backedge-taken count. +; +entry: + br label %loop + +loop: + %iv = phi i32 [ 0, %entry ], [ %iv.inc, %loop ] + %iv.inc = add nsw i32 %iv, 1 + call void @may_exit() + %freeze = freeze i32 %iv + %becond = icmp ult i32 %freeze, %n + br i1 %becond, label %loop, label %leave + +leave: + ret void +} + +define void @frozen_inc(i32 %n) { +; CHECK-LABEL: 'frozen_inc' +; CHECK-NEXT: Determining loop execution counts for: @frozen_inc +; CHECK-NEXT: Loop %loop: Unpredictable backedge-taken count. +; CHECK-NEXT: Loop %loop: Unpredictable max backedge-taken count. +; CHECK-NEXT: Loop %loop: Unpredictable predicated backedge-taken count. +; +entry: + br label %loop + +loop: + %iv = phi i32 [ 0, %entry ], [ %freeze, %loop ] + %iv.inc = add nsw i32 %iv, 1 + %freeze = freeze i32 %iv.inc + call void @may_exit() + %becond = icmp ult i32 %iv, %n + br i1 %becond, label %loop, label %leave + +leave: + ret void +} + +define void @frozen_limit(i32 %n) { +; CHECK-LABEL: 'frozen_limit' +; CHECK-NEXT: Determining loop execution counts for: @frozen_limit +; CHECK-NEXT: Loop %loop: backedge-taken count is %freeze +; CHECK-NEXT: Loop %loop: max backedge-taken count is -1 +; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is %freeze +; CHECK-NEXT: Predicates: +; CHECK: Loop %loop: Trip multiple is 1 +; +entry: + %freeze = freeze i32 %n + br label %loop + +loop: + %iv = phi i32 [ 0, %entry ], [ %iv.inc, %loop ] + %iv.inc = add nsw i32 %iv, 1 + call void @may_exit() + %becond = icmp ult i32 %iv, %freeze + br i1 %becond, label %loop, label %leave + +leave: + ret void +} + + +