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; (back edge) 27; 28; First we thread eq_1->check_2 to check_3. Frequencies are updated to remove 29; the frequency of eq_1 from check_2 and then the false edge leaving check_2 30; (changed frequencies are highlighted with * *): 31; 32; check_1 (16) 33; (8) / | 34; eq_1~ | (8) 35; / | 36; / check_2 (*8*) 37; / (8) / | 38; \ eq_2 | (*0*) 39; \ \ | 40; ` --- check_3 (16) 41; (1) / | 42; (loop exit) | (15) 43; | 44; (back edge) 45; 46; Next we thread eq_1->check_3 and eq_2->check_3 to check_1 as new back edges. 47; Frequencies are updated to remove the frequency of eq_1 and eq_3 from 48; check_3 and then the false edge leaving check_3 (changed frequencies are 49; highlighted with * *): 50; 51; check_1 (16) 52; (8) / | 53; eq_1~ | (8) 54; / | 55; / check_2 (*8*) 56; / (8) / | 57; /-- eq_2~ | (*0*) 58; (back edge) | 59; check_3 (*0*) 60; (*0*) / | 61; (loop exit) | (*0*) 62; | 63; (back edge) 64; 65; As a result, the loop exit edge ends up with 0 frequency which in turn makes 66; the loop header to have maximum frequency. 67 68declare void @bar() 69 70define void @foo(i32 *%p, i32 %n) !prof !0 { 71entry: 72 %enter_loop = icmp eq i32 %n, 0 73 br i1 %enter_loop, label %exit, label %check_1, !prof !1 74; CHECK: br i1 %enter_loop, label %exit, label %check_1, !prof !1 75 76check_1: 77 %v = load i32, i32* %p 78 %cond1 = icmp eq i32 %v, 1 79 br i1 %cond1, label %eq_1, label %check_2 80; No metadata: 81; CHECK: br i1 %cond1, label %check_2.thread, label %check_2{{$}} 82 83eq_1: 84 call void @bar() 85 br label %check_2 86; Verify the new backedge: 87; CHECK: check_2.thread: 88; CHECK-NEXT: call void @bar() 89; CHECK-NEXT: br label %check_1 90 91check_2: 92 %cond2 = icmp eq i32 %v, 2 93 br i1 %cond2, label %eq_2, label %check_3 94; No metadata: 95; CHECK: br i1 %cond2, label %eq_2, label %check_3{{$}} 96 97eq_2: 98 call void @bar() 99 br label %check_3 100; Verify the new backedge: 101; CHECK: eq_2: 102; CHECK-NEXT: call void @bar() 103; CHECK-NEXT: br label %check_1 104 105check_3: 106 %condE = icmp eq i32 %v, 3 107 br i1 %condE, label %exit, label %check_1 108; No metadata: 109; CHECK: br i1 %condE, label %exit, label %check_1{{$}} 110 111exit: 112 ret void 113} 114 115!0 = !{!"function_entry_count", i64 120} 116; CHECK-NOT: branch_weights 117!1 = !{!"branch_weights", i32 119, i32 1} 118; CHECK: !1 = !{!"branch_weights", i32 119, i32 1} 119; CHECK-NOT: branch_weights 120