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 74 declare void @bar() 75 76 define void @foo(i32 *%p, i32 %n) !prof !0 { 77 entry: 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 82 check_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 89 eq_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 97 check_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 103 eq_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 111 check_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 117 latch: 118 br label %check_1 119 120 exit: 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