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