1; RUN: opt < %s -analyze -branch-prob | FileCheck %s 2; RUN: opt < %s -analyze -lazy-branch-prob | FileCheck %s 3; RUN: opt < %s -passes='print<branch-prob>' -disable-output 2>&1 | FileCheck %s 4 5declare i32 @strcmp(i8*, i8*) 6declare i32 @strncmp(i8*, i8*, i32) 7declare i32 @strcasecmp(i8*, i8*) 8declare i32 @strncasecmp(i8*, i8*, i32) 9declare i32 @memcmp(i8*, i8*) 10declare i32 @nonstrcmp(i8*, i8*) 11 12 13; Check that the result of strcmp is considered more likely to be nonzero than 14; zero, and equally likely to be (nonzero) positive or negative. 15 16define i32 @test_strcmp_eq(i8* %p, i8* %q) { 17; CHECK: Printing analysis {{.*}} for function 'test_strcmp_eq' 18entry: 19 %val = call i32 @strcmp(i8* %p, i8* %q) 20 %cond = icmp eq i32 %val, 0 21 br i1 %cond, label %then, label %else 22; CHECK: edge entry -> then probability is 0x30000000 / 0x80000000 = 37.50% 23; CHECK: edge entry -> else probability is 0x50000000 / 0x80000000 = 62.50% 24 25then: 26 br label %exit 27; CHECK: edge then -> exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge] 28 29else: 30 br label %exit 31; CHECK: edge else -> exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge] 32 33exit: 34 %result = phi i32 [ 0, %then ], [ 1, %else ] 35 ret i32 %result 36} 37 38define i32 @test_strcmp_ne(i8* %p, i8* %q) { 39; CHECK: Printing analysis {{.*}} for function 'test_strcmp_ne' 40entry: 41 %val = call i32 @strcmp(i8* %p, i8* %q) 42 %cond = icmp ne i32 %val, 0 43 br i1 %cond, label %then, label %else 44; CHECK: edge entry -> then probability is 0x50000000 / 0x80000000 = 62.50% 45; CHECK: edge entry -> else probability is 0x30000000 / 0x80000000 = 37.50% 46 47then: 48 br label %exit 49; CHECK: edge then -> exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge] 50 51else: 52 br label %exit 53; CHECK: edge else -> exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge] 54 55exit: 56 %result = phi i32 [ 0, %then ], [ 1, %else ] 57 ret i32 %result 58} 59 60define i32 @test_strcmp_sgt(i8* %p, i8* %q) { 61; CHECK: Printing analysis {{.*}} for function 'test_strcmp_sgt' 62entry: 63 %val = call i32 @strcmp(i8* %p, i8* %q) 64 %cond = icmp sgt i32 %val, 0 65 br i1 %cond, label %then, label %else 66; CHECK: edge entry -> then probability is 0x40000000 / 0x80000000 = 50.00% 67; CHECK: edge entry -> else probability is 0x40000000 / 0x80000000 = 50.00% 68 69then: 70 br label %exit 71; CHECK: edge then -> exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge] 72 73else: 74 br label %exit 75; CHECK: edge else -> exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge] 76 77exit: 78 %result = phi i32 [ 0, %then ], [ 1, %else ] 79 ret i32 %result 80} 81 82define i32 @test_strcmp_slt(i8* %p, i8* %q) { 83; CHECK: Printing analysis {{.*}} for function 'test_strcmp_slt' 84entry: 85 %val = call i32 @strcmp(i8* %p, i8* %q) 86 %cond = icmp slt i32 %val, 0 87 br i1 %cond, label %then, label %else 88; CHECK: edge entry -> then probability is 0x40000000 / 0x80000000 = 50.00% 89; CHECK: edge entry -> else probability is 0x40000000 / 0x80000000 = 50.00% 90 91then: 92 br label %exit 93; CHECK: edge then -> exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge] 94 95else: 96 br label %exit 97; CHECK: edge else -> exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge] 98 99exit: 100 %result = phi i32 [ 0, %then ], [ 1, %else ] 101 ret i32 %result 102} 103 104 105; Similarly check other library functions that have the same behaviour 106 107define i32 @test_strncmp_sgt(i8* %p, i8* %q) { 108; CHECK: Printing analysis {{.*}} for function 'test_strncmp_sgt' 109entry: 110 %val = call i32 @strncmp(i8* %p, i8* %q, i32 4) 111 %cond = icmp sgt i32 %val, 0 112 br i1 %cond, label %then, label %else 113; CHECK: edge entry -> then probability is 0x40000000 / 0x80000000 = 50.00% 114; CHECK: edge entry -> else probability is 0x40000000 / 0x80000000 = 50.00% 115 116then: 117 br label %exit 118; CHECK: edge then -> exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge] 119 120else: 121 br label %exit 122; CHECK: edge else -> exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge] 123 124exit: 125 %result = phi i32 [ 0, %then ], [ 1, %else ] 126 ret i32 %result 127} 128 129define i32 @test_strcasecmp_sgt(i8* %p, i8* %q) { 130; CHECK: Printing analysis {{.*}} for function 'test_strcasecmp_sgt' 131entry: 132 %val = call i32 @strcasecmp(i8* %p, i8* %q) 133 %cond = icmp sgt i32 %val, 0 134 br i1 %cond, label %then, label %else 135; CHECK: edge entry -> then probability is 0x40000000 / 0x80000000 = 50.00% 136; CHECK: edge entry -> else probability is 0x40000000 / 0x80000000 = 50.00% 137 138then: 139 br label %exit 140; CHECK: edge then -> exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge] 141 142else: 143 br label %exit 144; CHECK: edge else -> exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge] 145 146exit: 147 %result = phi i32 [ 0, %then ], [ 1, %else ] 148 ret i32 %result 149} 150 151define i32 @test_strncasecmp_sgt(i8* %p, i8* %q) { 152; CHECK: Printing analysis {{.*}} for function 'test_strncasecmp_sgt' 153entry: 154 %val = call i32 @strncasecmp(i8* %p, i8* %q, i32 4) 155 %cond = icmp sgt i32 %val, 0 156 br i1 %cond, label %then, label %else 157; CHECK: edge entry -> then probability is 0x40000000 / 0x80000000 = 50.00% 158; CHECK: edge entry -> else probability is 0x40000000 / 0x80000000 = 50.00% 159 160then: 161 br label %exit 162; CHECK: edge then -> exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge] 163 164else: 165 br label %exit 166; CHECK: edge else -> exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge] 167 168exit: 169 %result = phi i32 [ 0, %then ], [ 1, %else ] 170 ret i32 %result 171} 172 173define i32 @test_memcmp_sgt(i8* %p, i8* %q) { 174; CHECK: Printing analysis {{.*}} for function 'test_memcmp_sgt' 175entry: 176 %val = call i32 @memcmp(i8* %p, i8* %q) 177 %cond = icmp sgt i32 %val, 0 178 br i1 %cond, label %then, label %else 179; CHECK: edge entry -> then probability is 0x40000000 / 0x80000000 = 50.00% 180; CHECK: edge entry -> else probability is 0x40000000 / 0x80000000 = 50.00% 181 182then: 183 br label %exit 184; CHECK: edge then -> exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge] 185 186else: 187 br label %exit 188; CHECK: edge else -> exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge] 189 190exit: 191 %result = phi i32 [ 0, %then ], [ 1, %else ] 192 ret i32 %result 193} 194 195 196; Check that for the result of a call to a non-library function the default 197; heuristic is applied, i.e. positive more likely than negative, nonzero more 198; likely than zero. 199 200define i32 @test_nonstrcmp_eq(i8* %p, i8* %q) { 201; CHECK: Printing analysis {{.*}} for function 'test_nonstrcmp_eq' 202entry: 203 %val = call i32 @nonstrcmp(i8* %p, i8* %q) 204 %cond = icmp eq i32 %val, 0 205 br i1 %cond, label %then, label %else 206; CHECK: edge entry -> then probability is 0x30000000 / 0x80000000 = 37.50% 207; CHECK: edge entry -> else probability is 0x50000000 / 0x80000000 = 62.50% 208 209then: 210 br label %exit 211; CHECK: edge then -> exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge] 212 213else: 214 br label %exit 215; CHECK: edge else -> exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge] 216 217exit: 218 %result = phi i32 [ 0, %then ], [ 1, %else ] 219 ret i32 %result 220} 221 222define i32 @test_nonstrcmp_ne(i8* %p, i8* %q) { 223; CHECK: Printing analysis {{.*}} for function 'test_nonstrcmp_ne' 224entry: 225 %val = call i32 @nonstrcmp(i8* %p, i8* %q) 226 %cond = icmp ne i32 %val, 0 227 br i1 %cond, label %then, label %else 228; CHECK: edge entry -> then probability is 0x50000000 / 0x80000000 = 62.50% 229; CHECK: edge entry -> else probability is 0x30000000 / 0x80000000 = 37.50% 230 231then: 232 br label %exit 233; CHECK: edge then -> exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge] 234 235else: 236 br label %exit 237; CHECK: edge else -> exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge] 238 239exit: 240 %result = phi i32 [ 0, %then ], [ 1, %else ] 241 ret i32 %result 242} 243 244define i32 @test_nonstrcmp_sgt(i8* %p, i8* %q) { 245; CHECK: Printing analysis {{.*}} for function 'test_nonstrcmp_sgt' 246entry: 247 %val = call i32 @nonstrcmp(i8* %p, i8* %q) 248 %cond = icmp sgt i32 %val, 0 249 br i1 %cond, label %then, label %else 250; CHECK: edge entry -> then probability is 0x50000000 / 0x80000000 = 62.50% 251; CHECK: edge entry -> else probability is 0x30000000 / 0x80000000 = 37.50% 252 253then: 254 br label %exit 255; CHECK: edge then -> exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge] 256 257else: 258 br label %exit 259; CHECK: edge else -> exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge] 260 261exit: 262 %result = phi i32 [ 0, %then ], [ 1, %else ] 263 ret i32 %result 264} 265