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=0 -phi-node-folding-threshold=4 < %s | FileCheck %s
4 declare void @sideeffect0()
5 declare void @sideeffect1()
6 declare void @sideeffect2()
8 define i32 @unknown(i1 %c, i32 %a, i32 %b) {
9 ; CHECK-LABEL: @unknown(
11 ; CHECK-NEXT: call void @sideeffect0()
12 ; CHECK-NEXT: br i1 [[C:%.*]], label [[DISPATCH:%.*]], label [[END:%.*]]
14 ; CHECK-NEXT: call void @sideeffect1()
15 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]
16 ; CHECK-NEXT: [[VAL:%.*]] = add i32 [[A]], [[B]]
17 ; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[CMP]], i32 [[VAL]], i32 0
18 ; CHECK-NEXT: br label [[END]]
20 ; CHECK-NEXT: [[RES:%.*]] = phi i32 [ -1, [[ENTRY:%.*]] ], [ [[SPEC_SELECT]], [[DISPATCH]] ]
21 ; CHECK-NEXT: call void @sideeffect2()
22 ; CHECK-NEXT: ret i32 [[RES]]
25 call void @sideeffect0()
26 br i1 %c, label %dispatch, label %end
29 call void @sideeffect1()
30 %cmp = icmp eq i32 %a, %b
31 br i1 %cmp, label %cond.true, label %end
38 %res = phi i32 [ -1, %entry ], [ 0, %dispatch ], [ %val, %cond.true ]
39 call void @sideeffect2()
43 define i32 @predictably_taken(i1 %c, i32 %a, i32 %b) {
44 ; CHECK-LABEL: @predictably_taken(
46 ; CHECK-NEXT: call void @sideeffect0()
47 ; CHECK-NEXT: br i1 [[C:%.*]], label [[DISPATCH:%.*]], label [[END:%.*]]
49 ; CHECK-NEXT: call void @sideeffect1()
50 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]
51 ; CHECK-NEXT: [[VAL:%.*]] = add i32 [[A]], [[B]]
52 ; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[CMP]], i32 [[VAL]], i32 0, !prof [[PROF0:![0-9]+]]
53 ; CHECK-NEXT: br label [[END]]
55 ; CHECK-NEXT: [[RES:%.*]] = phi i32 [ -1, [[ENTRY:%.*]] ], [ [[SPEC_SELECT]], [[DISPATCH]] ]
56 ; CHECK-NEXT: call void @sideeffect2()
57 ; CHECK-NEXT: ret i32 [[RES]]
60 call void @sideeffect0()
61 br i1 %c, label %dispatch, label %end
64 call void @sideeffect1()
65 %cmp = icmp eq i32 %a, %b
66 br i1 %cmp, label %cond.true, label %end, !prof !0 ; likely branches to %cond.true
73 %res = phi i32 [ -1, %entry ], [ 0, %dispatch ], [ %val, %cond.true ]
74 call void @sideeffect2()
78 define i32 @predictably_nontaken(i1 %c, i32 %a, i32 %b) {
79 ; CHECK-LABEL: @predictably_nontaken(
81 ; CHECK-NEXT: call void @sideeffect0()
82 ; CHECK-NEXT: br i1 [[C:%.*]], label [[DISPATCH:%.*]], label [[END:%.*]]
84 ; CHECK-NEXT: call void @sideeffect1()
85 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]
86 ; CHECK-NEXT: br i1 [[CMP]], label [[END]], label [[COND_TRUE:%.*]], !prof [[PROF0]]
88 ; CHECK-NEXT: [[VAL:%.*]] = add i32 [[A]], [[B]]
89 ; CHECK-NEXT: br label [[END]]
91 ; CHECK-NEXT: [[RES:%.*]] = phi i32 [ -1, [[ENTRY:%.*]] ], [ 0, [[DISPATCH]] ], [ [[VAL]], [[COND_TRUE]] ]
92 ; CHECK-NEXT: call void @sideeffect2()
93 ; CHECK-NEXT: ret i32 [[RES]]
96 call void @sideeffect0()
97 br i1 %c, label %dispatch, label %end
100 call void @sideeffect1()
101 %cmp = icmp eq i32 %a, %b
102 br i1 %cmp, label %end, label %cond.true, !prof !0 ; likely branches to %end
105 %val = add i32 %a, %b
109 %res = phi i32 [ -1, %entry ], [ 0, %dispatch ], [ %val, %cond.true ]
110 call void @sideeffect2()
114 define i32 @almost_predictably_nontaken(i1 %c, i32 %a, i32 %b) {
115 ; CHECK-LABEL: @almost_predictably_nontaken(
117 ; CHECK-NEXT: call void @sideeffect0()
118 ; CHECK-NEXT: br i1 [[C:%.*]], label [[DISPATCH:%.*]], label [[END:%.*]]
120 ; CHECK-NEXT: call void @sideeffect1()
121 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]
122 ; CHECK-NEXT: [[VAL:%.*]] = add i32 [[A]], [[B]]
123 ; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[CMP]], i32 0, i32 [[VAL]], !prof [[PROF1:![0-9]+]]
124 ; CHECK-NEXT: br label [[END]]
126 ; CHECK-NEXT: [[RES:%.*]] = phi i32 [ -1, [[ENTRY:%.*]] ], [ [[SPEC_SELECT]], [[DISPATCH]] ]
127 ; CHECK-NEXT: call void @sideeffect2()
128 ; CHECK-NEXT: ret i32 [[RES]]
131 call void @sideeffect0()
132 br i1 %c, label %dispatch, label %end
135 call void @sideeffect1()
136 %cmp = icmp eq i32 %a, %b
137 br i1 %cmp, label %end, label %cond.true, !prof !1 ; almost likely branches to %end
140 %val = add i32 %a, %b
144 %res = phi i32 [ -1, %entry ], [ 0, %dispatch ], [ %val, %cond.true ]
145 call void @sideeffect2()
149 define i32 @unpredictable(i1 %c, i32 %a, i32 %b) {
150 ; CHECK-LABEL: @unpredictable(
152 ; CHECK-NEXT: call void @sideeffect0()
153 ; CHECK-NEXT: br i1 [[C:%.*]], label [[DISPATCH:%.*]], label [[END:%.*]]
155 ; CHECK-NEXT: call void @sideeffect1()
156 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]
157 ; CHECK-NEXT: [[VAL:%.*]] = add i32 [[A]], [[B]]
158 ; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[CMP]], i32 [[VAL]], i32 0, !unpredictable [[META2:![0-9]+]]
159 ; CHECK-NEXT: br label [[END]]
161 ; CHECK-NEXT: [[RES:%.*]] = phi i32 [ -1, [[ENTRY:%.*]] ], [ [[SPEC_SELECT]], [[DISPATCH]] ]
162 ; CHECK-NEXT: call void @sideeffect2()
163 ; CHECK-NEXT: ret i32 [[RES]]
166 call void @sideeffect0()
167 br i1 %c, label %dispatch, label %end
170 call void @sideeffect1()
171 %cmp = icmp eq i32 %a, %b
172 br i1 %cmp, label %cond.true, label %end, !unpredictable !2 ; unpredictable
175 %val = add i32 %a, %b
179 %res = phi i32 [ -1, %entry ], [ 0, %dispatch ], [ %val, %cond.true ]
180 call void @sideeffect2()
184 define i32 @unpredictable_yet_taken(i1 %c, i32 %a, i32 %b) {
185 ; CHECK-LABEL: @unpredictable_yet_taken(
187 ; CHECK-NEXT: call void @sideeffect0()
188 ; CHECK-NEXT: br i1 [[C:%.*]], label [[DISPATCH:%.*]], label [[END:%.*]]
190 ; CHECK-NEXT: call void @sideeffect1()
191 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]
192 ; CHECK-NEXT: [[VAL:%.*]] = add i32 [[A]], [[B]]
193 ; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[CMP]], i32 [[VAL]], i32 0, !prof [[PROF0]], !unpredictable [[META2]]
194 ; CHECK-NEXT: br label [[END]]
196 ; CHECK-NEXT: [[RES:%.*]] = phi i32 [ -1, [[ENTRY:%.*]] ], [ [[SPEC_SELECT]], [[DISPATCH]] ]
197 ; CHECK-NEXT: call void @sideeffect2()
198 ; CHECK-NEXT: ret i32 [[RES]]
201 call void @sideeffect0()
202 br i1 %c, label %dispatch, label %end
205 call void @sideeffect1()
206 %cmp = icmp eq i32 %a, %b
207 br i1 %cmp, label %cond.true, label %end, !prof !0, !unpredictable !2 ; likely branches to %cond.true, yet unpredictable
210 %val = add i32 %a, %b
214 %res = phi i32 [ -1, %entry ], [ 0, %dispatch ], [ %val, %cond.true ]
215 call void @sideeffect2()
219 define i32 @unpredictable_yet_nontaken(i1 %c, i32 %a, i32 %b) {
220 ; CHECK-LABEL: @unpredictable_yet_nontaken(
222 ; CHECK-NEXT: call void @sideeffect0()
223 ; CHECK-NEXT: br i1 [[C:%.*]], label [[DISPATCH:%.*]], label [[END:%.*]]
225 ; CHECK-NEXT: call void @sideeffect1()
226 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]
227 ; CHECK-NEXT: [[VAL:%.*]] = add i32 [[A]], [[B]]
228 ; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[CMP]], i32 0, i32 [[VAL]], !prof [[PROF0]], !unpredictable [[META2]]
229 ; CHECK-NEXT: br label [[END]]
231 ; CHECK-NEXT: [[RES:%.*]] = phi i32 [ -1, [[ENTRY:%.*]] ], [ [[SPEC_SELECT]], [[DISPATCH]] ]
232 ; CHECK-NEXT: call void @sideeffect2()
233 ; CHECK-NEXT: ret i32 [[RES]]
236 call void @sideeffect0()
237 br i1 %c, label %dispatch, label %end
240 call void @sideeffect1()
241 %cmp = icmp eq i32 %a, %b
242 br i1 %cmp, label %end, label %cond.true, !prof !0, !unpredictable !2 ; likely branches to %end, yet unpredictable
245 %val = add i32 %a, %b
249 %res = phi i32 [ -1, %entry ], [ 0, %dispatch ], [ %val, %cond.true ]
250 call void @sideeffect2()
254 !0 = !{!"branch_weights", i32 99, i32 1}
255 !1 = !{!"branch_weights", i32 70, i32 1}
258 ; CHECK: !0 = !{!"branch_weights", i32 99, i32 1}
259 ; CHECK: !1 = !{!"branch_weights", i32 70, i32 1}