1 // RUN: %clang_cc1 -O1 -disable-llvm-passes -emit-llvm %s -o - -triple=x86_64-linux-gnu | opt --lower-expect -S | FileCheck %s
2 
3 // Verifies the output of __builtin_expect versus the output of the likelihood
4 // attributes. They should generate the same probabilities for the branches.
5 
6 extern bool a();
7 extern bool b();
8 extern bool c();
9 
ab1(int & i)10 void ab1(int &i) {
11   // CHECK-LABEL: define{{.*}}ab1
12   // CHECK: br {{.*}} !prof !6
13   // CHECK: br {{.*}} !prof !6
14   // CHECK: br {{.*}} !prof !6
15   if (__builtin_expect(a() && b() && a(), 1)) {
16     ++i;
17   } else {
18     --i;
19   }
20 }
21 
al(int & i)22 void al(int &i) {
23   // CHECK-LABEL: define{{.*}}al
24   // CHECK: br {{.*}} !prof !6
25   // CHECK: br {{.*}} !prof !6
26   // CHECK: br {{.*}} !prof !6
27   if (a() && b() && c()) [[likely]] {
28     ++i;
29   } else {
30     --i;
31   }
32 }
33 
ab0(int & i)34 void ab0(int &i) {
35   // CHECK-LABEL: define{{.*}}ab0
36   // CHECK: br {{.*}}end{{$}}
37   // CHECK: br {{.*}}end{{$}}
38   // CHECK: br {{.*}}end{{$}}
39   // CHECK: br {{.*}} !prof !9
40   if (__builtin_expect(a() && b() && c(), 0)) {
41     ++i;
42   } else {
43     --i;
44   }
45 }
46 
au(int & i)47 void au(int &i) {
48   // CHECK-LABEL: define{{.*}}au
49   // CHECK: br {{.*}}else{{$}}
50   // CHECK: br {{.*}}else{{$}}
51   // CHECK: br {{.*}} !prof !9
52   if (a() && b() && c()) [[unlikely]] {
53     ++i;
54   } else {
55     --i;
56   }
57 }
58 
ob1(int & i)59 void ob1(int &i) {
60   // CHECK-LABEL: define{{.*}}ob1
61   // CHECK: br {{.*}}false{{$}}
62   // CHECK: br {{.*}}rhs{{$}}
63   // CHECK: br {{.*}}end{{$}}
64   // CHECK: br {{.*}} !prof !6
65   if (__builtin_expect(a() || b() || a(), 1)) {
66     i = 0;
67   } else {
68     --i;
69   }
70 }
71 
ol(int & i)72 void ol(int &i) {
73   // CHECK-LABEL: define{{.*}}ol
74   // CHECK: br {{.*}}false{{$}}
75   // CHECK: br {{.*}}false2{{$}}
76   // CHECK: br {{.*}} !prof !6
77   if (a() || b() || c()) [[likely]] {
78     i = 0;
79   } else {
80     --i;
81   }
82 }
83 
ob0(int & i)84 void ob0(int &i) {
85   // CHECK-LABEL: define{{.*}}ob0
86   // CHECK: br {{.*}} !prof !9
87   // CHECK: br {{.*}} !prof !9
88   // CHECK: br {{.*}} !prof !9
89   if (__builtin_expect(a() || b() || c(), 0)) {
90     i = 0;
91   } else {
92     --i;
93   }
94 }
95 
ou(int & i)96 void ou(int &i) {
97   // CHECK-LABEL: define{{.*}}ou
98   // CHECK: br {{.*}} !prof !9
99   // CHECK: br {{.*}} !prof !9
100   // CHECK: br {{.*}} !prof !9
101   if (a() || b() || c()) [[unlikely]] {
102     i = 0;
103   } else {
104     --i;
105   }
106 }
107 
nb1(int & i)108 void nb1(int &i) {
109   // CHECK-LABEL: define{{.*}}nb1
110   // CHECK: br {{.*}} !prof !6
111   if (__builtin_expect(!a(), 1)) {
112     ++i;
113   } else {
114     --i;
115   }
116 }
117 
nl(int & i)118 void nl(int &i) {
119   // CHECK-LABEL: define{{.*}}nl
120   // CHECK: br {{.*}} !prof !6
121   if (bool d = !a()) [[likely]] {
122     ++i;
123   } else {
124     --i;
125   }
126 }
127 
nb0(int & i)128 void nb0(int &i) {
129   // CHECK-LABEL: define{{.*}}nb0
130   // CHECK: br {{.*}} !prof !9
131   if (__builtin_expect(!a(), 0)) {
132     ++i;
133   } else {
134     --i;
135   }
136 }
137 
nu(int & i)138 void nu(int &i) {
139   // CHECK-LABEL: define{{.*}}nu
140   // CHECK: br {{.*}} !prof !9
141   if (bool d = !a()) [[unlikely]] {
142     ++i;
143   } else {
144     --i;
145   }
146 }
147 
tb1(int & i)148 void tb1(int &i) {
149   // CHECK-LABEL: define{{.*}}tb1
150   // CHECK: br {{.*}}false{{$}}
151   // CHECK: br {{.*}}end{{$}}
152   // CHECK: br {{.*}}end{{$}}
153   // CHECK: br {{.*}} !prof !6
154   if (__builtin_expect(a() ? b() : c(), 1)) {
155     ++i;
156   } else {
157     --i;
158   }
159 }
160 
tl(int & i)161 void tl(int &i) {
162   // CHECK-LABEL: define{{.*}}tl
163   // CHECK: br {{.*}}false{{$}}
164   // CHECK: br {{.*}}end{{$}}
165   // CHECK: br {{.*}}end{{$}}
166   // CHECK: br {{.*}} !prof !6
167   if (bool d = a() ? b() : c()) [[likely]] {
168     ++i;
169   } else {
170     --i;
171   }
172 }
173 
tl2(int & i)174 void tl2(int &i) {
175   // CHECK-LABEL: define{{.*}}tl
176   // CHECK: br {{.*}}false{{$}}
177   // CHECK: br {{.*}} !prof !6
178   // CHECK: br {{.*}} !prof !6
179   if (a() ? b() : c()) [[likely]] {
180     ++i;
181   } else {
182     --i;
183   }
184 }
185 
tb0(int & i)186 void tb0(int &i) {
187   // CHECK-LABEL: define{{.*}}tb0
188   // CHECK: br {{.*}}false{{$}}
189   // CHECK: br {{.*}}end{{$}}
190   // CHECK: br {{.*}}end{{$}}
191   // CHECK: br {{.*}} !prof !9
192   if (__builtin_expect(a() ? b() : c(), 0)) {
193     ++i;
194   } else {
195     --i;
196   }
197 }
198 
tu(int & i)199 void tu(int &i) {
200   // CHECK-LABEL: define{{.*}}tu
201   // CHECK: br {{.*}}false{{$}}
202   // CHECK: br {{.*}}end{{$}}
203   // CHECK: br {{.*}}end{{$}}
204   // CHECK: br {{.*}} !prof !9
205   if (bool d = a() ? b() : c()) [[unlikely]] {
206     ++i;
207   } else {
208     --i;
209   }
210 }
211 
tu2(int & i)212 void tu2(int &i) {
213   // CHECK-LABEL: define{{.*}}tu
214   // CHECK: br {{.*}}false{{$}}
215   // CHECK: br {{.*}} !prof !9
216   // CHECK: br {{.*}} !prof !9
217   if (a() ? b() : c()) [[unlikely]] {
218     ++i;
219   } else {
220     --i;
221   }
222 }
223 
224 // CHECK: !6 = !{!"branch_weights", i32 2000, i32 1}
225 // CHECK: !9 = !{!"branch_weights", i32 1, i32 2000}
226