1 ; RUN: opt -S -passes='function(lower-expect),strip-dead-prototypes' -likely-branch-weight=2147483647 -unlikely-branch-weight=1 < %s | FileCheck %s
4 ; if (__builtin_expect_with_probability(((a0 == 1) || (a1 == 1) || (a2 == 1)), 1, 0))
5 ; For the above case, all 3 branches should be annotated
6 ; which should be equivalent to if (__builtin_expect(((a0 == 1) || (a1 == 1) || (a2 == 1)), 0))
9 ; if (__builtin_expect_with_probability(((a0 == 1) || (a1 == 1) || (a2 == 1)), 1, 1))
10 ; For the above case, we do not have enough information, so only the last branch could be annotated
11 ; which should be equivalent to if (__builtin_expect(((a0 == 1) || (a1 == 1) || (a2 == 1)), 1))
15 declare i64 @llvm.expect.i64(i64, i64) nounwind readnone
16 declare i64 @llvm.expect.with.probability.i64(i64, i64, double) nounwind readnone
18 ; CHECK-LABEL: @test1_expect_1(
24 ; CHECK: br i1 %tobool, label %block4, label %block5, !prof !0
25 define void @test1_expect_1(i8 %a0, i8 %a1, i8 %a2) {
27 %c0 = icmp eq i8 %a0, 1
28 br i1 %c0, label %block3, label %block1
31 %c1 = icmp eq i8 %a1, 1
32 br i1 %c1, label %block3, label %block2
35 %c2 = icmp eq i8 %a2, 1
39 %cond0 = phi i1 [ true, %block0 ], [ true, %block1 ], [ %c2, %block2 ]
40 %cond1 = zext i1 %cond0 to i32
41 %cond2 = sext i32 %cond1 to i64
42 %expval = call i64 @llvm.expect.i64(i64 %cond2, i64 1)
43 %tobool = icmp ne i64 %expval, 0
44 br i1 %tobool, label %block4, label %block5
54 ; should have exactly the same behavior as test1
55 ; CHECK-LABEL: @test2_expect_with_prob_1_1(
61 ; CHECK: br i1 %tobool, label %block4, label %block5, !prof !0
62 define void @test2_expect_with_prob_1_1(i8 %a0, i8 %a1, i8 %a2) {
64 %c0 = icmp eq i8 %a0, 1
65 br i1 %c0, label %block3, label %block1
68 %c1 = icmp eq i8 %a1, 1
69 br i1 %c1, label %block3, label %block2
72 %c2 = icmp eq i8 %a2, 1
76 %cond0 = phi i1 [ true, %block0 ], [ true, %block1 ], [ %c2, %block2 ]
77 %cond1 = zext i1 %cond0 to i32
78 %cond2 = sext i32 %cond1 to i64
79 %expval = call i64 @llvm.expect.with.probability.i64(i64 %cond2, i64 1, double 1.0)
80 %tobool = icmp ne i64 %expval, 0
81 br i1 %tobool, label %block4, label %block5
91 ; should have exactly the same behavior as test1
92 ; CHECK-LABEL: @test3_expect_with_prob_0_0(
98 ; CHECK: br i1 %tobool, label %block4, label %block5, !prof !0
99 define void @test3_expect_with_prob_0_0(i8 %a0, i8 %a1, i8 %a2) {
101 %c0 = icmp eq i8 %a0, 1
102 br i1 %c0, label %block3, label %block1
105 %c1 = icmp eq i8 %a1, 1
106 br i1 %c1, label %block3, label %block2
109 %c2 = icmp eq i8 %a2, 1
113 %cond0 = phi i1 [ true, %block0 ], [ true, %block1 ], [ %c2, %block2 ]
114 %cond1 = zext i1 %cond0 to i32
115 %cond2 = sext i32 %cond1 to i64
116 %expval = call i64 @llvm.expect.with.probability.i64(i64 %cond2, i64 0, double 0.0)
117 %tobool = icmp ne i64 %expval, 0
118 br i1 %tobool, label %block4, label %block5
128 ; CHECK-LABEL: @test4_expect_0(
130 ; CHECK: br i1 %c0, label %block3, label %block1, !prof !1
132 ; CHECK: br i1 %c1, label %block3, label %block2, !prof !1
134 ; CHECK: br i1 %tobool, label %block4, label %block5, !prof !1
135 define void @test4_expect_0(i8 %a0, i8 %a1, i8 %a2) {
137 %c0 = icmp eq i8 %a0, 1
138 br i1 %c0, label %block3, label %block1
141 %c1 = icmp eq i8 %a1, 1
142 br i1 %c1, label %block3, label %block2
145 %c2 = icmp eq i8 %a2, 1
149 %cond0 = phi i1 [ true, %block0 ], [ true, %block1 ], [ %c2, %block2 ]
150 %cond1 = zext i1 %cond0 to i32
151 %cond2 = sext i32 %cond1 to i64
152 %expval = call i64 @llvm.expect.i64(i64 %cond2, i64 0)
153 %tobool = icmp ne i64 %expval, 0
154 br i1 %tobool, label %block4, label %block5
164 ; should have exactly the same behavior as test4
165 ; CHECK-LABEL: @test5_expect_with_prob_1_0(
167 ; CHECK: br i1 %c0, label %block3, label %block1, !prof !1
169 ; CHECK: br i1 %c1, label %block3, label %block2, !prof !1
171 ; CHECK: br i1 %tobool, label %block4, label %block5, !prof !1
172 define void @test5_expect_with_prob_1_0(i8 %a0, i8 %a1, i8 %a2) {
174 %c0 = icmp eq i8 %a0, 1
175 br i1 %c0, label %block3, label %block1
178 %c1 = icmp eq i8 %a1, 1
179 br i1 %c1, label %block3, label %block2
182 %c2 = icmp eq i8 %a2, 1
186 %cond0 = phi i1 [ true, %block0 ], [ true, %block1 ], [ %c2, %block2 ]
187 %cond1 = zext i1 %cond0 to i32
188 %cond2 = sext i32 %cond1 to i64
189 %expval = call i64 @llvm.expect.with.probability.i64(i64 %cond2, i64 1, double 0.0)
190 %tobool = icmp ne i64 %expval, 0
191 br i1 %tobool, label %block4, label %block5
201 ; should have exactly the same behavior as test4
202 ; CHECK-LABEL: @test6_expect_with_prob_0_1(
204 ; CHECK: br i1 %c0, label %block3, label %block1, !prof !1
206 ; CHECK: br i1 %c1, label %block3, label %block2, !prof !1
208 ; CHECK: br i1 %tobool, label %block4, label %block5, !prof !1
209 define void @test6_expect_with_prob_0_1(i8 %a0, i8 %a1, i8 %a2) {
211 %c0 = icmp eq i8 %a0, 1
212 br i1 %c0, label %block3, label %block1
215 %c1 = icmp eq i8 %a1, 1
216 br i1 %c1, label %block3, label %block2
219 %c2 = icmp eq i8 %a2, 1
223 %cond0 = phi i1 [ true, %block0 ], [ true, %block1 ], [ %c2, %block2 ]
224 %cond1 = zext i1 %cond0 to i32
225 %cond2 = sext i32 %cond1 to i64
226 %expval = call i64 @llvm.expect.with.probability.i64(i64 %cond2, i64 0, double 1.0)
227 %tobool = icmp ne i64 %expval, 0
228 br i1 %tobool, label %block4, label %block5
238 ; CHECK: !0 = !{!"branch_weights", i32 2147483647, i32 1}
239 ; CHECK: !1 = !{!"branch_weights", i32 1, i32 2147483647}