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