1 // RUN: %clang_cc1 -O1 -disable-llvm-passes -emit-llvm %s -o - -triple=x86_64-linux-gnu | opt -passes=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 10 void ab1(int &i) { 11 // CHECK-LABEL: define{{.*}}ab1 12 // CHECK: br {{.*}} !prof [[BW_LIKELY:!.+]] 13 // CHECK: br {{.*}} !prof [[BW_LIKELY]] 14 // CHECK: br {{.*}} !prof [[BW_LIKELY]] 15 if (__builtin_expect(a() && b() && a(), 1)) { 16 ++i; 17 } else { 18 --i; 19 } 20 } 21 22 void al(int &i) { 23 // CHECK-LABEL: define{{.*}}al 24 // CHECK: br {{.*}} !prof [[BW_LIKELY]] 25 // CHECK: br {{.*}} !prof [[BW_LIKELY]] 26 // CHECK: br {{.*}} !prof [[BW_LIKELY]] 27 if (a() && b() && c()) [[likely]] { 28 ++i; 29 } else { 30 --i; 31 } 32 } 33 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 [[BW_UNLIKELY:!.+]] 40 if (__builtin_expect(a() && b() && c(), 0)) { 41 ++i; 42 } else { 43 --i; 44 } 45 } 46 47 void au(int &i) { 48 // CHECK-LABEL: define{{.*}}au 49 // CHECK: br {{.*}}else{{$}} 50 // CHECK: br {{.*}}else{{$}} 51 // CHECK: br {{.*}} !prof [[BW_UNLIKELY]] 52 if (a() && b() && c()) [[unlikely]] { 53 ++i; 54 } else { 55 --i; 56 } 57 } 58 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 [[BW_LIKELY]] 65 if (__builtin_expect(a() || b() || a(), 1)) { 66 i = 0; 67 } else { 68 --i; 69 } 70 } 71 72 void ol(int &i) { 73 // CHECK-LABEL: define{{.*}}ol 74 // CHECK: br {{.*}}false{{$}} 75 // CHECK: br {{.*}}false2{{$}} 76 // CHECK: br {{.*}} !prof [[BW_LIKELY]] 77 if (a() || b() || c()) [[likely]] { 78 i = 0; 79 } else { 80 --i; 81 } 82 } 83 84 void ob0(int &i) { 85 // CHECK-LABEL: define{{.*}}ob0 86 // CHECK: br {{.*}} !prof [[BW_UNLIKELY]] 87 // CHECK: br {{.*}} !prof [[BW_UNLIKELY]] 88 // CHECK: br {{.*}} !prof [[BW_UNLIKELY]] 89 if (__builtin_expect(a() || b() || c(), 0)) { 90 i = 0; 91 } else { 92 --i; 93 } 94 } 95 96 void ou(int &i) { 97 // CHECK-LABEL: define{{.*}}ou 98 // CHECK: br {{.*}} !prof [[BW_UNLIKELY]] 99 // CHECK: br {{.*}} !prof [[BW_UNLIKELY]] 100 // CHECK: br {{.*}} !prof [[BW_UNLIKELY]] 101 if (a() || b() || c()) [[unlikely]] { 102 i = 0; 103 } else { 104 --i; 105 } 106 } 107 108 void nb1(int &i) { 109 // CHECK-LABEL: define{{.*}}nb1 110 // CHECK: br {{.*}} !prof [[BW_LIKELY]] 111 if (__builtin_expect(!a(), 1)) { 112 ++i; 113 } else { 114 --i; 115 } 116 } 117 118 void nl(int &i) { 119 // CHECK-LABEL: define{{.*}}nl 120 // CHECK: br {{.*}} !prof [[BW_LIKELY]] 121 if (bool d = !a()) [[likely]] { 122 ++i; 123 } else { 124 --i; 125 } 126 } 127 128 void nb0(int &i) { 129 // CHECK-LABEL: define{{.*}}nb0 130 // CHECK: br {{.*}} !prof [[BW_UNLIKELY]] 131 if (__builtin_expect(!a(), 0)) { 132 ++i; 133 } else { 134 --i; 135 } 136 } 137 138 void nu(int &i) { 139 // CHECK-LABEL: define{{.*}}nu 140 // CHECK: br {{.*}} !prof [[BW_UNLIKELY]] 141 if (bool d = !a()) [[unlikely]] { 142 ++i; 143 } else { 144 --i; 145 } 146 } 147 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 [[BW_LIKELY]] 154 if (__builtin_expect(a() ? b() : c(), 1)) { 155 ++i; 156 } else { 157 --i; 158 } 159 } 160 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 [[BW_LIKELY]] 167 if (bool d = a() ? b() : c()) [[likely]] { 168 ++i; 169 } else { 170 --i; 171 } 172 } 173 174 void tl2(int &i) { 175 // CHECK-LABEL: define{{.*}}tl 176 // CHECK: br {{.*}}false{{$}} 177 // CHECK: br {{.*}} !prof [[BW_LIKELY]] 178 // CHECK: br {{.*}} !prof [[BW_LIKELY]] 179 if (a() ? b() : c()) [[likely]] { 180 ++i; 181 } else { 182 --i; 183 } 184 } 185 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 [[BW_UNLIKELY]] 192 if (__builtin_expect(a() ? b() : c(), 0)) { 193 ++i; 194 } else { 195 --i; 196 } 197 } 198 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 [[BW_UNLIKELY]] 205 if (bool d = a() ? b() : c()) [[unlikely]] { 206 ++i; 207 } else { 208 --i; 209 } 210 } 211 212 void tu2(int &i) { 213 // CHECK-LABEL: define{{.*}}tu 214 // CHECK: br {{.*}}false{{$}} 215 // CHECK: br {{.*}} !prof [[BW_UNLIKELY]] 216 // CHECK: br {{.*}} !prof [[BW_UNLIKELY]] 217 if (a() ? b() : c()) [[unlikely]] { 218 ++i; 219 } else { 220 --i; 221 } 222 } 223 224 // CHECK: [[BW_LIKELY]] = !{!"branch_weights", !"expected", i32 2000, i32 1} 225 // CHECK: [[BW_UNLIKELY]] = !{!"branch_weights", !"expected", i32 1, i32 2000} 226