• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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