xref: /llvm-project/clang/test/Profile/c-counter-overflows.c (revision 5c31b8b94fddc7c109672964c72670430fe30887)
1*5c31b8b9SArthur Eubanks // Test that big branch weights get scaled down to 32-bits, rather than just
2*5c31b8b9SArthur Eubanks // truncated.
3*5c31b8b9SArthur Eubanks 
4*5c31b8b9SArthur Eubanks // RUN: llvm-profdata merge %S/Inputs/c-counter-overflows.proftext -o %t.profdata
5*5c31b8b9SArthur Eubanks // RUN: %clang_cc1 -triple x86_64-apple-macosx10.9 -main-file-name c-counter-overflows.c %s -o - -emit-llvm -fprofile-instrument-use-path=%t.profdata | FileCheck %s
6*5c31b8b9SArthur Eubanks 
7*5c31b8b9SArthur Eubanks typedef unsigned long long uint64_t;
8*5c31b8b9SArthur Eubanks 
main(int argc,const char * argv[])9*5c31b8b9SArthur Eubanks int main(int argc, const char *argv[]) {
10*5c31b8b9SArthur Eubanks   // Need counts higher than 32-bits.
11*5c31b8b9SArthur Eubanks   // CHECK: br {{.*}} !prof ![[FOR:[0-9]+]]
12*5c31b8b9SArthur Eubanks   // max   = 0xffffffff0
13*5c31b8b9SArthur Eubanks   // scale = 0xffffffff0 / 0xffffffff + 1 = 17
14*5c31b8b9SArthur Eubanks   // loop-body: 0xffffffff0 / 17 + 1 = 0xf0f0f0f0 + 1 = 4042322161 => -252645135
15*5c31b8b9SArthur Eubanks   // loop-exit: 0x000000001 / 17 + 1 = 0x00000000 + 1 =          1 =>          1
16*5c31b8b9SArthur Eubanks   for (uint64_t I = 0; I < 0xffffffff0; ++I) {
17*5c31b8b9SArthur Eubanks     // max   = 0xffffffff * 15 = 0xefffffff1
18*5c31b8b9SArthur Eubanks     // scale = 0xefffffff1 / 0xffffffff + 1 = 16
19*5c31b8b9SArthur Eubanks     // CHECK: br {{.*}} !prof ![[IF:[0-9]+]]
20*5c31b8b9SArthur Eubanks     if (I & 0xf) {
21*5c31b8b9SArthur Eubanks       // 0xefffffff1 / 16 + 1 = 0xefffffff + 1 = 4026531840 => -268435456
22*5c31b8b9SArthur Eubanks     } else {
23*5c31b8b9SArthur Eubanks       // 0x0ffffffff / 16 + 1 = 0x0fffffff + 1 =  268435456 =>  268435456
24*5c31b8b9SArthur Eubanks     }
25*5c31b8b9SArthur Eubanks 
26*5c31b8b9SArthur Eubanks     // max   = 0xffffffff * 5 = 0x4fffffffb
27*5c31b8b9SArthur Eubanks     // scale = 0x4fffffffb / 0xffffffff + 1 = 6
28*5c31b8b9SArthur Eubanks     // CHECK: ], !prof ![[SWITCH:[0-9]+]]
29*5c31b8b9SArthur Eubanks     switch ((I & 0xf) / 5) {
30*5c31b8b9SArthur Eubanks     case 0:
31*5c31b8b9SArthur Eubanks       // 0x4fffffffb / 6 = 0xd5555554 + 1 = 3579139413 => -715827883
32*5c31b8b9SArthur Eubanks       break;
33*5c31b8b9SArthur Eubanks     case 1:
34*5c31b8b9SArthur Eubanks       // 0x4fffffffb / 6 = 0xd5555554 + 1 = 3579139413 => -715827883
35*5c31b8b9SArthur Eubanks       break;
36*5c31b8b9SArthur Eubanks     case 2:
37*5c31b8b9SArthur Eubanks       // 0x4fffffffb / 6 = 0xd5555554 + 1 = 3579139413 => -715827883
38*5c31b8b9SArthur Eubanks       break;
39*5c31b8b9SArthur Eubanks     default:
40*5c31b8b9SArthur Eubanks       // 0x0ffffffff / 6 = 0x2aaaaaaa + 1 =  715827883 =>  715827883
41*5c31b8b9SArthur Eubanks       break;
42*5c31b8b9SArthur Eubanks     }
43*5c31b8b9SArthur Eubanks   }
44*5c31b8b9SArthur Eubanks   return 0;
45*5c31b8b9SArthur Eubanks }
46*5c31b8b9SArthur Eubanks 
47*5c31b8b9SArthur Eubanks // CHECK-DAG: ![[FOR]] = !{!"branch_weights", i32 -252645135, i32 1}
48*5c31b8b9SArthur Eubanks // CHECK-DAG: ![[IF]]  = !{!"branch_weights", i32 -268435456, i32 268435456}
49*5c31b8b9SArthur Eubanks // CHECK-DAG: ![[SWITCH]] = !{!"branch_weights", i32 715827883, i32 -715827883, i32 -715827883, i32 -715827883}
50