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