1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -S -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -two-entry-phi-node-folding-threshold=4 -phi-node-folding-threshold=0 < %s | FileCheck %s
3
4declare void @sideeffect0()
5declare void @sideeffect1()
6
7define i32 @unknown(i32 %a, i32 %b, i32 %c, i32 %d) {
8; CHECK-LABEL: @unknown(
9; CHECK-NEXT:  entry:
10; CHECK-NEXT:    call void @sideeffect0()
11; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]
12; CHECK-NEXT:    [[V0:%.*]] = add i32 [[C:%.*]], [[D:%.*]]
13; CHECK-NEXT:    [[V1:%.*]] = sub i32 [[C]], [[D]]
14; CHECK-NEXT:    [[RES:%.*]] = select i1 [[CMP]], i32 [[V0]], i32 [[V1]]
15; CHECK-NEXT:    call void @sideeffect1()
16; CHECK-NEXT:    ret i32 [[RES]]
17;
18entry:
19  call void @sideeffect0()
20  %cmp = icmp eq i32 %a, %b
21  br i1 %cmp, label %cond.true, label %cond.false
22
23cond.true:
24  %v0 = add i32 %c, %d
25  br label %end
26
27cond.false:
28  %v1 = sub i32 %c, %d
29  br label %end
30
31end:
32  %res = phi i32 [ %v0, %cond.true ], [ %v1, %cond.false ]
33  call void @sideeffect1()
34  ret i32 %res
35}
36
37define i32 @predictably_taken(i32 %a, i32 %b, i32 %c, i32 %d) {
38; CHECK-LABEL: @predictably_taken(
39; CHECK-NEXT:  entry:
40; CHECK-NEXT:    call void @sideeffect0()
41; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]
42; CHECK-NEXT:    br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]], !prof [[PROF0:![0-9]+]]
43; CHECK:       cond.true:
44; CHECK-NEXT:    [[V0:%.*]] = add i32 [[C:%.*]], [[D:%.*]]
45; CHECK-NEXT:    br label [[END:%.*]]
46; CHECK:       cond.false:
47; CHECK-NEXT:    [[V1:%.*]] = sub i32 [[C]], [[D]]
48; CHECK-NEXT:    br label [[END]]
49; CHECK:       end:
50; CHECK-NEXT:    [[RES:%.*]] = phi i32 [ [[V0]], [[COND_TRUE]] ], [ [[V1]], [[COND_FALSE]] ]
51; CHECK-NEXT:    call void @sideeffect1()
52; CHECK-NEXT:    ret i32 [[RES]]
53;
54entry:
55  call void @sideeffect0()
56  %cmp = icmp eq i32 %a, %b
57  br i1 %cmp, label %cond.true, label %cond.false, !prof !0 ; likely branches to %cond.true
58
59cond.true:
60  %v0 = add i32 %c, %d
61  br label %end
62
63cond.false:
64  %v1 = sub i32 %c, %d
65  br label %end
66
67end:
68  %res = phi i32 [ %v0, %cond.true ], [ %v1, %cond.false ]
69  call void @sideeffect1()
70  ret i32 %res
71}
72
73define i32 @almost_predictably_taken(i32 %a, i32 %b, i32 %c, i32 %d) {
74; CHECK-LABEL: @almost_predictably_taken(
75; CHECK-NEXT:  entry:
76; CHECK-NEXT:    call void @sideeffect0()
77; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]
78; CHECK-NEXT:    [[V0:%.*]] = add i32 [[C:%.*]], [[D:%.*]]
79; CHECK-NEXT:    [[V1:%.*]] = sub i32 [[C]], [[D]]
80; CHECK-NEXT:    [[RES:%.*]] = select i1 [[CMP]], i32 [[V0]], i32 [[V1]], !prof [[PROF1:![0-9]+]]
81; CHECK-NEXT:    call void @sideeffect1()
82; CHECK-NEXT:    ret i32 [[RES]]
83;
84entry:
85  call void @sideeffect0()
86  %cmp = icmp eq i32 %a, %b
87  br i1 %cmp, label %cond.true, label %cond.false, !prof !1 ; almost likely branches to %cond.true
88
89cond.true:
90  %v0 = add i32 %c, %d
91  br label %end
92
93cond.false:
94  %v1 = sub i32 %c, %d
95  br label %end
96
97end:
98  %res = phi i32 [ %v0, %cond.true ], [ %v1, %cond.false ]
99  call void @sideeffect1()
100  ret i32 %res
101}
102
103define i32 @predictably_nontaken(i32 %a, i32 %b, i32 %c, i32 %d) {
104; CHECK-LABEL: @predictably_nontaken(
105; CHECK-NEXT:  entry:
106; CHECK-NEXT:    call void @sideeffect0()
107; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]
108; CHECK-NEXT:    br i1 [[CMP]], label [[COND_FALSE:%.*]], label [[COND_TRUE:%.*]], !prof [[PROF0]]
109; CHECK:       cond.true:
110; CHECK-NEXT:    [[V0:%.*]] = add i32 [[C:%.*]], [[D:%.*]]
111; CHECK-NEXT:    br label [[END:%.*]]
112; CHECK:       cond.false:
113; CHECK-NEXT:    [[V1:%.*]] = sub i32 [[C]], [[D]]
114; CHECK-NEXT:    br label [[END]]
115; CHECK:       end:
116; CHECK-NEXT:    [[RES:%.*]] = phi i32 [ [[V0]], [[COND_TRUE]] ], [ [[V1]], [[COND_FALSE]] ]
117; CHECK-NEXT:    call void @sideeffect1()
118; CHECK-NEXT:    ret i32 [[RES]]
119;
120entry:
121  call void @sideeffect0()
122  %cmp = icmp eq i32 %a, %b
123  br i1 %cmp, label %cond.false, label %cond.true, !prof !0 ; likely branches to %cond.false
124
125cond.true:
126  %v0 = add i32 %c, %d
127  br label %end
128
129cond.false:
130  %v1 = sub i32 %c, %d
131  br label %end
132
133end:
134  %res = phi i32 [ %v0, %cond.true ], [ %v1, %cond.false ]
135  call void @sideeffect1()
136  ret i32 %res
137}
138
139define i32 @almost_predictably_nontaken(i32 %a, i32 %b, i32 %c, i32 %d) {
140; CHECK-LABEL: @almost_predictably_nontaken(
141; CHECK-NEXT:  entry:
142; CHECK-NEXT:    call void @sideeffect0()
143; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]
144; CHECK-NEXT:    [[V0:%.*]] = add i32 [[C:%.*]], [[D:%.*]]
145; CHECK-NEXT:    [[V1:%.*]] = sub i32 [[C]], [[D]]
146; CHECK-NEXT:    [[RES:%.*]] = select i1 [[CMP]], i32 [[V1]], i32 [[V0]], !prof [[PROF1]]
147; CHECK-NEXT:    call void @sideeffect1()
148; CHECK-NEXT:    ret i32 [[RES]]
149;
150entry:
151  call void @sideeffect0()
152  %cmp = icmp eq i32 %a, %b
153  br i1 %cmp, label %cond.false, label %cond.true, !prof !1 ; probably likely branches to %cond.false
154
155cond.true:
156  %v0 = add i32 %c, %d
157  br label %end
158
159cond.false:
160  %v1 = sub i32 %c, %d
161  br label %end
162
163end:
164  %res = phi i32 [ %v0, %cond.true ], [ %v1, %cond.false ]
165  call void @sideeffect1()
166  ret i32 %res
167}
168
169define i32 @unpredictable(i32 %a, i32 %b, i32 %c, i32 %d) {
170; CHECK-LABEL: @unpredictable(
171; CHECK-NEXT:  entry:
172; CHECK-NEXT:    call void @sideeffect0()
173; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]
174; CHECK-NEXT:    [[V0:%.*]] = add i32 [[C:%.*]], [[D:%.*]]
175; CHECK-NEXT:    [[V1:%.*]] = sub i32 [[C]], [[D]]
176; CHECK-NEXT:    [[RES:%.*]] = select i1 [[CMP]], i32 [[V0]], i32 [[V1]], !unpredictable [[META2:![0-9]+]]
177; CHECK-NEXT:    call void @sideeffect1()
178; CHECK-NEXT:    ret i32 [[RES]]
179;
180entry:
181  call void @sideeffect0()
182  %cmp = icmp eq i32 %a, %b
183  br i1 %cmp, label %cond.true, label %cond.false, !unpredictable !2 ; unpredictable
184
185cond.true:
186  %v0 = add i32 %c, %d
187  br label %end
188
189cond.false:
190  %v1 = sub i32 %c, %d
191  br label %end
192
193end:
194  %res = phi i32 [ %v0, %cond.true ], [ %v1, %cond.false ]
195  call void @sideeffect1()
196  ret i32 %res
197}
198
199define i32 @unpredictable_yet_taken(i32 %a, i32 %b, i32 %c, i32 %d) {
200; CHECK-LABEL: @unpredictable_yet_taken(
201; CHECK-NEXT:  entry:
202; CHECK-NEXT:    call void @sideeffect0()
203; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]
204; CHECK-NEXT:    [[V0:%.*]] = add i32 [[C:%.*]], [[D:%.*]]
205; CHECK-NEXT:    [[V1:%.*]] = sub i32 [[C]], [[D]]
206; CHECK-NEXT:    [[RES:%.*]] = select i1 [[CMP]], i32 [[V0]], i32 [[V1]], !prof [[PROF0]], !unpredictable [[META2]]
207; CHECK-NEXT:    call void @sideeffect1()
208; CHECK-NEXT:    ret i32 [[RES]]
209;
210entry:
211  call void @sideeffect0()
212  %cmp = icmp eq i32 %a, %b
213  br i1 %cmp, label %cond.true, label %cond.false, !prof !0, !unpredictable !2 ; likely branches to %cond.true, yet unpredictable
214
215cond.true:
216  %v0 = add i32 %c, %d
217  br label %end
218
219cond.false:
220  %v1 = sub i32 %c, %d
221  br label %end
222
223end:
224  %res = phi i32 [ %v0, %cond.true ], [ %v1, %cond.false ]
225  call void @sideeffect1()
226  ret i32 %res
227}
228
229define i32 @unpredictable_yet_nontaken(i32 %a, i32 %b, i32 %c, i32 %d) {
230; CHECK-LABEL: @unpredictable_yet_nontaken(
231; CHECK-NEXT:  entry:
232; CHECK-NEXT:    call void @sideeffect0()
233; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]
234; CHECK-NEXT:    [[V0:%.*]] = add i32 [[C:%.*]], [[D:%.*]]
235; CHECK-NEXT:    [[V1:%.*]] = sub i32 [[C]], [[D]]
236; CHECK-NEXT:    [[RES:%.*]] = select i1 [[CMP]], i32 [[V1]], i32 [[V0]], !prof [[PROF0]], !unpredictable [[META2]]
237; CHECK-NEXT:    call void @sideeffect1()
238; CHECK-NEXT:    ret i32 [[RES]]
239;
240entry:
241  call void @sideeffect0()
242  %cmp = icmp eq i32 %a, %b
243  br i1 %cmp, label %cond.false, label %cond.true, !prof !0, !unpredictable !2 ; likely branches to %cond.false, yet unpredictable
244
245cond.true:
246  %v0 = add i32 %c, %d
247  br label %end
248
249cond.false:
250  %v1 = sub i32 %c, %d
251  br label %end
252
253end:
254  %res = phi i32 [ %v0, %cond.true ], [ %v1, %cond.false ]
255  call void @sideeffect1()
256  ret i32 %res
257}
258
259!0 = !{!"branch_weights", i32 99, i32 1}
260!1 = !{!"branch_weights", i32 70, i32 1}
261!2 = !{}
262
263; CHECK: !0 = !{!"branch_weights", i32 99, i32 1}
264; CHECK: !1 = !{!"branch_weights", i32 70, i32 1}
265; CHECK: !2 = !{}
266