Home | History | Annotate | Download | only in JumpThreading
      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