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