Currently the loop branch heuristic is applied before the invoke heuristic which makes us overestimate the probability of the unwind destination of invokes inside loops. This in turn makes us grossly underestimate the frequencies of loops with invokes.

loop: %i = phi i32 [ 0, %entry ], [ %i.next, %invoke.cont ] invoke void @foo() to label %invoke.cont unwind label %lpad invoke.cont: %i.next = add i32 %i, 1 %cont = icmp ult i32 %i.next, %n br i1 %cont, label %loop, label %exit, !prof !{!"branch_weights", i32 9999, i32 1}

-analyze -branch-prob: ... edge loop -> invoke.cont probability is 0x7c000000 / 0x80000000 = 96.88% [HOT edge] edge loop -> lpad probability is 0x04000000 / 0x80000000 = 3.12% ... -analyze -block-freq: ... - loop: float = 31.901 ...

Applying the invoke heuristic before the loop one makes the results more resonable:

-analyze -branch-prob: ... edge loop -> invoke.cont probability is 0x7ffff800 / 0x80000000 = 100.00% [HOT edge] edge loop -> lpad probability is 0x00000800 / 0x80000000 = 0.00% ... -analyze -block-freq: ... - loop: float = 9905.6 ...