[clang][modules] Don't prevent translation of FW_Private includes when explicitly...
[llvm-project.git] / llvm / test / Transforms / LowerExpectIntrinsic / phi_unexpect.ll
blob2bad66343b761b17b41adebc6524a50ad05543b3
1 ; RUN: opt -S -passes='function(lower-expect),strip-dead-prototypes' -likely-branch-weight=2147483647 -unlikely-branch-weight=1 < %s | FileCheck %s
3 ; The C case
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))
8 ; The C case
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))
13 declare void @foo()
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(
19 ; CHECK: block0:
20 ; CHECK-NOT: prof
21 ; CHECK: block1:
22 ; CHECK-NOT: prof
23 ; CHECK: block3:
24 ; CHECK: br i1 %tobool, label %block4, label %block5, !prof !0
25 define void @test1_expect_1(i8 %a0, i8 %a1, i8 %a2) {
26 block0:
27   %c0 = icmp eq i8 %a0, 1
28   br i1 %c0, label %block3, label %block1
30 block1:
31   %c1 = icmp eq i8 %a1, 1
32   br i1 %c1, label %block3, label %block2
34 block2:
35   %c2 = icmp eq i8 %a2, 1
36   br label %block3
38 block3:
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
46 block4:
47   call void @foo()
48   br label %block5
50 block5:
51   ret void
54 ; should have exactly the same behavior as test1
55 ; CHECK-LABEL: @test2_expect_with_prob_1_1(
56 ; CHECK: block0:
57 ; CHECK-NOT: prof
58 ; CHECK: block1:
59 ; CHECK-NOT: prof
60 ; CHECK: block3:
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) {
63 block0:
64   %c0 = icmp eq i8 %a0, 1
65   br i1 %c0, label %block3, label %block1
67 block1:
68   %c1 = icmp eq i8 %a1, 1
69   br i1 %c1, label %block3, label %block2
71 block2:
72   %c2 = icmp eq i8 %a2, 1
73   br label %block3
75 block3:
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
83 block4:
84   call void @foo()
85   br label %block5
87 block5:
88   ret void
91 ; should have exactly the same behavior as test1
92 ; CHECK-LABEL: @test3_expect_with_prob_0_0(
93 ; CHECK: block0:
94 ; CHECK-NOT: prof
95 ; CHECK: block1:
96 ; CHECK-NOT: prof
97 ; CHECK: block3:
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) {
100 block0:
101   %c0 = icmp eq i8 %a0, 1
102   br i1 %c0, label %block3, label %block1
104 block1:
105   %c1 = icmp eq i8 %a1, 1
106   br i1 %c1, label %block3, label %block2
108 block2:
109   %c2 = icmp eq i8 %a2, 1
110   br label %block3
112 block3:
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
120 block4:
121   call void @foo()
122   br label %block5
124 block5:
125   ret void
128 ; CHECK-LABEL: @test4_expect_0(
129 ; CHECK: block0:
130 ; CHECK: br i1 %c0, label %block3, label %block1, !prof !1
131 ; CHECK: block1:
132 ; CHECK: br i1 %c1, label %block3, label %block2, !prof !1
133 ; CHECK: block3:
134 ; CHECK: br i1 %tobool, label %block4, label %block5, !prof !1
135 define void @test4_expect_0(i8 %a0, i8 %a1, i8 %a2) {
136 block0:
137   %c0 = icmp eq i8 %a0, 1
138   br i1 %c0, label %block3, label %block1
140 block1:
141   %c1 = icmp eq i8 %a1, 1
142   br i1 %c1, label %block3, label %block2
144 block2:
145   %c2 = icmp eq i8 %a2, 1
146   br label %block3
148 block3:
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
156 block4:
157   call void @foo()
158   br label %block5
160 block5:
161   ret void
164 ; should have exactly the same behavior as test4
165 ; CHECK-LABEL: @test5_expect_with_prob_1_0(
166 ; CHECK: block0:
167 ; CHECK: br i1 %c0, label %block3, label %block1, !prof !1
168 ; CHECK: block1:
169 ; CHECK: br i1 %c1, label %block3, label %block2, !prof !1
170 ; CHECK: block3:
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) {
173 block0:
174   %c0 = icmp eq i8 %a0, 1
175   br i1 %c0, label %block3, label %block1
177 block1:
178   %c1 = icmp eq i8 %a1, 1
179   br i1 %c1, label %block3, label %block2
181 block2:
182   %c2 = icmp eq i8 %a2, 1
183   br label %block3
185 block3:
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
193 block4:
194   call void @foo()
195   br label %block5
197 block5:
198   ret void
201 ; should have exactly the same behavior as test4
202 ; CHECK-LABEL: @test6_expect_with_prob_0_1(
203 ; CHECK: block0:
204 ; CHECK: br i1 %c0, label %block3, label %block1, !prof !1
205 ; CHECK: block1:
206 ; CHECK: br i1 %c1, label %block3, label %block2, !prof !1
207 ; CHECK: block3:
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) {
210 block0:
211   %c0 = icmp eq i8 %a0, 1
212   br i1 %c0, label %block3, label %block1
214 block1:
215   %c1 = icmp eq i8 %a1, 1
216   br i1 %c1, label %block3, label %block2
218 block2:
219   %c2 = icmp eq i8 %a2, 1
220   br label %block3
222 block3:
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
230 block4:
231   call void @foo()
232   br label %block5
234 block5:
235   ret void
238 ; CHECK: !0 = !{!"branch_weights", i32 2147483647, i32 1}
239 ; CHECK: !1 = !{!"branch_weights", i32 1, i32 2147483647}