1; RUN: opt < %s -passes='print<branch-prob>' -disable-output 2>&1 | FileCheck %s 2 3declare i32 @strcmp(ptr, ptr) 4declare i32 @strncmp(ptr, ptr, i32) 5declare i32 @strcasecmp(ptr, ptr) 6declare i32 @strncasecmp(ptr, ptr, i32) 7declare i32 @memcmp(ptr, ptr) 8declare i32 @bcmp(ptr, ptr) 9declare i32 @nonstrcmp(ptr, ptr) 10 11 12; Check that the result of strcmp is considered more likely to be nonzero than 13; zero, and equally likely to be (nonzero) positive or negative. 14 15define i32 @test_strcmp_eq(ptr %p, ptr %q) { 16; CHECK: Printing analysis {{.*}} for function 'test_strcmp_eq' 17entry: 18 %val = call i32 @strcmp(ptr %p, ptr %q) 19 %cond = icmp eq i32 %val, 0 20 br i1 %cond, label %then, label %else 21; CHECK: edge %entry -> %then probability is 0x30000000 / 0x80000000 = 37.50% 22; CHECK: edge %entry -> %else probability is 0x50000000 / 0x80000000 = 62.50% 23 24then: 25 br label %exit 26; CHECK: edge %then -> %exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge] 27 28else: 29 br label %exit 30; CHECK: edge %else -> %exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge] 31 32exit: 33 %result = phi i32 [ 0, %then ], [ 1, %else ] 34 ret i32 %result 35} 36 37define i32 @test_strcmp_eq5(ptr %p, ptr %q) { 38; CHECK: Printing analysis {{.*}} for function 'test_strcmp_eq5' 39entry: 40 %val = call i32 @strcmp(ptr %p, ptr %q) 41 %cond = icmp eq i32 %val, 5 42 br i1 %cond, label %then, label %else 43; CHECK: edge %entry -> %then probability is 0x30000000 / 0x80000000 = 37.50% 44; CHECK: edge %entry -> %else probability is 0x50000000 / 0x80000000 = 62.50% 45 46then: 47 br label %exit 48; CHECK: edge %then -> %exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge] 49 50else: 51 br label %exit 52; CHECK: edge %else -> %exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge] 53 54exit: 55 %result = phi i32 [ 0, %then ], [ 1, %else ] 56 ret i32 %result 57} 58 59define i32 @test_strcmp_ne(ptr %p, ptr %q) { 60; CHECK: Printing analysis {{.*}} for function 'test_strcmp_ne' 61entry: 62 %val = call i32 @strcmp(ptr %p, ptr %q) 63 %cond = icmp ne i32 %val, 0 64 br i1 %cond, label %then, label %else 65; CHECK: edge %entry -> %then probability is 0x50000000 / 0x80000000 = 62.50% 66; CHECK: edge %entry -> %else probability is 0x30000000 / 0x80000000 = 37.50% 67 68then: 69 br label %exit 70; CHECK: edge %then -> %exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge] 71 72else: 73 br label %exit 74; CHECK: edge %else -> %exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge] 75 76exit: 77 %result = phi i32 [ 0, %then ], [ 1, %else ] 78 ret i32 %result 79} 80 81define i32 @test_strcmp_sgt(ptr %p, ptr %q) { 82; CHECK: Printing analysis {{.*}} for function 'test_strcmp_sgt' 83entry: 84 %val = call i32 @strcmp(ptr %p, ptr %q) 85 %cond = icmp sgt i32 %val, 0 86 br i1 %cond, label %then, label %else 87; CHECK: edge %entry -> %then probability is 0x40000000 / 0x80000000 = 50.00% 88; CHECK: edge %entry -> %else probability is 0x40000000 / 0x80000000 = 50.00% 89 90then: 91 br label %exit 92; CHECK: edge %then -> %exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge] 93 94else: 95 br label %exit 96; CHECK: edge %else -> %exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge] 97 98exit: 99 %result = phi i32 [ 0, %then ], [ 1, %else ] 100 ret i32 %result 101} 102 103define i32 @test_strcmp_slt(ptr %p, ptr %q) { 104; CHECK: Printing analysis {{.*}} for function 'test_strcmp_slt' 105entry: 106 %val = call i32 @strcmp(ptr %p, ptr %q) 107 %cond = icmp slt i32 %val, 0 108 br i1 %cond, label %then, label %else 109; CHECK: edge %entry -> %then probability is 0x40000000 / 0x80000000 = 50.00% 110; CHECK: edge %entry -> %else probability is 0x40000000 / 0x80000000 = 50.00% 111 112then: 113 br label %exit 114; CHECK: edge %then -> %exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge] 115 116else: 117 br label %exit 118; CHECK: edge %else -> %exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge] 119 120exit: 121 %result = phi i32 [ 0, %then ], [ 1, %else ] 122 ret i32 %result 123} 124 125 126; Similarly check other library functions that have the same behaviour 127 128define i32 @test_strncmp_sgt(ptr %p, ptr %q) { 129; CHECK: Printing analysis {{.*}} for function 'test_strncmp_sgt' 130entry: 131 %val = call i32 @strncmp(ptr %p, ptr %q, i32 4) 132 %cond = icmp sgt i32 %val, 0 133 br i1 %cond, label %then, label %else 134; CHECK: edge %entry -> %then probability is 0x40000000 / 0x80000000 = 50.00% 135; CHECK: edge %entry -> %else probability is 0x40000000 / 0x80000000 = 50.00% 136 137then: 138 br label %exit 139; CHECK: edge %then -> %exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge] 140 141else: 142 br label %exit 143; CHECK: edge %else -> %exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge] 144 145exit: 146 %result = phi i32 [ 0, %then ], [ 1, %else ] 147 ret i32 %result 148} 149 150define i32 @test_strcasecmp_sgt(ptr %p, ptr %q) { 151; CHECK: Printing analysis {{.*}} for function 'test_strcasecmp_sgt' 152entry: 153 %val = call i32 @strcasecmp(ptr %p, ptr %q) 154 %cond = icmp sgt i32 %val, 0 155 br i1 %cond, label %then, label %else 156; CHECK: edge %entry -> %then probability is 0x40000000 / 0x80000000 = 50.00% 157; CHECK: edge %entry -> %else probability is 0x40000000 / 0x80000000 = 50.00% 158 159then: 160 br label %exit 161; CHECK: edge %then -> %exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge] 162 163else: 164 br label %exit 165; CHECK: edge %else -> %exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge] 166 167exit: 168 %result = phi i32 [ 0, %then ], [ 1, %else ] 169 ret i32 %result 170} 171 172define i32 @test_strncasecmp_sgt(ptr %p, ptr %q) { 173; CHECK: Printing analysis {{.*}} for function 'test_strncasecmp_sgt' 174entry: 175 %val = call i32 @strncasecmp(ptr %p, ptr %q, i32 4) 176 %cond = icmp sgt i32 %val, 0 177 br i1 %cond, label %then, label %else 178; CHECK: edge %entry -> %then probability is 0x40000000 / 0x80000000 = 50.00% 179; CHECK: edge %entry -> %else probability is 0x40000000 / 0x80000000 = 50.00% 180 181then: 182 br label %exit 183; CHECK: edge %then -> %exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge] 184 185else: 186 br label %exit 187; CHECK: edge %else -> %exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge] 188 189exit: 190 %result = phi i32 [ 0, %then ], [ 1, %else ] 191 ret i32 %result 192} 193 194define i32 @test_memcmp_sgt(ptr %p, ptr %q) { 195; CHECK: Printing analysis {{.*}} for function 'test_memcmp_sgt' 196entry: 197 %val = call i32 @memcmp(ptr %p, ptr %q) 198 %cond = icmp sgt i32 %val, 0 199 br i1 %cond, label %then, label %else 200; CHECK: edge %entry -> %then probability is 0x40000000 / 0x80000000 = 50.00% 201; CHECK: edge %entry -> %else probability is 0x40000000 / 0x80000000 = 50.00% 202 203then: 204 br label %exit 205; CHECK: edge %then -> %exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge] 206 207else: 208 br label %exit 209; CHECK: edge %else -> %exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge] 210 211exit: 212 %result = phi i32 [ 0, %then ], [ 1, %else ] 213 ret i32 %result 214} 215 216 217; Check that for the result of a call to a non-library function the default 218; heuristic is applied, i.e. positive more likely than negative, nonzero more 219; likely than zero. 220 221define i32 @test_nonstrcmp_eq(ptr %p, ptr %q) { 222; CHECK: Printing analysis {{.*}} for function 'test_nonstrcmp_eq' 223entry: 224 %val = call i32 @nonstrcmp(ptr %p, ptr %q) 225 %cond = icmp eq i32 %val, 0 226 br i1 %cond, label %then, label %else 227; CHECK: edge %entry -> %then probability is 0x30000000 / 0x80000000 = 37.50% 228; CHECK: edge %entry -> %else probability is 0x50000000 / 0x80000000 = 62.50% 229 230then: 231 br label %exit 232; CHECK: edge %then -> %exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge] 233 234else: 235 br label %exit 236; CHECK: edge %else -> %exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge] 237 238exit: 239 %result = phi i32 [ 0, %then ], [ 1, %else ] 240 ret i32 %result 241} 242 243define i32 @test_nonstrcmp_ne(ptr %p, ptr %q) { 244; CHECK: Printing analysis {{.*}} for function 'test_nonstrcmp_ne' 245entry: 246 %val = call i32 @nonstrcmp(ptr %p, ptr %q) 247 %cond = icmp ne i32 %val, 0 248 br i1 %cond, label %then, label %else 249; CHECK: edge %entry -> %then probability is 0x50000000 / 0x80000000 = 62.50% 250; CHECK: edge %entry -> %else probability is 0x30000000 / 0x80000000 = 37.50% 251 252then: 253 br label %exit 254; CHECK: edge %then -> %exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge] 255 256else: 257 br label %exit 258; CHECK: edge %else -> %exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge] 259 260exit: 261 %result = phi i32 [ 0, %then ], [ 1, %else ] 262 ret i32 %result 263} 264 265define i32 @test_nonstrcmp_sgt(ptr %p, ptr %q) { 266; CHECK: Printing analysis {{.*}} for function 'test_nonstrcmp_sgt' 267entry: 268 %val = call i32 @nonstrcmp(ptr %p, ptr %q) 269 %cond = icmp sgt i32 %val, 0 270 br i1 %cond, label %then, label %else 271; CHECK: edge %entry -> %then probability is 0x50000000 / 0x80000000 = 62.50% 272; CHECK: edge %entry -> %else probability is 0x30000000 / 0x80000000 = 37.50% 273 274then: 275 br label %exit 276; CHECK: edge %then -> %exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge] 277 278else: 279 br label %exit 280; CHECK: edge %else -> %exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge] 281 282exit: 283 %result = phi i32 [ 0, %then ], [ 1, %else ] 284 ret i32 %result 285} 286 287 288define i32 @test_bcmp_eq(ptr %p, ptr %q) { 289; CHECK: Printing analysis {{.*}} for function 'test_bcmp_eq' 290entry: 291 %val = call i32 @bcmp(ptr %p, ptr %q) 292 %cond = icmp eq i32 %val, 0 293 br i1 %cond, label %then, label %else 294; CHECK: edge %entry -> %then probability is 0x30000000 / 0x80000000 = 37.50% 295; CHECK: edge %entry -> %else probability is 0x50000000 / 0x80000000 = 62.50% 296 297then: 298 br label %exit 299; CHECK: edge %then -> %exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge] 300 301else: 302 br label %exit 303; CHECK: edge %else -> %exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge] 304 305exit: 306 %result = phi i32 [ 0, %then ], [ 1, %else ] 307 ret i32 %result 308} 309 310define i32 @test_bcmp_eq5(ptr %p, ptr %q) { 311; CHECK: Printing analysis {{.*}} for function 'test_bcmp_eq5' 312entry: 313 %val = call i32 @bcmp(ptr %p, ptr %q) 314 %cond = icmp eq i32 %val, 5 315 br i1 %cond, label %then, label %else 316; CHECK: edge %entry -> %then probability is 0x30000000 / 0x80000000 = 37.50% 317; CHECK: edge %entry -> %else probability is 0x50000000 / 0x80000000 = 62.50% 318 319then: 320 br label %exit 321; CHECK: edge %then -> %exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge] 322 323else: 324 br label %exit 325; CHECK: edge %else -> %exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge] 326 327exit: 328 %result = phi i32 [ 0, %then ], [ 1, %else ] 329 ret i32 %result 330} 331 332 333 334define i32 @test_bcmp_ne(ptr %p, ptr %q) { 335; CHECK: Printing analysis {{.*}} for function 'test_bcmp_ne' 336entry: 337 %val = call i32 @bcmp(ptr %p, ptr %q) 338 %cond = icmp ne i32 %val, 0 339 br i1 %cond, label %then, label %else 340; CHECK: edge %entry -> %then probability is 0x50000000 / 0x80000000 = 62.50% 341; CHECK: edge %entry -> %else probability is 0x30000000 / 0x80000000 = 37.50% 342 343then: 344 br label %exit 345; CHECK: edge %then -> %exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge] 346 347else: 348 br label %exit 349; CHECK: edge %else -> %exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge] 350 351exit: 352 %result = phi i32 [ 0, %then ], [ 1, %else ] 353 ret i32 %result 354} 355