1 // RUN: %clang_cc1 -O1 -emit-llvm %s -o - -triple=x86_64-linux-gnu | FileCheck -DLIKELY=2000 -DUNLIKELY=1 %s
2 // RUN: %clang_cc1 -O1 -emit-llvm %s -triple=x86_64-linux-gnu -mllvm -likely-branch-weight=99 -mllvm -unlikely-branch-weight=42 -o - | FileCheck -DLIKELY=99 -DUNLIKELY=42 %s
3
4 extern volatile bool b;
5 extern volatile int i;
6 extern bool A();
7 extern bool B();
8
f()9 bool f() {
10 // CHECK-LABEL: define{{.*}} zeroext i1 @_Z1fv
11 // CHECK: br {{.*}} !prof !7
12 if (b)
13 [[likely]] {
14 return A();
15 }
16 return B();
17 }
18
g()19 bool g() {
20 // CHECK-LABEL: define{{.*}} zeroext i1 @_Z1gv
21 // CHECK: br {{.*}} !prof !8
22 if (b)
23 [[unlikely]] {
24 return A();
25 }
26
27 return B();
28 }
29
h()30 bool h() {
31 // CHECK-LABEL: define{{.*}} zeroext i1 @_Z1hv
32 // CHECK: br {{.*}} !prof !8
33 if (b)
34 [[unlikely]] return A();
35
36 return B();
37 }
38
NullStmt()39 void NullStmt() {
40 // CHECK-LABEL: define{{.*}}NullStmt
41 // CHECK: br {{.*}} !prof !8
42 if (b)
43 [[unlikely]];
44 else {
45 // Make sure the branches aren't optimized away.
46 b = true;
47 }
48 }
49
IfStmt()50 void IfStmt() {
51 // CHECK-LABEL: define{{.*}}IfStmt
52 // CHECK: br {{.*}} !prof !8
53 if (b)
54 [[unlikely]] if (B()) {}
55
56 // CHECK-NOT: br {{.*}} !prof
57 // CHECK: br {{.*}} !prof
58 if (b) {
59 if (B())
60 [[unlikely]] { b = false; }
61 }
62 }
63
WhileStmt()64 void WhileStmt() {
65 // CHECK-LABEL: define{{.*}}WhileStmt
66 // CHECK: br {{.*}} !prof !8
67 if (b)
68 [[unlikely]] while (B()) {}
69
70 // CHECK-NOT: br {{.*}} %if.end{{.*}} !prof
71 if (b)
72 // CHECK: br {{.*}} !prof !7
73 while (B())
74 [[unlikely]] { b = false; }
75 }
76
DoStmt()77 void DoStmt() {
78 // CHECK-LABEL: define{{.*}}DoStmt
79 // CHECK: br {{.*}} !prof !8
80 if (b)
81 [[unlikely]] do {}
82 while (B())
83 ;
84
85 // CHECK-NOT: br {{.*}} %if.end{{.*}} !prof
86 if (b)
87 do
88 [[unlikely]] {}
89 while (B());
90 }
91
ForStmt()92 void ForStmt() {
93 // CHECK-LABEL: define{{.*}}ForStmt
94 // CHECK: br {{.*}} !prof !8
95 if (b)
96 [[unlikely]] for (; B();) {}
97
98 // CHECK-NOT: br {{.*}} %if.end{{.*}} !prof
99 if (b)
100 // CHECK: br {{.*}} !prof !7
101 for (; B();)
102 [[unlikely]] {}
103 }
104
GotoStmt()105 void GotoStmt() {
106 // CHECK-LABEL: define{{.*}}GotoStmt
107 // CHECK: br {{.*}} !prof !8
108 if (b)
109 [[unlikely]] goto end;
110 else {
111 // Make sure the branches aren't optimized away.
112 b = true;
113 }
114 end:;
115 }
116
ReturnStmt()117 void ReturnStmt() {
118 // CHECK-LABEL: define{{.*}}ReturnStmt
119 // CHECK: br {{.*}} !prof !8
120 if (b)
121 [[unlikely]] return;
122 else {
123 // Make sure the branches aren't optimized away.
124 b = true;
125 }
126 }
127
SwitchStmt()128 void SwitchStmt() {
129 // CHECK-LABEL: define{{.*}}SwitchStmt
130 // CHECK: br {{.*}} !prof !8
131 if (b)
132 [[unlikely]] switch (i) {}
133 else {
134 // Make sure the branches aren't optimized away.
135 b = true;
136 }
137 // CHECK-NOT: br {{.*}} %if.end{{.*}} !prof
138 if (b)
139 switch (i)
140 [[unlikely]] {}
141 else {
142 // Make sure the branches aren't optimized away.
143 b = true;
144 }
145 }
146
147 // CHECK: !7 = !{!"branch_weights", i32 [[UNLIKELY]], i32 [[LIKELY]]}
148 // CHECK: !8 = !{!"branch_weights", i32 [[LIKELY]], i32 [[UNLIKELY]]}
149