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 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 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 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 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 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 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 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 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 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 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 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