xref: /llvm-project/clang/test/Profile/c-general.c (revision 4f21fb84479286ddc781d73f8df152f81a8264e7)
1 // Test instrumentation of general constructs in C.
2 
3 // RUN: %clang_cc1 -triple x86_64-apple-macosx10.9 -main-file-name c-general.c %s -o - -emit-llvm -fprofile-instrument=clang | FileCheck -allow-deprecated-dag-overlap  -check-prefix=PGOGEN %s
4 
5 // RUN: llvm-profdata merge %S/Inputs/c-general.proftext -o %t.profdata
6 // RUN: %clang_cc1 -triple x86_64-apple-macosx10.9 -main-file-name c-general.c %s -o - -emit-llvm -fprofile-instrument-use-path=%t.profdata | FileCheck -allow-deprecated-dag-overlap  -check-prefix=PGOUSE %s
7 // RUN: %clang_cc1 -triple x86_64-apple-macosx10.9 -main-file-name c-general.c %s -o - -emit-llvm -fprofile-instrument-use-path=%S/Inputs/c-general.profdata.v5 | FileCheck -allow-deprecated-dag-overlap  -check-prefix=PGOUSE %s
8 // RUN: %clang_cc1 -triple x86_64-apple-macosx10.9 -main-file-name c-general.c %s -o - -emit-llvm -fprofile-instrument-use-path=%S/Inputs/c-general.profdata.v3 | FileCheck -allow-deprecated-dag-overlap  -check-prefix=PGOUSE %s
9 // Also check compatibility with older profiles.
10 // RUN: %clang_cc1 -triple x86_64-apple-macosx10.9 -main-file-name c-general.c %s -o - -emit-llvm -fprofile-instrument-use-path=%S/Inputs/c-general.profdata.v1 | FileCheck -allow-deprecated-dag-overlap  -check-prefix=PGOUSE %s
11 
12 // RUN: %clang -fprofile-generate -E -dM %s | FileCheck -match-full-lines -check-prefix=PROFGENMACRO %s
13 // RUN: %clang -fprofile-instr-generate -E -dM %s | FileCheck -match-full-lines -check-prefix=PROFGENMACRO %s
14 // RUN: %clang -fcs-profile-generate -E -dM %s | FileCheck -match-full-lines -check-prefix=PROFGENMACRO %s
15 //
16 // RUN: %clang -fprofile-use=%t.profdata -E -dM %s | FileCheck -match-full-lines -check-prefix=PROFUSEMACRO %s
17 // RUN: %clang -fprofile-instr-use=%t.profdata -E -dM %s | FileCheck -match-full-lines -check-prefix=PROFUSEMACRO %s
18 
19 // PROFGENMACRO:#define __LLVM_INSTR_PROFILE_GENERATE 1
20 // PROFUSEMACRO:#define __LLVM_INSTR_PROFILE_USE 1
21 
22 // PGOGEN: @[[SLC:__profc_simple_loops]] = private global [4 x i64] zeroinitializer
23 // PGOGEN: @[[IFC:__profc_conditionals]] = private global [13 x i64] zeroinitializer
24 // PGOGEN: @[[EEC:__profc_early_exits]] = private global [9 x i64] zeroinitializer
25 // PGOGEN: @[[JMC:__profc_jumps]] = private global [22 x i64] zeroinitializer
26 // PGOGEN: @[[SWC:__profc_switches]] = private global [19 x i64] zeroinitializer
27 // PGOGEN: @[[BSC:__profc_big_switch]] = private global [17 x i64] zeroinitializer
28 // PGOGEN: @[[BOC:__profc_boolean_operators]] = private global [14 x i64] zeroinitializer
29 // PGOGEN: @[[BLC:__profc_boolop_loops]] = private global [13 x i64] zeroinitializer
30 // PGOGEN: @[[COC:__profc_conditional_operator]] = private global [3 x i64] zeroinitializer
31 // PGOGEN: @[[DFC:__profc_do_fallthrough]] = private global [4 x i64] zeroinitializer
32 // PGOGEN: @[[MAC:__profc_main]] = private global [1 x i64] zeroinitializer
33 // PGOGEN: @[[STC:__profc_c_general.c_static_func]] = private global [2 x i64] zeroinitializer
34 
35 // PGOGEN-LABEL: @simple_loops()
36 // PGOUSE-LABEL: @simple_loops()
37 // PGOGEN: store {{.*}} @[[SLC]]
simple_loops(void)38 void simple_loops(void) {
39   int i;
40   // PGOGEN: store {{.*}} @[[SLC]], i32 0, i32 1
41   // PGOUSE: br {{.*}} !prof ![[SL1:[0-9]+]]
42   for (i = 0; i < 100; ++i) {
43   }
44   // PGOGEN: store {{.*}} @[[SLC]], i32 0, i32 2
45   // PGOUSE: br {{.*}} !prof ![[SL2:[0-9]+]]
46   while (i > 0)
47     i--;
48   // PGOGEN: store {{.*}} @[[SLC]], i32 0, i32 3
49   // PGOUSE: br {{.*}} !prof ![[SL3:[0-9]+]]
50   do {} while (i++ < 75);
51 
52   // PGOGEN-NOT: store {{.*}} @[[SLC]],
53   // PGOUSE-NOT: br {{.*}} !prof ![0-9]+
54 }
55 
56 // PGOGEN-LABEL: @conditionals()
57 // PGOUSE-LABEL: @conditionals()
58 // PGOGEN: store {{.*}} @[[IFC]]
conditionals(void)59 void conditionals(void) {
60   // PGOGEN: store {{.*}} @[[IFC]], i32 0, i32 1
61   // PGOUSE: br {{.*}} !prof ![[IF1:[0-9]+]]
62   for (int i = 0; i < 100; ++i) {
63     // PGOGEN: store {{.*}} @[[IFC]], i32 0, i32 2
64     // PGOUSE: br {{.*}} !prof ![[IF2:[0-9]+]]
65     if (i % 2) {
66       // PGOGEN: store {{.*}} @[[IFC]], i32 0, i32 3
67       // PGOUSE: br {{.*}} !prof ![[IF3:[0-9]+]]
68       if (i) {}
69       // PGOGEN: store {{.*}} @[[IFC]], i32 0, i32 4
70       // PGOUSE: br {{.*}} !prof ![[IF4:[0-9]+]]
71     } else if (i % 3) {
72       // PGOGEN: store {{.*}} @[[IFC]], i32 0, i32 5
73       // PGOUSE: br {{.*}} !prof ![[IF5:[0-9]+]]
74       if (i) {}
75     } else {
76       // PGOGEN: store {{.*}} @[[IFC]], i32 0, i32 6
77       // PGOUSE: br {{.*}} !prof ![[IF6:[0-9]+]]
78       if (i) {}
79     }
80 
81     // PGOGEN: store {{.*}} @[[IFC]], i32 0, i32 8
82     // PGOGEN: store {{.*}} @[[IFC]], i32 0, i32 9
83     // PGOGEN: store {{.*}} @[[IFC]], i32 0, i32 7
84     // PGOUSE: br {{.*}} !prof ![[IF7:[0-9]+]]
85     if (1 && i) {}
86     // PGOGEN: store {{.*}} @[[IFC]], i32 0, i32 11
87     // PGOGEN: store {{.*}} @[[IFC]], i32 0, i32 12
88     // PGOGEN: store {{.*}} @[[IFC]], i32 0, i32 10
89     // PGOUSE: br {{.*}} !prof ![[IF8:[0-9]+]]
90     if (0 || i) {}
91   }
92 
93   // PGOGEN-NOT: store {{.*}} @[[IFC]],
94   // PGOUSE-NOT: br {{.*}} !prof ![0-9]+
95 }
96 
97 // PGOGEN-LABEL: @early_exits()
98 // PGOUSE-LABEL: @early_exits()
99 // PGOGEN: store {{.*}} @[[EEC]]
early_exits(void)100 void early_exits(void) {
101   int i = 0;
102 
103   // PGOGEN: store {{.*}} @[[EEC]], i32 0, i32 1
104   // PGOUSE: br {{.*}} !prof ![[EE1:[0-9]+]]
105   if (i) {}
106 
107   // PGOGEN: store {{.*}} @[[EEC]], i32 0, i32 2
108   // PGOUSE: br {{.*}} !prof ![[EE2:[0-9]+]]
109   while (i < 100) {
110     i++;
111     // PGOGEN: store {{.*}} @[[EEC]], i32 0, i32 3
112     // PGOUSE: br {{.*}} !prof ![[EE3:[0-9]+]]
113     if (i > 50)
114       break;
115     // PGOGEN: store {{.*}} @[[EEC]], i32 0, i32 4
116     // PGOUSE: br {{.*}} !prof ![[EE4:[0-9]+]]
117     if (i % 2)
118       continue;
119   }
120 
121   // PGOGEN: store {{.*}} @[[EEC]], i32 0, i32 5
122   // PGOUSE: br {{.*}} !prof ![[EE5:[0-9]+]]
123   if (i) {}
124 
125   // PGOGEN: store {{.*}} @[[EEC]], i32 0, i32 6
126   do {
127     // PGOGEN: store {{.*}} @[[EEC]], i32 0, i32 7
128     // PGOUSE: br {{.*}} !prof ![[EE6:[0-9]+]]
129     if (i > 75)
130       return;
131     else
132       i++;
133   // PGOUSE: br {{.*}} !prof ![[EE7:[0-9]+]]
134   } while (i < 100);
135 
136   // PGOGEN: store {{.*}} @[[EEC]], i32 0, i32 8
137   // Never reached -> no weights
138   if (i) {}
139 
140   // PGOGEN-NOT: store {{.*}} @[[EEC]],
141   // PGOUSE-NOT: br {{.*}} !prof ![0-9]+
142 }
143 
144 // PGOGEN-LABEL: @jumps()
145 // PGOUSE-LABEL: @jumps()
146 // PGOGEN: store {{.*}} @[[JMC]]
jumps(void)147 void jumps(void) {
148   int i;
149 
150   // PGOGEN: store {{.*}} @[[JMC]], i32 0, i32 1
151   // PGOUSE: br {{.*}} !prof ![[JM1:[0-9]+]]
152   for (i = 0; i < 2; ++i) {
153     goto outofloop;
154     // Never reached -> no weights
155     if (i) {}
156   }
157 // PGOGEN: store {{.*}} @[[JMC]], i32 0, i32 3
158 outofloop:
159   // PGOGEN: store {{.*}} @[[JMC]], i32 0, i32 4
160   // PGOUSE: br {{.*}} !prof ![[JM2:[0-9]+]]
161   if (i) {}
162 
163   goto loop1;
164 
165   // PGOGEN: store {{.*}} @[[JMC]], i32 0, i32 5
166   // PGOUSE: br {{.*}} !prof ![[JM3:[0-9]+]]
167   while (i) {
168   // PGOGEN: store {{.*}} @[[JMC]], i32 0, i32 6
169   loop1:
170     // PGOGEN: store {{.*}} @[[JMC]], i32 0, i32 7
171     // PGOUSE: br {{.*}} !prof ![[JM4:[0-9]+]]
172     if (i) {}
173   }
174 
175   goto loop2;
176 // PGOGEN: store {{.*}} @[[JMC]], i32 0, i32 8
177 first:
178 // PGOGEN: store {{.*}} @[[JMC]], i32 0, i32 9
179 second:
180 // PGOGEN: store {{.*}} @[[JMC]], i32 0, i32 10
181 third:
182   i++;
183   // PGOGEN: store {{.*}} @[[JMC]], i32 0, i32 11
184   // PGOUSE: br {{.*}} !prof ![[JM5:[0-9]+]]
185   if (i < 3)
186     goto loop2;
187 
188   // PGOGEN: store {{.*}} @[[JMC]], i32 0, i32 12
189   // PGOUSE: br {{.*}} !prof ![[JM6:[0-9]+]]
190   while (i < 3) {
191   // PGOGEN: store {{.*}} @[[JMC]], i32 0, i32 13
192   loop2:
193     // PGOUSE: switch {{.*}} [
194     // PGOUSE: ], !prof ![[JM7:[0-9]+]]
195     switch (i) {
196     // PGOGEN: store {{.*}} @[[JMC]], i32 0, i32 15
197     case 0:
198       goto first;
199     // PGOGEN: store {{.*}} @[[JMC]], i32 0, i32 16
200     case 1:
201       goto second;
202     // PGOGEN: store {{.*}} @[[JMC]], i32 0, i32 17
203     case 2:
204       goto third;
205     }
206     // PGOGEN: store {{.*}} @[[JMC]], i32 0, i32 14
207   }
208 
209   // PGOGEN: store {{.*}} @[[JMC]], i32 0, i32 18
210   // PGOUSE: br {{.*}} !prof ![[JM8:[0-9]+]]
211   for (i = 0; i < 10; ++i) {
212     goto withinloop;
213     // never reached -> no weights
214     if (i) {}
215   // PGOGEN: store {{.*}} @[[JMC]], i32 0, i32 20
216   withinloop:
217     // PGOGEN: store {{.*}} @[[JMC]], i32 0, i32 21
218     // PGOUSE: br {{.*}} !prof ![[JM9:[0-9]+]]
219     if (i) {}
220   }
221 
222   // PGOGEN-NOT: store {{.*}} @[[JMC]],
223   // PGOUSE-NOT: br {{.*}} !prof ![0-9]+
224 }
225 
226 // PGOGEN-LABEL: @switches()
227 // PGOUSE-LABEL: @switches()
228 // PGOGEN: store {{.*}} @[[SWC]]
switches(void)229 void switches(void) {
230   static int weights[] = {1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5};
231 
232   // No cases -> no weights
233   switch (weights[0]) {
234   // PGOGEN: store {{.*}} @[[SWC]], i32 0, i32 2
235   default:
236     break;
237   }
238   // PGOGEN: store {{.*}} @[[SWC]], i32 0, i32 1
239 
240   // PGOGEN: store {{.*}} @[[SWC]], i32 0, i32 3
241   // PGOUSE: br {{.*}} !prof ![[SW1:[0-9]+]]
242   for (int i = 0, len = sizeof(weights) / sizeof(weights[0]); i < len; ++i) {
243     // PGOUSE: switch {{.*}} [
244     // PGOUSE: ], !prof ![[SW2:[0-9]+]]
245     switch (i[weights]) {
246     // PGOGEN: store {{.*}} @[[SWC]], i32 0, i32 5
247     case 1:
248       // PGOGEN: store {{.*}} @[[SWC]], i32 0, i32 6
249       // PGOUSE: br {{.*}} !prof ![[SW3:[0-9]+]]
250       if (i) {}
251       // fallthrough
252     // PGOGEN: store {{.*}} @[[SWC]], i32 0, i32 7
253     case 2:
254       // PGOGEN: store {{.*}} @[[SWC]], i32 0, i32 8
255       // PGOUSE: br {{.*}} !prof ![[SW4:[0-9]+]]
256       if (i) {}
257       break;
258     // PGOGEN: store {{.*}} @[[SWC]], i32 0, i32 9
259     case 3:
260       // PGOGEN: store {{.*}} @[[SWC]], i32 0, i32 10
261       // PGOUSE: br {{.*}} !prof ![[SW5:[0-9]+]]
262       if (i) {}
263       continue;
264     // PGOGEN: store {{.*}} @[[SWC]], i32 0, i32 11
265     case 4:
266       // PGOGEN: store {{.*}} @[[SWC]], i32 0, i32 12
267       // PGOUSE: br {{.*}} !prof ![[SW6:[0-9]+]]
268       if (i) {}
269       // PGOUSE: switch {{.*}} [
270       // PGOUSE: ], !prof ![[SW7:[0-9]+]]
271       switch (i) {
272       // PGOGEN: store {{.*}} @[[SWC]], i32 0, i32 14
273       case 6 ... 9:
274         // PGOGEN: store {{.*}} @[[SWC]], i32 0, i32 15
275         // PGOUSE: br {{.*}} !prof ![[SW8:[0-9]+]]
276         if (i) {}
277         continue;
278       }
279       // PGOGEN: store {{.*}} @[[SWC]], i32 0, i32 13
280 
281     // PGOGEN: store {{.*}} @[[SWC]], i32 0, i32 16
282     default:
283       // PGOGEN: store {{.*}} @[[SWC]], i32 0, i32 17
284       // PGOUSE: br {{.*}} !prof ![[SW9:[0-9]+]]
285       if (i == len - 1)
286         return;
287     }
288     // PGOGEN: store {{.*}} @[[SWC]], i32 0, i32 4
289   }
290 
291   // PGOGEN: store {{.*}} @[[SWC]], i32 0, i32 18
292   // Never reached -> no weights
293   if (weights[0]) {}
294 
295   // PGOGEN-NOT: store {{.*}} @[[SWC]],
296   // PGOUSE-NOT: br {{.*}} !prof ![0-9]+
297 }
298 
299 // PGOGEN-LABEL: @big_switch()
300 // PGOUSE-LABEL: @big_switch()
301 // PGOGEN: store {{.*}} @[[BSC]]
big_switch(void)302 void big_switch(void) {
303   // PGOGEN: store {{.*}} @[[BSC]], i32 0, i32 1
304   // PGOUSE: br {{.*}} !prof ![[BS1:[0-9]+]]
305   for (int i = 0; i < 32; ++i) {
306     // PGOUSE: switch {{.*}} [
307     // PGOUSE: ], !prof ![[BS2:[0-9]+]]
308     switch (1 << i) {
309     // PGOGEN: store {{.*}} @[[BSC]], i32 0, i32 3
310     case (1 << 0):
311       // PGOGEN: store {{.*}} @[[BSC]], i32 0, i32 4
312       // PGOUSE: br {{.*}} !prof ![[BS3:[0-9]+]]
313       if (i) {}
314       // fallthrough
315     // PGOGEN: store {{.*}} @[[BSC]], i32 0, i32 5
316     case (1 << 1):
317       // PGOGEN: store {{.*}} @[[BSC]], i32 0, i32 6
318       // PGOUSE: br {{.*}} !prof ![[BS4:[0-9]+]]
319       if (i) {}
320       break;
321     // PGOGEN: store {{.*}} @[[BSC]], i32 0, i32 7
322     case (1 << 2) ... (1 << 12):
323       // PGOGEN: store {{.*}} @[[BSC]], i32 0, i32 8
324       // PGOUSE: br {{.*}} !prof ![[BS5:[0-9]+]]
325       if (i) {}
326       break;
327     // The branch for the large case range above appears after the case body
328     // PGOUSE: br {{.*}} !prof ![[BS6:[0-9]+]]
329 
330     // PGOGEN: store {{.*}} @[[BSC]], i32 0, i32 9
331     case (1 << 13):
332       // PGOGEN: store {{.*}} @[[BSC]], i32 0, i32 10
333       // PGOUSE: br {{.*}} !prof ![[BS7:[0-9]+]]
334       if (i) {}
335       break;
336     // PGOGEN: store {{.*}} @[[BSC]], i32 0, i32 11
337     case (1 << 14) ... (1 << 28):
338       // PGOGEN: store {{.*}} @[[BSC]], i32 0, i32 12
339       // PGOUSE: br {{.*}} !prof ![[BS8:[0-9]+]]
340       if (i) {}
341       break;
342     // The branch for the large case range above appears after the case body
343     // PGOUSE: br {{.*}} !prof ![[BS9:[0-9]+]]
344 
345     // PGOGEN: store {{.*}} @[[BSC]], i32 0, i32 13
346     case (1 << 29) ... ((1 << 29) + 1):
347       // PGOGEN: store {{.*}} @[[BSC]], i32 0, i32 14
348       // PGOUSE: br {{.*}} !prof ![[BS10:[0-9]+]]
349       if (i) {}
350       break;
351     // PGOGEN: store {{.*}} @[[BSC]], i32 0, i32 15
352     default:
353       // PGOGEN: store {{.*}} @[[BSC]], i32 0, i32 16
354       // PGOUSE: br {{.*}} !prof ![[BS11:[0-9]+]]
355       if (i) {}
356       break;
357     }
358     // PGOGEN: store {{.*}} @[[BSC]], i32 0, i32 2
359   }
360 
361   // PGOGEN-NOT: store {{.*}} @[[BSC]],
362   // PGOUSE-NOT: br {{.*}} !prof ![0-9]+
363   // PGOUSE: ret void
364 }
365 
366 // PGOGEN-LABEL: @boolean_operators()
367 // PGOUSE-LABEL: @boolean_operators()
368 // PGOGEN: store {{.*}} @[[BOC]]
boolean_operators(void)369 void boolean_operators(void) {
370   int v;
371   // PGOGEN: store {{.*}} @[[BOC]], i32 0, i32 1
372   // PGOUSE: br {{.*}} !prof ![[BO1:[0-9]+]]
373   for (int i = 0; i < 100; ++i) {
374     // PGOGEN: store {{.*}} @[[BOC]], i32 0, i32 2
375     // PGOGEN: store {{.*}} @[[BOC]], i32 0, i32 3
376     // PGOUSE: br {{.*}} !prof ![[BO2:[0-9]+]]
377     v = i % 3 || i;
378 
379     // PGOGEN: store {{.*}} @[[BOC]], i32 0, i32 4
380     // PGOGEN: store {{.*}} @[[BOC]], i32 0, i32 5
381     // PGOUSE: br {{.*}} !prof ![[BO3:[0-9]+]]
382     v = i % 3 && i;
383 
384     // PGOGEN: store {{.*}} @[[BOC]], i32 0, i32 8
385     // PGOGEN: store {{.*}} @[[BOC]], i32 0, i32 9
386     // PGOGEN: store {{.*}} @[[BOC]], i32 0, i32 6
387     // PGOGEN: store {{.*}} @[[BOC]], i32 0, i32 7
388     // PGOUSE: br {{.*}} !prof ![[BO4:[0-9]+]]
389     // PGOUSE: br {{.*}} !prof ![[BO5:[0-9]+]]
390     v = i % 3 || i % 2 || i;
391 
392     // PGOGEN: store {{.*}} @[[BOC]], i32 0, i32 12
393     // PGOGEN: store {{.*}} @[[BOC]], i32 0, i32 13
394     // PGOGEN: store {{.*}} @[[BOC]], i32 0, i32 10
395     // PGOGEN: store {{.*}} @[[BOC]], i32 0, i32 11
396     // PGOUSE: br {{.*}} !prof ![[BO6:[0-9]+]]
397     // PGOUSE: br {{.*}} !prof ![[BO7:[0-9]+]]
398     v = i % 2 && i % 3 && i;
399   }
400 
401   // PGOGEN-NOT: store {{.*}} @[[BOC]],
402   // PGOUSE-NOT: br {{.*}} !prof ![0-9]+
403 }
404 
405 // PGOGEN-LABEL: @boolop_loops()
406 // PGOUSE-LABEL: @boolop_loops()
407 // PGOGEN: store {{.*}} @[[BLC]]
boolop_loops(void)408 void boolop_loops(void) {
409   int i = 100;
410 
411   // PGOGEN: store {{.*}} @[[BLC]], i32 0, i32 2
412   // PGOGEN: store {{.*}} @[[BLC]], i32 0, i32 3
413   // PGOGEN: store {{.*}} @[[BLC]], i32 0, i32 1
414   // PGOUSE: br {{.*}} !prof ![[BL1:[0-9]+]]
415   // PGOUSE: br {{.*}} !prof ![[BL2:[0-9]+]]
416   while (i && i > 50)
417     i--;
418 
419   // PGOGEN: store {{.*}} @[[BLC]], i32 0, i32 5
420   // PGOGEN: store {{.*}} @[[BLC]], i32 0, i32 6
421   // PGOGEN: store {{.*}} @[[BLC]], i32 0, i32 4
422   // PGOUSE: br {{.*}} !prof ![[BL3:[0-9]+]]
423   // PGOUSE: br {{.*}} !prof ![[BL4:[0-9]+]]
424   while ((i % 2) || (i > 0))
425     i--;
426 
427   // PGOGEN: store {{.*}} @[[BLC]], i32 0, i32 8
428   // PGOGEN: store {{.*}} @[[BLC]], i32 0, i32 9
429   // PGOGEN: store {{.*}} @[[BLC]], i32 0, i32 7
430   // PGOUSE: br {{.*}} !prof ![[BL5:[0-9]+]]
431   // PGOUSE: br {{.*}} !prof ![[BL6:[0-9]+]]
432   for (i = 100; i && i > 50; --i);
433 
434   // PGOGEN: store {{.*}} @[[BLC]], i32 0, i32 11
435   // PGOGEN: store {{.*}} @[[BLC]], i32 0, i32 12
436   // PGOGEN: store {{.*}} @[[BLC]], i32 0, i32 10
437   // PGOUSE: br {{.*}} !prof ![[BL7:[0-9]+]]
438   // PGOUSE: br {{.*}} !prof ![[BL8:[0-9]+]]
439   for (; (i % 2) || (i > 0); --i);
440 
441   // PGOGEN-NOT: store {{.*}} @[[BLC]],
442   // PGOUSE-NOT: br {{.*}} !prof ![0-9]+
443 }
444 
445 // PGOGEN-LABEL: @conditional_operator()
446 // PGOUSE-LABEL: @conditional_operator()
447 // PGOGEN: store {{.*}} @[[COC]]
conditional_operator(void)448 void conditional_operator(void) {
449   int i = 100;
450 
451   // PGOGEN: store {{.*}} @[[COC]], i32 0, i32 1
452   // PGOUSE: br {{.*}} !prof ![[CO1:[0-9]+]]
453   int j = i < 50 ? i : 1;
454 
455   // PGOGEN: store {{.*}} @[[COC]], i32 0, i32 2
456   // PGOUSE: br {{.*}} !prof ![[CO2:[0-9]+]]
457   int k = i ?: 0;
458 
459   // PGOGEN-NOT: store {{.*}} @[[COC]],
460   // PGOUSE-NOT: br {{.*}} !prof ![0-9]+
461 }
462 
463 // PGOGEN-LABEL: @do_fallthrough()
464 // PGOUSE-LABEL: @do_fallthrough()
465 // PGOGEN: store {{.*}} @[[DFC]]
do_fallthrough(void)466 void do_fallthrough(void) {
467   // PGOGEN: store {{.*}} @[[DFC]], i32 0, i32 1
468   // PGOUSE: br {{.*}} !prof ![[DF1:[0-9]+]]
469   for (int i = 0; i < 10; ++i) {
470     int j = 0;
471     // PGOGEN: store {{.*}} @[[DFC]], i32 0, i32 2
472     do {
473       // The number of exits out of this do-loop via the break statement
474       // exceeds the counter value for the loop (which does not include the
475       // fallthrough count). Make sure that does not violate any assertions.
476       // PGOGEN: store {{.*}} @[[DFC]], i32 0, i32 3
477       // PGOUSE: br {{.*}} !prof ![[DF3:[0-9]+]]
478       if (i < 8) break;
479       j++;
480     // PGOUSE: br {{.*}} !prof ![[DF2:[0-9]+]]
481     } while (j < 2);
482   }
483 }
484 
485 // PGOGEN-LABEL: @static_func()
486 // PGOUSE-LABEL: @static_func()
487 // PGOGEN: store {{.*}} @[[STC]]
static_func(void)488 static void static_func(void) {
489   // PGOGEN: store {{.*}} @[[STC]], i32 0, i32 1
490   // PGOUSE: br {{.*}} !prof ![[ST1:[0-9]+]]
491   for (int i = 0; i < 10; ++i) {
492   }
493 }
494 
495 // PGOUSE-DAG: ![[SL1]] = !{!"branch_weights", i32 101, i32 2}
496 // PGOUSE-DAG: ![[SL2]] = !{!"branch_weights", i32 101, i32 2}
497 // PGOUSE-DAG: ![[SL3]] = !{!"branch_weights", i32 76, i32 2}
498 
499 // PGOUSE-DAG: ![[EE1]] = !{!"branch_weights", i32 1, i32 2}
500 // PGOUSE-DAG: ![[EE2]] = !{!"branch_weights", i32 52, i32 1}
501 // PGOUSE-DAG: ![[EE3]] = !{!"branch_weights", i32 2, i32 51}
502 // PGOUSE-DAG: ![[EE4]] = !{!"branch_weights", i32 26, i32 26}
503 // PGOUSE-DAG: ![[EE5]] = !{!"branch_weights", i32 2, i32 1}
504 // PGOUSE-DAG: ![[EE6]] = !{!"branch_weights", i32 2, i32 26}
505 // PGOUSE-DAG: ![[EE7]] = !{!"branch_weights", i32 26, i32 1}
506 
507 // PGOUSE-DAG: ![[IF1]] = !{!"branch_weights", i32 101, i32 2}
508 // PGOUSE-DAG: ![[IF2]] = !{!"branch_weights", i32 51, i32 51}
509 // PGOUSE-DAG: ![[IF3]] = !{!"branch_weights", i32 51, i32 1}
510 // PGOUSE-DAG: ![[IF4]] = !{!"branch_weights", i32 34, i32 18}
511 // PGOUSE-DAG: ![[IF5]] = !{!"branch_weights", i32 34, i32 1}
512 // PGOUSE-DAG: ![[IF6]] = !{!"branch_weights", i32 17, i32 2}
513 // PGOUSE-DAG: ![[IF7]] = !{!"branch_weights", i32 100, i32 2}
514 // PGOUSE-DAG: ![[IF8]] = !{!"branch_weights", i32 100, i32 2}
515 
516 // PGOUSE-DAG: ![[JM1]] = !{!"branch_weights", i32 2, i32 1}
517 // PGOUSE-DAG: ![[JM2]] = !{!"branch_weights", i32 1, i32 2}
518 // PGOUSE-DAG: ![[JM3]] = !{!"branch_weights", i32 1, i32 2}
519 // PGOUSE-DAG: ![[JM4]] = !{!"branch_weights", i32 1, i32 2}
520 // PGOUSE-DAG: ![[JM5]] = !{!"branch_weights", i32 3, i32 2}
521 // PGOUSE-DAG: ![[JM6]] = !{!"branch_weights", i32 1, i32 2}
522 // PGOUSE-DAG: ![[JM7]] = !{!"branch_weights", i32 1, i32 2, i32 2, i32 2}
523 // PGOUSE-DAG: ![[JM8]] = !{!"branch_weights", i32 11, i32 2}
524 // PGOUSE-DAG: ![[JM9]] = !{!"branch_weights", i32 10, i32 2}
525 
526 // PGOUSE-DAG: ![[SW1]] = !{!"branch_weights", i32 16, i32 1}
527 // PGOUSE-DAG: ![[SW2]] = !{!"branch_weights", i32 6, i32 2, i32 3, i32 4, i32 5}
528 // PGOUSE-DAG: ![[SW3]] = !{!"branch_weights", i32 1, i32 2}
529 // PGOUSE-DAG: ![[SW4]] = !{!"branch_weights", i32 3, i32 2}
530 // PGOUSE-DAG: ![[SW5]] = !{!"branch_weights", i32 4, i32 1}
531 // PGOUSE-DAG: ![[SW6]] = !{!"branch_weights", i32 5, i32 1}
532 // PGOUSE-DAG: ![[SW7]] = !{!"branch_weights", i32 1, i32 2, i32 2, i32 2, i32 2}
533 // PGOUSE-DAG: ![[SW8]] = !{!"branch_weights", i32 5, i32 1}
534 // PGOUSE-DAG: ![[SW9]] = !{!"branch_weights", i32 2, i32 5}
535 
536 // PGOUSE-DAG: ![[BS1]] = !{!"branch_weights", i32 33, i32 2}
537 // PGOUSE-DAG: ![[BS2]] = !{!"branch_weights", i32 29, i32 2, i32 2, i32 2, i32 2, i32 1}
538 // PGOUSE-DAG: ![[BS3]] = !{!"branch_weights", i32 1, i32 2}
539 // PGOUSE-DAG: ![[BS4]] = !{!"branch_weights", i32 2, i32 2}
540 // PGOUSE-DAG: ![[BS5]] = !{!"branch_weights", i32 12, i32 1}
541 // PGOUSE-DAG: ![[BS6]] = !{!"branch_weights", i32 12, i32 3}
542 // PGOUSE-DAG: ![[BS7]] = !{!"branch_weights", i32 2, i32 1}
543 // PGOUSE-DAG: ![[BS8]] = !{!"branch_weights", i32 16, i32 1}
544 // PGOUSE-DAG: ![[BS9]] = !{!"branch_weights", i32 16, i32 14}
545 // PGOUSE-DAG: ![[BS10]] = !{!"branch_weights", i32 2, i32 1}
546 // PGOUSE-DAG: ![[BS11]] = !{!"branch_weights", i32 3, i32 1}
547 
548 // PGOUSE-DAG: ![[BO1]] = !{!"branch_weights", i32 101, i32 2}
549 // PGOUSE-DAG: ![[BO2]] = !{!"branch_weights", i32 67, i32 35}
550 // PGOUSE-DAG: ![[BO3]] = !{!"branch_weights", i32 67, i32 35}
551 // PGOUSE-DAG: ![[BO4]] = !{!"branch_weights", i32 67, i32 35}
552 // PGOUSE-DAG: ![[BO5]] = !{!"branch_weights", i32 18, i32 18}
553 // PGOUSE-DAG: ![[BO6]] = !{!"branch_weights", i32 51, i32 51}
554 // PGOUSE-DAG: ![[BO7]] = !{!"branch_weights", i32 34, i32 18}
555 // PGOUSE-DAG: ![[BL1]] = !{!"branch_weights", i32 52, i32 1}
556 // PGOUSE-DAG: ![[BL2]] = !{!"branch_weights", i32 51, i32 2}
557 // PGOUSE-DAG: ![[BL3]] = !{!"branch_weights", i32 26, i32 27}
558 // PGOUSE-DAG: ![[BL4]] = !{!"branch_weights", i32 51, i32 2}
559 // PGOUSE-DAG: ![[BL5]] = !{!"branch_weights", i32 52, i32 1}
560 // PGOUSE-DAG: ![[BL6]] = !{!"branch_weights", i32 51, i32 2}
561 // PGOUSE-DAG: ![[BL7]] = !{!"branch_weights", i32 26, i32 27}
562 // PGOUSE-DAG: ![[BL8]] = !{!"branch_weights", i32 51, i32 2}
563 // PGOUSE-DAG: ![[CO1]] = !{!"branch_weights", i32 1, i32 2}
564 // PGOUSE-DAG: ![[CO2]] = !{!"branch_weights", i32 2, i32 1}
565 
566 // PGOUSE-DAG: ![[DF1]] = !{!"branch_weights", i32 11, i32 2}
567 // PGOUSE-DAG: ![[DF2]] = !{!"branch_weights", i32 3, i32 3}
568 // PGOUSE-DAG: ![[DF3]] = !{!"branch_weights", i32 9, i32 5}
569 
570 // PGOUSE-DAG: ![[ST1]] = !{!"branch_weights", i32 11, i32 2}
571 
main(int argc,const char * argv[])572 int main(int argc, const char *argv[]) {
573   simple_loops();
574   conditionals();
575   early_exits();
576   jumps();
577   switches();
578   big_switch();
579   boolean_operators();
580   boolop_loops();
581   conditional_operator();
582   do_fallthrough();
583   static_func();
584   return 0;
585 }
586