355 lines · plain
1; RUN: opt < %s -passes='print<branch-prob>' -disable-output 2>&1 | FileCheck %s2 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 than13; 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, 020 br i1 %cond, label %then, label %else21; 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 %exit26; CHECK: edge %then -> %exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]27 28else:29 br label %exit30; 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 %result35}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, 542 br i1 %cond, label %then, label %else43; 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 %exit48; CHECK: edge %then -> %exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]49 50else:51 br label %exit52; 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 %result57}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, 064 br i1 %cond, label %then, label %else65; 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 %exit70; CHECK: edge %then -> %exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]71 72else:73 br label %exit74; 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 %result79}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, 086 br i1 %cond, label %then, label %else87; 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 %exit92; CHECK: edge %then -> %exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]93 94else:95 br label %exit96; 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 %result101}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, 0108 br i1 %cond, label %then, label %else109; 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 %exit114; CHECK: edge %then -> %exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]115 116else:117 br label %exit118; 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 %result123}124 125 126; Similarly check other library functions that have the same behaviour127 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, 0133 br i1 %cond, label %then, label %else134; 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 %exit139; CHECK: edge %then -> %exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]140 141else:142 br label %exit143; 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 %result148}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, 0155 br i1 %cond, label %then, label %else156; 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 %exit161; CHECK: edge %then -> %exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]162 163else:164 br label %exit165; 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 %result170}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, 0177 br i1 %cond, label %then, label %else178; 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 %exit183; CHECK: edge %then -> %exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]184 185else:186 br label %exit187; 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 %result192}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, 0199 br i1 %cond, label %then, label %else200; 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 %exit205; CHECK: edge %then -> %exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]206 207else:208 br label %exit209; 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 %result214}215 216 217; Check that for the result of a call to a non-library function the default218; heuristic is applied, i.e. positive more likely than negative, nonzero more219; 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, 0226 br i1 %cond, label %then, label %else227; 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 %exit232; CHECK: edge %then -> %exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]233 234else:235 br label %exit236; 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 %result241}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, 0248 br i1 %cond, label %then, label %else249; 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 %exit254; CHECK: edge %then -> %exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]255 256else:257 br label %exit258; 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 %result263}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, 0270 br i1 %cond, label %then, label %else271; 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 %exit276; CHECK: edge %then -> %exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]277 278else:279 br label %exit280; 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 %result285}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, 0293 br i1 %cond, label %then, label %else294; 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 %exit299; CHECK: edge %then -> %exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]300 301else:302 br label %exit303; 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 %result308}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, 5315 br i1 %cond, label %then, label %else316; 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 %exit321; CHECK: edge %then -> %exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]322 323else:324 br label %exit325; 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 %result330}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, 0339 br i1 %cond, label %then, label %else340; 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 %exit345; CHECK: edge %then -> %exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]346 347else:348 br label %exit349; 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 %result354}355