blob: d634a607eabfbcb94944757a7a70120fd83a979e [file] [log] [blame]
Adam Nemetc5208222016-09-06 16:08:33 +00001; 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