1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes
2; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal  -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=18 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
3; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal  -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=21 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
4; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal  -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
5; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal  -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM
6
7define i8 @test1(i32 %a, i32 %length) {
8; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone
9; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@test1
10; IS__TUNIT_OPM-SAME: (i32 [[A:%.*]], i32 [[LENGTH:%.*]]) [[ATTR0:#.*]] {
11; IS__TUNIT_OPM-NEXT:  entry:
12; IS__TUNIT_OPM-NEXT:    br label [[LOOP:%.*]]
13; IS__TUNIT_OPM:       loop:
14; IS__TUNIT_OPM-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
15; IS__TUNIT_OPM-NEXT:    [[CND:%.*]] = icmp sge i32 [[IV]], 0
16; IS__TUNIT_OPM-NEXT:    br i1 [[CND]], label [[BACKEDGE]], label [[EXIT:%.*]]
17; IS__TUNIT_OPM:       backedge:
18; IS__TUNIT_OPM-NEXT:    [[IV_NEXT]] = add nsw i32 [[IV]], 1
19; IS__TUNIT_OPM-NEXT:    [[CONT:%.*]] = icmp slt i32 [[IV_NEXT]], 400
20; IS__TUNIT_OPM-NEXT:    br i1 [[CONT]], label [[LOOP]], label [[EXIT]]
21; IS__TUNIT_OPM:       exit:
22; IS__TUNIT_OPM-NEXT:    ret i8 0
23;
24; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
25; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@test1
26; IS__TUNIT_NPM-SAME: (i32 [[A:%.*]], i32 [[LENGTH:%.*]]) [[ATTR0:#.*]] {
27; IS__TUNIT_NPM-NEXT:  entry:
28; IS__TUNIT_NPM-NEXT:    br label [[LOOP:%.*]]
29; IS__TUNIT_NPM:       loop:
30; IS__TUNIT_NPM-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
31; IS__TUNIT_NPM-NEXT:    br label [[BACKEDGE]]
32; IS__TUNIT_NPM:       backedge:
33; IS__TUNIT_NPM-NEXT:    [[IV_NEXT]] = add nsw i32 [[IV]], 1
34; IS__TUNIT_NPM-NEXT:    [[CONT:%.*]] = icmp slt i32 [[IV_NEXT]], 400
35; IS__TUNIT_NPM-NEXT:    br i1 [[CONT]], label [[LOOP]], label [[EXIT:%.*]]
36; IS__TUNIT_NPM:       exit:
37; IS__TUNIT_NPM-NEXT:    ret i8 0
38;
39; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone
40; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test1
41; IS__CGSCC_OPM-SAME: (i32 [[A:%.*]], i32 [[LENGTH:%.*]]) [[ATTR0:#.*]] {
42; IS__CGSCC_OPM-NEXT:  entry:
43; IS__CGSCC_OPM-NEXT:    br label [[LOOP:%.*]]
44; IS__CGSCC_OPM:       loop:
45; IS__CGSCC_OPM-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
46; IS__CGSCC_OPM-NEXT:    [[CND:%.*]] = icmp sge i32 [[IV]], 0
47; IS__CGSCC_OPM-NEXT:    br i1 [[CND]], label [[BACKEDGE]], label [[EXIT:%.*]]
48; IS__CGSCC_OPM:       backedge:
49; IS__CGSCC_OPM-NEXT:    [[IV_NEXT]] = add nsw i32 [[IV]], 1
50; IS__CGSCC_OPM-NEXT:    [[CONT:%.*]] = icmp slt i32 [[IV_NEXT]], 400
51; IS__CGSCC_OPM-NEXT:    br i1 [[CONT]], label [[LOOP]], label [[EXIT]]
52; IS__CGSCC_OPM:       exit:
53; IS__CGSCC_OPM-NEXT:    ret i8 0
54;
55; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
56; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test1
57; IS__CGSCC_NPM-SAME: (i32 [[A:%.*]], i32 [[LENGTH:%.*]]) [[ATTR0:#.*]] {
58; IS__CGSCC_NPM-NEXT:  entry:
59; IS__CGSCC_NPM-NEXT:    br label [[LOOP:%.*]]
60; IS__CGSCC_NPM:       loop:
61; IS__CGSCC_NPM-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
62; IS__CGSCC_NPM-NEXT:    br label [[BACKEDGE]]
63; IS__CGSCC_NPM:       backedge:
64; IS__CGSCC_NPM-NEXT:    [[IV_NEXT]] = add nsw i32 [[IV]], 1
65; IS__CGSCC_NPM-NEXT:    [[CONT:%.*]] = icmp slt i32 [[IV_NEXT]], 400
66; IS__CGSCC_NPM-NEXT:    br i1 [[CONT]], label [[LOOP]], label [[EXIT:%.*]]
67; IS__CGSCC_NPM:       exit:
68; IS__CGSCC_NPM-NEXT:    ret i8 0
69;
70entry:
71  br label %loop
72
73loop:
74  %iv = phi i32 [0, %entry], [%iv.next, %backedge]
75  %cnd = icmp sge i32 %iv, 0
76  br i1 %cnd, label %backedge, label %exit
77
78backedge:
79  %iv.next = add nsw i32 %iv, 1
80  %cont = icmp slt i32 %iv.next, 400
81  br i1 %cont, label %loop, label %exit
82
83exit:
84  ret i8 0
85}
86
87define i8 @test2(i32 %n) {
88; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone
89; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@test2
90; IS__TUNIT_OPM-SAME: (i32 [[N:%.*]]) [[ATTR0]] {
91; IS__TUNIT_OPM-NEXT:  entry:
92; IS__TUNIT_OPM-NEXT:    br label [[LOOP:%.*]]
93; IS__TUNIT_OPM:       loop:
94; IS__TUNIT_OPM-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
95; IS__TUNIT_OPM-NEXT:    [[IV2:%.*]] = phi i32 [ [[N]], [[ENTRY]] ], [ [[IV2_NEXT:%.*]], [[BACKEDGE]] ]
96; IS__TUNIT_OPM-NEXT:    [[CND1:%.*]] = icmp sge i32 [[IV]], 0
97; IS__TUNIT_OPM-NEXT:    [[CND2:%.*]] = icmp sgt i32 [[IV2]], 0
98; IS__TUNIT_OPM-NEXT:    [[CND:%.*]] = and i1 [[CND1]], [[CND2]]
99; IS__TUNIT_OPM-NEXT:    br i1 [[CND]], label [[BACKEDGE]], label [[EXIT:%.*]]
100; IS__TUNIT_OPM:       backedge:
101; IS__TUNIT_OPM-NEXT:    [[IV_NEXT]] = add nsw i32 [[IV]], 1
102; IS__TUNIT_OPM-NEXT:    [[IV2_NEXT]] = sub nsw i32 [[IV2]], 1
103; IS__TUNIT_OPM-NEXT:    [[CONT1:%.*]] = icmp slt i32 [[IV_NEXT]], 400
104; IS__TUNIT_OPM-NEXT:    [[CONT2:%.*]] = icmp sgt i32 [[IV2_NEXT]], 0
105; IS__TUNIT_OPM-NEXT:    [[CONT:%.*]] = and i1 [[CONT1]], [[CONT2]]
106; IS__TUNIT_OPM-NEXT:    br i1 [[CONT]], label [[LOOP]], label [[EXIT]]
107; IS__TUNIT_OPM:       exit:
108; IS__TUNIT_OPM-NEXT:    ret i8 0
109;
110; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
111; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@test2
112; IS__TUNIT_NPM-SAME: (i32 [[N:%.*]]) [[ATTR0]] {
113; IS__TUNIT_NPM-NEXT:  entry:
114; IS__TUNIT_NPM-NEXT:    br label [[LOOP:%.*]]
115; IS__TUNIT_NPM:       loop:
116; IS__TUNIT_NPM-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
117; IS__TUNIT_NPM-NEXT:    [[IV2:%.*]] = phi i32 [ [[N]], [[ENTRY]] ], [ [[IV2_NEXT:%.*]], [[BACKEDGE]] ]
118; IS__TUNIT_NPM-NEXT:    [[CND1:%.*]] = icmp sge i32 [[IV]], 0
119; IS__TUNIT_NPM-NEXT:    [[CND2:%.*]] = icmp sgt i32 [[IV2]], 0
120; IS__TUNIT_NPM-NEXT:    [[CND:%.*]] = and i1 [[CND1]], [[CND2]]
121; IS__TUNIT_NPM-NEXT:    br i1 [[CND]], label [[BACKEDGE]], label [[EXIT:%.*]]
122; IS__TUNIT_NPM:       backedge:
123; IS__TUNIT_NPM-NEXT:    [[IV_NEXT]] = add nsw i32 [[IV]], 1
124; IS__TUNIT_NPM-NEXT:    [[IV2_NEXT]] = sub nsw i32 [[IV2]], 1
125; IS__TUNIT_NPM-NEXT:    [[CONT1:%.*]] = icmp slt i32 [[IV_NEXT]], 400
126; IS__TUNIT_NPM-NEXT:    [[CONT2:%.*]] = icmp sgt i32 [[IV2_NEXT]], 0
127; IS__TUNIT_NPM-NEXT:    [[CONT:%.*]] = and i1 [[CONT1]], [[CONT2]]
128; IS__TUNIT_NPM-NEXT:    br i1 [[CONT]], label [[LOOP]], label [[EXIT]]
129; IS__TUNIT_NPM:       exit:
130; IS__TUNIT_NPM-NEXT:    ret i8 0
131;
132; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone
133; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test2
134; IS__CGSCC_OPM-SAME: (i32 [[N:%.*]]) [[ATTR0]] {
135; IS__CGSCC_OPM-NEXT:  entry:
136; IS__CGSCC_OPM-NEXT:    br label [[LOOP:%.*]]
137; IS__CGSCC_OPM:       loop:
138; IS__CGSCC_OPM-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
139; IS__CGSCC_OPM-NEXT:    [[IV2:%.*]] = phi i32 [ [[N]], [[ENTRY]] ], [ [[IV2_NEXT:%.*]], [[BACKEDGE]] ]
140; IS__CGSCC_OPM-NEXT:    [[CND1:%.*]] = icmp sge i32 [[IV]], 0
141; IS__CGSCC_OPM-NEXT:    [[CND2:%.*]] = icmp sgt i32 [[IV2]], 0
142; IS__CGSCC_OPM-NEXT:    [[CND:%.*]] = and i1 [[CND1]], [[CND2]]
143; IS__CGSCC_OPM-NEXT:    br i1 [[CND]], label [[BACKEDGE]], label [[EXIT:%.*]]
144; IS__CGSCC_OPM:       backedge:
145; IS__CGSCC_OPM-NEXT:    [[IV_NEXT]] = add nsw i32 [[IV]], 1
146; IS__CGSCC_OPM-NEXT:    [[IV2_NEXT]] = sub nsw i32 [[IV2]], 1
147; IS__CGSCC_OPM-NEXT:    [[CONT1:%.*]] = icmp slt i32 [[IV_NEXT]], 400
148; IS__CGSCC_OPM-NEXT:    [[CONT2:%.*]] = icmp sgt i32 [[IV2_NEXT]], 0
149; IS__CGSCC_OPM-NEXT:    [[CONT:%.*]] = and i1 [[CONT1]], [[CONT2]]
150; IS__CGSCC_OPM-NEXT:    br i1 [[CONT]], label [[LOOP]], label [[EXIT]]
151; IS__CGSCC_OPM:       exit:
152; IS__CGSCC_OPM-NEXT:    ret i8 0
153;
154; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
155; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test2
156; IS__CGSCC_NPM-SAME: (i32 [[N:%.*]]) [[ATTR0]] {
157; IS__CGSCC_NPM-NEXT:  entry:
158; IS__CGSCC_NPM-NEXT:    br label [[LOOP:%.*]]
159; IS__CGSCC_NPM:       loop:
160; IS__CGSCC_NPM-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
161; IS__CGSCC_NPM-NEXT:    [[IV2:%.*]] = phi i32 [ [[N]], [[ENTRY]] ], [ [[IV2_NEXT:%.*]], [[BACKEDGE]] ]
162; IS__CGSCC_NPM-NEXT:    [[CND1:%.*]] = icmp sge i32 [[IV]], 0
163; IS__CGSCC_NPM-NEXT:    [[CND2:%.*]] = icmp sgt i32 [[IV2]], 0
164; IS__CGSCC_NPM-NEXT:    [[CND:%.*]] = and i1 [[CND1]], [[CND2]]
165; IS__CGSCC_NPM-NEXT:    br i1 [[CND]], label [[BACKEDGE]], label [[EXIT:%.*]]
166; IS__CGSCC_NPM:       backedge:
167; IS__CGSCC_NPM-NEXT:    [[IV_NEXT]] = add nsw i32 [[IV]], 1
168; IS__CGSCC_NPM-NEXT:    [[IV2_NEXT]] = sub nsw i32 [[IV2]], 1
169; IS__CGSCC_NPM-NEXT:    [[CONT1:%.*]] = icmp slt i32 [[IV_NEXT]], 400
170; IS__CGSCC_NPM-NEXT:    [[CONT2:%.*]] = icmp sgt i32 [[IV2_NEXT]], 0
171; IS__CGSCC_NPM-NEXT:    [[CONT:%.*]] = and i1 [[CONT1]], [[CONT2]]
172; IS__CGSCC_NPM-NEXT:    br i1 [[CONT]], label [[LOOP]], label [[EXIT]]
173; IS__CGSCC_NPM:       exit:
174; IS__CGSCC_NPM-NEXT:    ret i8 0
175;
176entry:
177  br label %loop
178
179loop:
180  %iv = phi i32 [0, %entry], [%iv.next, %backedge]
181  %iv2 = phi i32 [%n, %entry], [%iv2.next, %backedge]
182
183  %cnd1 = icmp sge i32 %iv, 0
184  %cnd2 = icmp sgt i32 %iv2, 0
185  %cnd = and i1 %cnd1, %cnd2
186  br i1 %cnd, label %backedge, label %exit
187
188backedge:
189  %iv.next = add nsw i32 %iv, 1
190  %iv2.next = sub nsw i32 %iv2, 1
191  %cont1 = icmp slt i32 %iv.next, 400
192  %cont2 = icmp sgt i32 %iv2.next, 0
193  %cont = and i1 %cont1, %cont2
194  br i1 %cont, label %loop, label %exit
195
196exit:
197  ret i8 0
198}
199
200; Merging cont block into do block.
201define i32 @test3(i32 %i, i1 %f, i32 %n) {
202; IS________OPM-LABEL: define {{[^@]+}}@test3
203; IS________OPM-SAME: (i32 [[I:%.*]], i1 [[F:%.*]], i32 [[N:%.*]]) {
204; IS________OPM-NEXT:  entry:
205; IS________OPM-NEXT:    [[C:%.*]] = icmp ne i32 [[I]], -2134
206; IS________OPM-NEXT:    br i1 [[C]], label [[DO:%.*]], label [[EXIT:%.*]]
207; IS________OPM:       exit:
208; IS________OPM-NEXT:    [[C1:%.*]] = icmp ne i32 [[I]], -42
209; IS________OPM-NEXT:    br i1 [[C1]], label [[EXIT2:%.*]], label [[EXIT]]
210; IS________OPM:       cont:
211; IS________OPM-NEXT:    [[COND_3:%.*]] = icmp sgt i32 [[I]], [[N]]
212; IS________OPM-NEXT:    br i1 [[COND_3]], label [[EXIT2]], label [[EXIT]]
213; IS________OPM:       do:
214; IS________OPM-NEXT:    [[COND_0:%.*]] = icmp sgt i32 [[I]], 0
215; IS________OPM-NEXT:    [[CONSUME:%.*]] = call i32 @consume(i1 [[COND_0]])
216; IS________OPM-NEXT:    [[COND:%.*]] = icmp eq i32 [[I]], 0
217; IS________OPM-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[COND]]) [ "deopt"() ]
218; IS________OPM-NEXT:    [[COND_2:%.*]] = icmp sgt i32 [[I]], 0
219; IS________OPM-NEXT:    br i1 [[COND_2]], label [[EXIT]], label [[CONT:%.*]]
220; IS________OPM:       exit2:
221; IS________OPM-NEXT:    ret i32 30
222;
223; IS________NPM-LABEL: define {{[^@]+}}@test3
224; IS________NPM-SAME: (i32 [[I:%.*]], i1 [[F:%.*]], i32 [[N:%.*]]) {
225; IS________NPM-NEXT:  entry:
226; IS________NPM-NEXT:    [[C:%.*]] = icmp ne i32 [[I]], -2134
227; IS________NPM-NEXT:    br i1 [[C]], label [[DO:%.*]], label [[EXIT:%.*]]
228; IS________NPM:       exit:
229; IS________NPM-NEXT:    [[C1:%.*]] = icmp ne i32 [[I]], -42
230; IS________NPM-NEXT:    br i1 [[C1]], label [[EXIT2:%.*]], label [[EXIT]]
231; IS________NPM:       cont:
232; IS________NPM-NEXT:    [[COND_3:%.*]] = icmp sgt i32 [[I]], [[N]]
233; IS________NPM-NEXT:    br i1 [[COND_3]], label [[EXIT2]], label [[EXIT]]
234; IS________NPM:       do:
235; IS________NPM-NEXT:    [[COND_0:%.*]] = icmp sgt i32 [[I]], 0
236; IS________NPM-NEXT:    [[CONSUME:%.*]] = call i32 @consume(i1 [[COND_0]])
237; IS________NPM-NEXT:    [[COND:%.*]] = icmp eq i32 [[I]], 0
238; IS________NPM-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[COND]]) [ "deopt"() ]
239; IS________NPM-NEXT:    br label [[CONT:%.*]]
240; IS________NPM:       exit2:
241; IS________NPM-NEXT:    ret i32 30
242;
243entry:
244  %c = icmp ne i32 %i, -2134
245  br i1 %c, label %do, label %exit
246
247exit:
248  %c1 = icmp ne i32 %i, -42
249  br i1 %c1, label %exit2, label %exit
250
251; Here cont is merged to do and i is any value except -2134.
252; i is not the single value: zero.
253cont:
254  %cond.3 = icmp sgt i32 %i, %n
255  br i1 %cond.3, label %exit2, label %exit
256
257do:
258  %cond.0 = icmp sgt i32 %i, 0
259  %consume = call i32 @consume(i1 %cond.0)
260  %cond = icmp eq i32 %i, 0
261  call void (i1, ...) @llvm.experimental.guard(i1 %cond) [ "deopt"() ]
262  %cond.2 = icmp sgt i32 %i, 0
263  br i1 %cond.2, label %exit, label %cont
264
265exit2:
266; LatticeVal for: 'i32 %i' is: constantrange<-2134, 1>
267  ret i32 30
268}
269
270; FIXME: We should be able to merge cont into do.
271; FIXME: COND should be replaced with false. This will be fixed by improving LVI.
272define i32 @test4(i32 %i, i1 %f, i32 %n) {
273; CHECK-LABEL: define {{[^@]+}}@test4
274; CHECK-SAME: (i32 [[I:%.*]], i1 [[F:%.*]], i32 [[N:%.*]]) {
275; CHECK-NEXT:  entry:
276; CHECK-NEXT:    [[C:%.*]] = icmp ne i32 [[I]], -2134
277; CHECK-NEXT:    br i1 [[C]], label [[DO:%.*]], label [[EXIT:%.*]]
278; CHECK:       exit:
279; CHECK-NEXT:    [[C1:%.*]] = icmp ne i32 [[I]], -42
280; CHECK-NEXT:    br i1 [[C1]], label [[EXIT2:%.*]], label [[EXIT]]
281; CHECK:       cont:
282; CHECK-NEXT:    call void @dummy(i1 [[F]]) [[ATTR2:#.*]]
283; CHECK-NEXT:    br label [[EXIT2]]
284; CHECK:       do:
285; CHECK-NEXT:    call void @dummy(i1 [[F]]) [[ATTR2]]
286; CHECK-NEXT:    [[CONSUME:%.*]] = call i32 @exit()
287; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[F]])
288; CHECK-NEXT:    [[COND:%.*]] = icmp eq i1 [[F]], false
289; CHECK-NEXT:    br i1 [[COND]], label [[EXIT]], label [[CONT:%.*]]
290; CHECK:       exit2:
291; CHECK-NEXT:    ret i32 30
292;
293entry:
294  %c = icmp ne i32 %i, -2134
295  br i1 %c, label %do, label %exit
296
297exit:                                             ; preds = %do, %cont, %exit, %entry
298  %c1 = icmp ne i32 %i, -42
299  br i1 %c1, label %exit2, label %exit
300
301cont:                                             ; preds = %do
302  call void @dummy(i1 %f)
303  br label %exit2
304
305do:                                               ; preds = %entry
306  call void @dummy(i1 %f)
307  %consume = call i32 @exit()
308  call void @llvm.assume(i1 %f)
309  %cond = icmp eq i1 %f, false
310  br i1 %cond, label %exit, label %cont
311
312exit2:                                            ; preds = %cont, %exit
313  ret i32 30
314}
315
316declare i32 @exit()
317declare i32 @consume(i1)
318declare void @llvm.assume(i1) nounwind
319declare void @dummy(i1) nounwind
320declare void @llvm.experimental.guard(i1, ...)
321