1; RUN: opt -lower-expect -strip-dead-prototypes -S -o - < %s | FileCheck %s
2; RUN: opt -S -passes='function(lower-expect),strip-dead-prototypes' < %s | FileCheck %s
3
4; CHECK-LABEL: @test1(
5define i32 @test1(i32 %x) nounwind uwtable ssp {
6entry:
7  %retval = alloca i32, align 4
8  %x.addr = alloca i32, align 4
9  store i32 %x, i32* %x.addr, align 4
10  %tmp = load i32, i32* %x.addr, align 4
11  %cmp = icmp sgt i32 %tmp, 1
12  %conv = zext i1 %cmp to i32
13  %conv1 = sext i32 %conv to i64
14  %expval = call i64 @llvm.expect.i64(i64 %conv1, i64 1)
15  %tobool = icmp ne i64 %expval, 0
16; CHECK: !prof !0
17; CHECK-NOT: @llvm.expect
18  br i1 %tobool, label %if.then, label %if.end
19
20if.then:                                          ; preds = %entry
21  %call = call i32 (...) @f()
22  store i32 %call, i32* %retval
23  br label %return
24
25if.end:                                           ; preds = %entry
26  store i32 1, i32* %retval
27  br label %return
28
29return:                                           ; preds = %if.end, %if.then
30  %0 = load i32, i32* %retval
31  ret i32 %0
32}
33
34declare i64 @llvm.expect.i64(i64, i64) nounwind readnone
35
36declare i32 @f(...)
37
38; CHECK-LABEL: @test2(
39define i32 @test2(i32 %x) nounwind uwtable ssp {
40entry:
41  %retval = alloca i32, align 4
42  %x.addr = alloca i32, align 4
43  store i32 %x, i32* %x.addr, align 4
44  %tmp = load i32, i32* %x.addr, align 4
45  %conv = sext i32 %tmp to i64
46  %expval = call i64 @llvm.expect.i64(i64 %conv, i64 1)
47  %tobool = icmp ne i64 %expval, 0
48; CHECK: !prof !0
49; CHECK-NOT: @llvm.expect
50  br i1 %tobool, label %if.then, label %if.end
51
52if.then:                                          ; preds = %entry
53  %call = call i32 (...) @f()
54  store i32 %call, i32* %retval
55  br label %return
56
57if.end:                                           ; preds = %entry
58  store i32 1, i32* %retval
59  br label %return
60
61return:                                           ; preds = %if.end, %if.then
62  %0 = load i32, i32* %retval
63  ret i32 %0
64}
65
66; CHECK-LABEL: @test3(
67define i32 @test3(i32 %x) nounwind uwtable ssp {
68entry:
69  %retval = alloca i32, align 4
70  %x.addr = alloca i32, align 4
71  store i32 %x, i32* %x.addr, align 4
72  %tmp = load i32, i32* %x.addr, align 4
73  %tobool = icmp ne i32 %tmp, 0
74  %lnot = xor i1 %tobool, true
75  %lnot.ext = zext i1 %lnot to i32
76  %conv = sext i32 %lnot.ext to i64
77  %expval = call i64 @llvm.expect.i64(i64 %conv, i64 1)
78  %tobool1 = icmp ne i64 %expval, 0
79; CHECK: !prof !0
80; CHECK-NOT: @llvm.expect
81  br i1 %tobool1, label %if.then, label %if.end
82
83if.then:                                          ; preds = %entry
84  %call = call i32 (...) @f()
85  store i32 %call, i32* %retval
86  br label %return
87
88if.end:                                           ; preds = %entry
89  store i32 1, i32* %retval
90  br label %return
91
92return:                                           ; preds = %if.end, %if.then
93  %0 = load i32, i32* %retval
94  ret i32 %0
95}
96
97; CHECK-LABEL: @test4(
98define i32 @test4(i32 %x) nounwind uwtable ssp {
99entry:
100  %retval = alloca i32, align 4
101  %x.addr = alloca i32, align 4
102  store i32 %x, i32* %x.addr, align 4
103  %tmp = load i32, i32* %x.addr, align 4
104  %tobool = icmp ne i32 %tmp, 0
105  %lnot = xor i1 %tobool, true
106  %lnot1 = xor i1 %lnot, true
107  %lnot.ext = zext i1 %lnot1 to i32
108  %conv = sext i32 %lnot.ext to i64
109  %expval = call i64 @llvm.expect.i64(i64 %conv, i64 1)
110  %tobool2 = icmp ne i64 %expval, 0
111; CHECK: !prof !0
112; CHECK-NOT: @llvm.expect
113  br i1 %tobool2, label %if.then, label %if.end
114
115if.then:                                          ; preds = %entry
116  %call = call i32 (...) @f()
117  store i32 %call, i32* %retval
118  br label %return
119
120if.end:                                           ; preds = %entry
121  store i32 1, i32* %retval
122  br label %return
123
124return:                                           ; preds = %if.end, %if.then
125  %0 = load i32, i32* %retval
126  ret i32 %0
127}
128
129; CHECK-LABEL: @test5(
130define i32 @test5(i32 %x) nounwind uwtable ssp {
131entry:
132  %retval = alloca i32, align 4
133  %x.addr = alloca i32, align 4
134  store i32 %x, i32* %x.addr, align 4
135  %tmp = load i32, i32* %x.addr, align 4
136  %cmp = icmp slt i32 %tmp, 0
137  %conv = zext i1 %cmp to i32
138  %conv1 = sext i32 %conv to i64
139  %expval = call i64 @llvm.expect.i64(i64 %conv1, i64 0)
140  %tobool = icmp ne i64 %expval, 0
141; CHECK: !prof !1
142; CHECK-NOT: @llvm.expect
143  br i1 %tobool, label %if.then, label %if.end
144
145if.then:                                          ; preds = %entry
146  %call = call i32 (...) @f()
147  store i32 %call, i32* %retval
148  br label %return
149
150if.end:                                           ; preds = %entry
151  store i32 1, i32* %retval
152  br label %return
153
154return:                                           ; preds = %if.end, %if.then
155  %0 = load i32, i32* %retval
156  ret i32 %0
157}
158
159; CHECK-LABEL: @test6(
160define i32 @test6(i32 %x) nounwind uwtable ssp {
161entry:
162  %retval = alloca i32, align 4
163  %x.addr = alloca i32, align 4
164  store i32 %x, i32* %x.addr, align 4
165  %tmp = load i32, i32* %x.addr, align 4
166  %conv = sext i32 %tmp to i64
167  %expval = call i64 @llvm.expect.i64(i64 %conv, i64 1)
168; CHECK: !prof !2
169; CHECK-NOT: @llvm.expect
170  switch i64 %expval, label %sw.epilog [
171    i64 1, label %sw.bb
172    i64 2, label %sw.bb
173  ]
174
175sw.bb:                                            ; preds = %entry, %entry
176  store i32 0, i32* %retval
177  br label %return
178
179sw.epilog:                                        ; preds = %entry
180  store i32 1, i32* %retval
181  br label %return
182
183return:                                           ; preds = %sw.epilog, %sw.bb
184  %0 = load i32, i32* %retval
185  ret i32 %0
186}
187
188; CHECK-LABEL: @test7(
189define i32 @test7(i32 %x) nounwind uwtable ssp {
190entry:
191  %retval = alloca i32, align 4
192  %x.addr = alloca i32, align 4
193  store i32 %x, i32* %x.addr, align 4
194  %tmp = load i32, i32* %x.addr, align 4
195  %conv = sext i32 %tmp to i64
196  %expval = call i64 @llvm.expect.i64(i64 %conv, i64 1)
197; CHECK: !prof !3
198; CHECK-NOT: @llvm.expect
199  switch i64 %expval, label %sw.epilog [
200    i64 2, label %sw.bb
201    i64 3, label %sw.bb
202  ]
203
204sw.bb:                                            ; preds = %entry, %entry
205  %tmp1 = load i32, i32* %x.addr, align 4
206  store i32 %tmp1, i32* %retval
207  br label %return
208
209sw.epilog:                                        ; preds = %entry
210  store i32 0, i32* %retval
211  br label %return
212
213return:                                           ; preds = %sw.epilog, %sw.bb
214  %0 = load i32, i32* %retval
215  ret i32 %0
216}
217
218; CHECK-LABEL: @test8(
219define i32 @test8(i32 %x) nounwind uwtable ssp {
220entry:
221  %retval = alloca i32, align 4
222  %x.addr = alloca i32, align 4
223  store i32 %x, i32* %x.addr, align 4
224  %tmp = load i32, i32* %x.addr, align 4
225  %cmp = icmp sgt i32 %tmp, 1
226  %conv = zext i1 %cmp to i32
227  %expval = call i32 @llvm.expect.i32(i32 %conv, i32 1)
228  %tobool = icmp ne i32 %expval, 0
229; CHECK: !prof !0
230; CHECK-NOT: @llvm.expect
231  br i1 %tobool, label %if.then, label %if.end
232
233if.then:                                          ; preds = %entry
234  %call = call i32 (...) @f()
235  store i32 %call, i32* %retval
236  br label %return
237
238if.end:                                           ; preds = %entry
239  store i32 1, i32* %retval
240  br label %return
241
242return:                                           ; preds = %if.end, %if.then
243  %0 = load i32, i32* %retval
244  ret i32 %0
245}
246
247declare i32 @llvm.expect.i32(i32, i32) nounwind readnone
248
249; CHECK-LABEL: @test9(
250define i32 @test9(i32 %x) nounwind uwtable ssp {
251entry:
252  %retval = alloca i32, align 4
253  %x.addr = alloca i32, align 4
254  store i32 %x, i32* %x.addr, align 4
255  %tmp = load i32, i32* %x.addr, align 4
256  %cmp = icmp sgt i32 %tmp, 1
257  %expval = call i1 @llvm.expect.i1(i1 %cmp, i1 1)
258; CHECK: !prof !0
259; CHECK-NOT: @llvm.expect
260  br i1 %expval, label %if.then, label %if.end
261
262if.then:                                          ; preds = %entry
263  %call = call i32 (...) @f()
264  store i32 %call, i32* %retval
265  br label %return
266
267if.end:                                           ; preds = %entry
268  store i32 1, i32* %retval
269  br label %return
270
271return:                                           ; preds = %if.end, %if.then
272  %0 = load i32, i32* %retval
273  ret i32 %0
274}
275
276declare i1 @llvm.expect.i1(i1, i1) nounwind readnone
277
278; CHECK: !0 = !{!"branch_weights", i32 2000, i32 1}
279; CHECK: !1 = !{!"branch_weights", i32 1, i32 2000}
280; CHECK: !2 = !{!"branch_weights", i32 1, i32 2000, i32 1}
281; CHECK: !3 = !{!"branch_weights", i32 2000, i32 1, i32 1}
282