1; RUN: opt -S -jump-threading < %s | FileCheck %s 2 3; Check that based solely on static profile estimation we don't update the 4; branch-weight metadata. Even if the function has an entry frequency, a 5; completely cold part of the CFG may be statically estimated. 6 7; For example in the loop below, jump threading would update the weight of the 8; loop-exiting branch to 0, drastically inflating the frequency of the loop 9; (in the range of billions). 10; 11; This is the CFG of the loop. There is no run-time profile info for edges 12; inside the loop, so branch and block frequencies are estimated as shown: 13; 14; check_1 (16) 15; (8) / | 16; eq_1 | (8) 17; \ | 18; check_2 (16) 19; (8) / | 20; eq_2 | (8) 21; \ | 22; check_3 (16) 23; (1) / | 24; (loop exit) | (15) 25; | 26; latch 27; | 28; (back edge) 29; 30; First we thread eq_1->check_2 to check_3. Frequencies are updated to remove 31; the frequency of eq_1 from check_2 and then the false edge leaving check_2 32; (changed frequencies are highlighted with * *): 33; 34; check_1 (16) 35; (8) / | 36; eq_1~ | (8) 37; / | 38; / check_2 (*8*) 39; / (8) / | 40; \ eq_2 | (*0*) 41; \ \ | 42; ` --- check_3 (16) 43; (1) / | 44; (loop exit) | (15) 45; | 46; latch 47; | 48; (back edge) 49; 50; Next we thread eq_1->check_3 and eq_2->check_3 to check_1 as new edges to 51; the loop latch. Frequencies are updated to remove the frequency of eq_1 52; and eq_3 from check_3 and then the false edge leaving check_3 (changed 53; frequencies are highlighted with * *): 54; 55; check_1 (16) 56; (8) / | 57; eq_1~ | (8) 58; / | 59; / check_2 (*8*) 60; / (8) / | 61; /-- eq_2~ | (*0*) 62; / | 63; / check_3 (*0*) 64; / (*0*) / | 65; | (loop exit) | (*0*) 66; \ | 67; `--------- latch 68; | 69; (back edge) 70; 71; As a result, the loop exit edge ends up with 0 frequency which in turn makes 72; the loop header to have maximum frequency. 73 74declare void @bar() 75 76define void @foo(i32 *%p, i32 %n) !prof !0 { 77entry: 78 %enter_loop = icmp eq i32 %n, 0 79 br i1 %enter_loop, label %exit, label %check_1, !prof !1 80; CHECK: br i1 %enter_loop, label %exit, label %check_1, !prof !1 81 82check_1: 83 %v = load i32, i32* %p 84 %cond1 = icmp eq i32 %v, 1 85 br i1 %cond1, label %eq_1, label %check_2 86; No metadata: 87; CHECK: br i1 %cond1, label %check_2.thread, label %check_2{{$}} 88 89eq_1: 90 call void @bar() 91 br label %check_2 92; Verify the new edge: 93; CHECK: check_2.thread: 94; CHECK-NEXT: call void @bar() 95; CHECK-NEXT: br label %latch 96 97check_2: 98 %cond2 = icmp eq i32 %v, 2 99 br i1 %cond2, label %eq_2, label %check_3 100; No metadata: 101; CHECK: br i1 %cond2, label %eq_2, label %check_3{{$}} 102 103eq_2: 104 call void @bar() 105 br label %check_3 106; Verify the new edge: 107; CHECK: eq_2: 108; CHECK-NEXT: call void @bar() 109; CHECK-NEXT: br label %latch 110 111check_3: 112 %condE = icmp eq i32 %v, 3 113 br i1 %condE, label %exit, label %latch 114; No metadata: 115; CHECK: br i1 %condE, label %exit, label %latch{{$}} 116 117latch: 118 br label %check_1 119 120exit: 121 ret void 122} 123 124!0 = !{!"function_entry_count", i64 120} 125; CHECK-NOT: branch_weights 126!1 = !{!"branch_weights", i32 119, i32 1} 127; CHECK: !1 = !{!"branch_weights", i32 119, i32 1} 128; CHECK-NOT: branch_weights 129