xref: /llvm-project/llvm/test/Transforms/LoopUnroll/runtime-loop-multiexit-dom-verify.ll (revision b9808e5660f5fe9e7414c0c0b93acd899235471c)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=loop-unroll -unroll-runtime=true -unroll-runtime-epilog=false -unroll-runtime-multi-exit=true -unroll-count=4  -verify-dom-info -S | FileCheck %s
3
4; REQUIRES: asserts
5; The tests below are for verifying dom tree after runtime unrolling
6; with multiple exit/exiting blocks.
7
8; We explicitly set the unroll count so that expensiveTripCount computation is allowed.
9
10declare i1 @unknown(i32) readonly nounwind willreturn
11
12; mergedexit block has edges from loop exit blocks.
13define i64 @test1() {
14; CHECK-LABEL: @test1(
15; CHECK-NEXT:  entry:
16; CHECK-NEXT:    br label [[PREHEADER:%.*]]
17; CHECK:       preheader:
18; CHECK-NEXT:    [[TRIP:%.*]] = zext i32 undef to i64
19; CHECK-NEXT:    br label [[HEADER:%.*]]
20; CHECK:       header:
21; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 2, [[PREHEADER]] ], [ [[ADD_IV_3:%.*]], [[LATCH_3:%.*]] ]
22; CHECK-NEXT:    [[ADD_IV:%.*]] = add nuw nsw i64 [[IV]], 2
23; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i64 [[ADD_IV]], [[TRIP]]
24; CHECK-NEXT:    br i1 [[CMP1]], label [[LATCH:%.*]], label [[HEADEREXIT:%.*]]
25; CHECK:       latch:
26; CHECK-NEXT:    [[SHFT:%.*]] = ashr i64 [[ADD_IV]], 1
27; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i64 [[SHFT]], [[TRIP]]
28; CHECK-NEXT:    br i1 [[CMP2]], label [[HEADER_1:%.*]], label [[LATCHEXIT:%.*]]
29; CHECK:       header.1:
30; CHECK-NEXT:    [[ADD_IV_1:%.*]] = add nuw nsw i64 [[IV]], 4
31; CHECK-NEXT:    [[CMP1_1:%.*]] = icmp ult i64 [[ADD_IV_1]], [[TRIP]]
32; CHECK-NEXT:    br i1 [[CMP1_1]], label [[LATCH_1:%.*]], label [[HEADEREXIT]]
33; CHECK:       latch.1:
34; CHECK-NEXT:    [[SHFT_1:%.*]] = ashr i64 [[ADD_IV_1]], 1
35; CHECK-NEXT:    [[CMP2_1:%.*]] = icmp ult i64 [[SHFT_1]], [[TRIP]]
36; CHECK-NEXT:    br i1 [[CMP2_1]], label [[HEADER_2:%.*]], label [[LATCHEXIT]]
37; CHECK:       header.2:
38; CHECK-NEXT:    [[ADD_IV_2:%.*]] = add nuw nsw i64 [[IV]], 6
39; CHECK-NEXT:    [[CMP1_2:%.*]] = icmp ult i64 [[ADD_IV_2]], [[TRIP]]
40; CHECK-NEXT:    br i1 [[CMP1_2]], label [[LATCH_2:%.*]], label [[HEADEREXIT]]
41; CHECK:       latch.2:
42; CHECK-NEXT:    [[SHFT_2:%.*]] = ashr i64 [[ADD_IV_2]], 1
43; CHECK-NEXT:    [[CMP2_2:%.*]] = icmp ult i64 [[SHFT_2]], [[TRIP]]
44; CHECK-NEXT:    br i1 [[CMP2_2]], label [[HEADER_3:%.*]], label [[LATCHEXIT]]
45; CHECK:       header.3:
46; CHECK-NEXT:    [[ADD_IV_3]] = add nuw nsw i64 [[IV]], 8
47; CHECK-NEXT:    [[CMP1_3:%.*]] = icmp ult i64 [[ADD_IV_3]], [[TRIP]]
48; CHECK-NEXT:    br i1 [[CMP1_3]], label [[LATCH_3]], label [[HEADEREXIT]]
49; CHECK:       latch.3:
50; CHECK-NEXT:    [[SHFT_3:%.*]] = ashr i64 [[ADD_IV_3]], 1
51; CHECK-NEXT:    [[CMP2_3:%.*]] = icmp ult i64 [[SHFT_3]], [[TRIP]]
52; CHECK-NEXT:    br i1 [[CMP2_3]], label [[HEADER]], label [[LATCHEXIT]], !llvm.loop [[LOOP0:![0-9]+]]
53; CHECK:       headerexit:
54; CHECK-NEXT:    [[ADDPHI:%.*]] = phi i64 [ [[ADD_IV]], [[HEADER]] ], [ [[ADD_IV_1]], [[HEADER_1]] ], [ [[ADD_IV_2]], [[HEADER_2]] ], [ [[ADD_IV_3]], [[HEADER_3]] ]
55; CHECK-NEXT:    br label [[MERGEDEXIT:%.*]]
56; CHECK:       latchexit:
57; CHECK-NEXT:    [[SHFTPHI:%.*]] = phi i64 [ [[SHFT]], [[LATCH]] ], [ [[SHFT_1]], [[LATCH_1]] ], [ [[SHFT_2]], [[LATCH_2]] ], [ [[SHFT_3]], [[LATCH_3]] ]
58; CHECK-NEXT:    br label [[MERGEDEXIT]]
59; CHECK:       mergedexit:
60; CHECK-NEXT:    [[RETVAL:%.*]] = phi i64 [ [[ADDPHI]], [[HEADEREXIT]] ], [ [[SHFTPHI]], [[LATCHEXIT]] ]
61; CHECK-NEXT:    ret i64 [[RETVAL]]
62;
63entry:
64  br label %preheader
65
66preheader:                                              ; preds = %bb
67  %trip = zext i32 undef to i64
68  br label %header
69
70header:                                              ; preds = %latch, %preheader
71  %iv = phi i64 [ 2, %preheader ], [ %add.iv, %latch ]
72  %add.iv = add nuw nsw i64 %iv, 2
73  %cmp1 = icmp ult i64 %add.iv, %trip
74  br i1 %cmp1, label %latch, label %headerexit
75
76latch:                                             ; preds = %header
77  %shft = ashr i64 %add.iv, 1
78  %cmp2 = icmp ult i64 %shft, %trip
79  br i1 %cmp2, label %header, label %latchexit
80
81headerexit:                                              ; preds = %header
82  %addphi = phi i64 [ %add.iv, %header ]
83  br label %mergedexit
84
85latchexit:                                              ; preds = %latch
86  %shftphi = phi i64 [ %shft, %latch ]
87  br label %mergedexit
88
89mergedexit:                                              ; preds = %latchexit, %headerexit
90  %retval = phi i64 [ %addphi, %headerexit ], [ %shftphi, %latchexit ]
91  ret i64 %retval
92}
93
94; mergedexit has edges from loop exit blocks and a block outside the loop.
95define  void @test2(i1 %cond, i32 %n) {
96; CHECK-LABEL: @test2(
97; CHECK-NEXT:  entry:
98; CHECK-NEXT:    br i1 [[COND:%.*]], label [[PREHEADER:%.*]], label [[MERGEDEXIT:%.*]]
99; CHECK:       preheader:
100; CHECK-NEXT:    [[TRIP:%.*]] = zext i32 [[N:%.*]] to i64
101; CHECK-NEXT:    br label [[HEADER:%.*]]
102; CHECK:       header:
103; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 2, [[PREHEADER]] ], [ [[ADD_IV_3:%.*]], [[LATCH_3:%.*]] ]
104; CHECK-NEXT:    [[ADD_IV:%.*]] = add nuw nsw i64 [[IV]], 2
105; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i64 [[ADD_IV]], [[TRIP]]
106; CHECK-NEXT:    br i1 [[CMP1]], label [[LATCH:%.*]], label [[HEADEREXIT:%.*]]
107; CHECK:       latch:
108; CHECK-NEXT:    [[SHFT:%.*]] = ashr i64 [[ADD_IV]], 1
109; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i64 [[SHFT]], [[TRIP]]
110; CHECK-NEXT:    br i1 [[CMP2]], label [[HEADER_1:%.*]], label [[LATCHEXIT:%.*]]
111; CHECK:       header.1:
112; CHECK-NEXT:    [[ADD_IV_1:%.*]] = add nuw nsw i64 [[IV]], 4
113; CHECK-NEXT:    [[CMP1_1:%.*]] = icmp ult i64 [[ADD_IV_1]], [[TRIP]]
114; CHECK-NEXT:    br i1 [[CMP1_1]], label [[LATCH_1:%.*]], label [[HEADEREXIT]]
115; CHECK:       latch.1:
116; CHECK-NEXT:    [[SHFT_1:%.*]] = ashr i64 [[ADD_IV_1]], 1
117; CHECK-NEXT:    [[CMP2_1:%.*]] = icmp ult i64 [[SHFT_1]], [[TRIP]]
118; CHECK-NEXT:    br i1 [[CMP2_1]], label [[HEADER_2:%.*]], label [[LATCHEXIT]]
119; CHECK:       header.2:
120; CHECK-NEXT:    [[ADD_IV_2:%.*]] = add nuw nsw i64 [[IV]], 6
121; CHECK-NEXT:    [[CMP1_2:%.*]] = icmp ult i64 [[ADD_IV_2]], [[TRIP]]
122; CHECK-NEXT:    br i1 [[CMP1_2]], label [[LATCH_2:%.*]], label [[HEADEREXIT]]
123; CHECK:       latch.2:
124; CHECK-NEXT:    [[SHFT_2:%.*]] = ashr i64 [[ADD_IV_2]], 1
125; CHECK-NEXT:    [[CMP2_2:%.*]] = icmp ult i64 [[SHFT_2]], [[TRIP]]
126; CHECK-NEXT:    br i1 [[CMP2_2]], label [[HEADER_3:%.*]], label [[LATCHEXIT]]
127; CHECK:       header.3:
128; CHECK-NEXT:    [[ADD_IV_3]] = add nuw nsw i64 [[IV]], 8
129; CHECK-NEXT:    [[CMP1_3:%.*]] = icmp ult i64 [[ADD_IV_3]], [[TRIP]]
130; CHECK-NEXT:    br i1 [[CMP1_3]], label [[LATCH_3]], label [[HEADEREXIT]]
131; CHECK:       latch.3:
132; CHECK-NEXT:    [[SHFT_3:%.*]] = ashr i64 [[ADD_IV_3]], 1
133; CHECK-NEXT:    [[CMP2_3:%.*]] = icmp ult i64 [[SHFT_3]], [[TRIP]]
134; CHECK-NEXT:    br i1 [[CMP2_3]], label [[HEADER]], label [[LATCHEXIT]], !llvm.loop [[LOOP2:![0-9]+]]
135; CHECK:       headerexit:
136; CHECK-NEXT:    br label [[MERGEDEXIT]]
137; CHECK:       latchexit:
138; CHECK-NEXT:    br label [[MERGEDEXIT]]
139; CHECK:       mergedexit:
140; CHECK-NEXT:    ret void
141;
142entry:
143  br i1 %cond, label %preheader, label %mergedexit
144
145preheader:                                              ; preds = %entry
146  %trip = zext i32 %n to i64
147  br label %header
148
149header:                                              ; preds = %latch, %preheader
150  %iv = phi i64 [ 2, %preheader ], [ %add.iv, %latch ]
151  %add.iv = add nuw nsw i64 %iv, 2
152  %cmp1 = icmp ult i64 %add.iv, %trip
153  br i1 %cmp1, label %latch, label %headerexit
154
155latch:                                             ; preds = %header
156  %shft = ashr i64 %add.iv, 1
157  %cmp2 = icmp ult i64 %shft, %trip
158  br i1 %cmp2, label %header, label %latchexit
159
160headerexit:                                              ; preds = %header
161  br label %mergedexit
162
163latchexit:                                              ; preds = %latch
164  br label %mergedexit
165
166mergedexit:                                              ; preds = %latchexit, %headerexit, %entry
167  ret void
168}
169
170
171; exitsucc is from loop exit block only.
172define i64 @test3(i32 %n) {
173; CHECK-LABEL: @test3(
174; CHECK-NEXT:  entry:
175; CHECK-NEXT:    br label [[PREHEADER:%.*]]
176; CHECK:       preheader:
177; CHECK-NEXT:    [[TRIP:%.*]] = zext i32 [[N:%.*]] to i64
178; CHECK-NEXT:    br label [[HEADER:%.*]]
179; CHECK:       header:
180; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 2, [[PREHEADER]] ], [ [[ADD_IV_3:%.*]], [[LATCH_3:%.*]] ]
181; CHECK-NEXT:    [[ADD_IV:%.*]] = add nuw nsw i64 [[IV]], 2
182; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i64 [[ADD_IV]], [[TRIP]]
183; CHECK-NEXT:    br i1 [[CMP1]], label [[LATCH:%.*]], label [[HEADEREXIT:%.*]]
184; CHECK:       latch:
185; CHECK-NEXT:    [[SHFT:%.*]] = ashr i64 [[ADD_IV]], 1
186; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i64 [[SHFT]], [[TRIP]]
187; CHECK-NEXT:    br i1 [[CMP2]], label [[HEADER_1:%.*]], label [[LATCHEXIT:%.*]]
188; CHECK:       header.1:
189; CHECK-NEXT:    [[ADD_IV_1:%.*]] = add nuw nsw i64 [[IV]], 4
190; CHECK-NEXT:    [[CMP1_1:%.*]] = icmp ult i64 [[ADD_IV_1]], [[TRIP]]
191; CHECK-NEXT:    br i1 [[CMP1_1]], label [[LATCH_1:%.*]], label [[HEADEREXIT]]
192; CHECK:       latch.1:
193; CHECK-NEXT:    [[SHFT_1:%.*]] = ashr i64 [[ADD_IV_1]], 1
194; CHECK-NEXT:    [[CMP2_1:%.*]] = icmp ult i64 [[SHFT_1]], [[TRIP]]
195; CHECK-NEXT:    br i1 [[CMP2_1]], label [[HEADER_2:%.*]], label [[LATCHEXIT]]
196; CHECK:       header.2:
197; CHECK-NEXT:    [[ADD_IV_2:%.*]] = add nuw nsw i64 [[IV]], 6
198; CHECK-NEXT:    [[CMP1_2:%.*]] = icmp ult i64 [[ADD_IV_2]], [[TRIP]]
199; CHECK-NEXT:    br i1 [[CMP1_2]], label [[LATCH_2:%.*]], label [[HEADEREXIT]]
200; CHECK:       latch.2:
201; CHECK-NEXT:    [[SHFT_2:%.*]] = ashr i64 [[ADD_IV_2]], 1
202; CHECK-NEXT:    [[CMP2_2:%.*]] = icmp ult i64 [[SHFT_2]], [[TRIP]]
203; CHECK-NEXT:    br i1 [[CMP2_2]], label [[HEADER_3:%.*]], label [[LATCHEXIT]]
204; CHECK:       header.3:
205; CHECK-NEXT:    [[ADD_IV_3]] = add nuw nsw i64 [[IV]], 8
206; CHECK-NEXT:    [[CMP1_3:%.*]] = icmp ult i64 [[ADD_IV_3]], [[TRIP]]
207; CHECK-NEXT:    br i1 [[CMP1_3]], label [[LATCH_3]], label [[HEADEREXIT]]
208; CHECK:       latch.3:
209; CHECK-NEXT:    [[SHFT_3:%.*]] = ashr i64 [[ADD_IV_3]], 1
210; CHECK-NEXT:    [[CMP2_3:%.*]] = icmp ult i64 [[SHFT_3]], [[TRIP]]
211; CHECK-NEXT:    br i1 [[CMP2_3]], label [[HEADER]], label [[LATCHEXIT]], !llvm.loop [[LOOP3:![0-9]+]]
212; CHECK:       headerexit:
213; CHECK-NEXT:    br label [[EXITSUCC:%.*]]
214; CHECK:       latchexit:
215; CHECK-NEXT:    [[SHFTPHI:%.*]] = phi i64 [ [[SHFT]], [[LATCH]] ], [ [[SHFT_1]], [[LATCH_1]] ], [ [[SHFT_2]], [[LATCH_2]] ], [ [[SHFT_3]], [[LATCH_3]] ]
216; CHECK-NEXT:    ret i64 [[SHFTPHI]]
217; CHECK:       exitsucc:
218; CHECK-NEXT:    ret i64 96
219;
220entry:
221  br label %preheader
222
223preheader:                                              ; preds = %bb
224  %trip = zext i32 %n to i64
225  br label %header
226
227header:                                              ; preds = %latch, %preheader
228  %iv = phi i64 [ 2, %preheader ], [ %add.iv, %latch ]
229  %add.iv = add nuw nsw i64 %iv, 2
230  %cmp1 = icmp ult i64 %add.iv, %trip
231  br i1 %cmp1, label %latch, label %headerexit
232
233latch:                                             ; preds = %header
234  %shft = ashr i64 %add.iv, 1
235  %cmp2 = icmp ult i64 %shft, %trip
236  br i1 %cmp2, label %header, label %latchexit
237
238headerexit:                                              ; preds = %header
239  br label %exitsucc
240
241latchexit:                                              ; preds = %latch
242  %shftphi = phi i64 [ %shft, %latch ]
243  ret i64 %shftphi
244
245exitsucc:                                              ; preds = %headerexit
246  ret i64 96
247}
248
249; exit block (%default) has an exiting block and another exit block as predecessors.
250define void @test4(i16 %c3) {
251; CHECK-LABEL: @test4(
252; CHECK-NEXT:  preheader:
253; CHECK-NEXT:    [[C1:%.*]] = zext i32 undef to i64
254; CHECK-NEXT:    [[UMAX:%.*]] = call i64 @llvm.umax.i64(i64 [[C1]], i64 1)
255; CHECK-NEXT:    [[TMP0:%.*]] = freeze i64 [[UMAX]]
256; CHECK-NEXT:    [[TMP1:%.*]] = add i64 [[TMP0]], -1
257; CHECK-NEXT:    [[XTRAITER:%.*]] = and i64 [[TMP0]], 3
258; CHECK-NEXT:    [[LCMP_MOD:%.*]] = icmp ne i64 [[XTRAITER]], 0
259; CHECK-NEXT:    br i1 [[LCMP_MOD]], label [[HEADER_PROL_PREHEADER:%.*]], label [[HEADER_PROL_LOOPEXIT:%.*]]
260; CHECK:       header.prol.preheader:
261; CHECK-NEXT:    br label [[HEADER_PROL:%.*]]
262; CHECK:       header.prol:
263; CHECK-NEXT:    [[INDVARS_IV_PROL:%.*]] = phi i64 [ 0, [[HEADER_PROL_PREHEADER]] ], [ [[INDVARS_IV_NEXT_PROL:%.*]], [[LATCH_PROL:%.*]] ]
264; CHECK-NEXT:    [[PROL_ITER:%.*]] = phi i64 [ 0, [[HEADER_PROL_PREHEADER]] ], [ [[PROL_ITER_NEXT:%.*]], [[LATCH_PROL]] ]
265; CHECK-NEXT:    br label [[EXITING_PROL:%.*]]
266; CHECK:       exiting.prol:
267; CHECK-NEXT:    switch i16 [[C3:%.*]], label [[DEFAULT_LOOPEXIT_LOOPEXIT1:%.*]] [
268; CHECK-NEXT:    i16 45, label [[OTHEREXIT_LOOPEXIT2:%.*]]
269; CHECK-NEXT:    i16 95, label [[LATCH_PROL]]
270; CHECK-NEXT:    ]
271; CHECK:       latch.prol:
272; CHECK-NEXT:    [[INDVARS_IV_NEXT_PROL]] = add nuw nsw i64 [[INDVARS_IV_PROL]], 1
273; CHECK-NEXT:    [[C2_PROL:%.*]] = icmp ult i64 [[INDVARS_IV_NEXT_PROL]], [[C1]]
274; CHECK-NEXT:    [[PROL_ITER_NEXT]] = add i64 [[PROL_ITER]], 1
275; CHECK-NEXT:    [[PROL_ITER_CMP:%.*]] = icmp ne i64 [[PROL_ITER_NEXT]], [[XTRAITER]]
276; CHECK-NEXT:    br i1 [[PROL_ITER_CMP]], label [[HEADER_PROL]], label [[HEADER_PROL_LOOPEXIT_UNR_LCSSA:%.*]], !llvm.loop [[LOOP4:![0-9]+]]
277; CHECK:       header.prol.loopexit.unr-lcssa:
278; CHECK-NEXT:    [[INDVARS_IV_UNR_PH:%.*]] = phi i64 [ [[INDVARS_IV_NEXT_PROL]], [[LATCH_PROL]] ]
279; CHECK-NEXT:    br label [[HEADER_PROL_LOOPEXIT]]
280; CHECK:       header.prol.loopexit:
281; CHECK-NEXT:    [[INDVARS_IV_UNR:%.*]] = phi i64 [ 0, [[PREHEADER:%.*]] ], [ [[INDVARS_IV_UNR_PH]], [[HEADER_PROL_LOOPEXIT_UNR_LCSSA]] ]
282; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i64 [[TMP1]], 3
283; CHECK-NEXT:    br i1 [[TMP2]], label [[LATCHEXIT:%.*]], label [[PREHEADER_NEW:%.*]]
284; CHECK:       preheader.new:
285; CHECK-NEXT:    br label [[HEADER:%.*]]
286; CHECK:       header:
287; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_UNR]], [[PREHEADER_NEW]] ], [ [[INDVARS_IV_NEXT_3:%.*]], [[LATCH_3:%.*]] ]
288; CHECK-NEXT:    br label [[EXITING:%.*]]
289; CHECK:       exiting:
290; CHECK-NEXT:    switch i16 [[C3]], label [[DEFAULT_LOOPEXIT_LOOPEXIT:%.*]] [
291; CHECK-NEXT:    i16 45, label [[OTHEREXIT_LOOPEXIT:%.*]]
292; CHECK-NEXT:    i16 95, label [[LATCH:%.*]]
293; CHECK-NEXT:    ]
294; CHECK:       latch:
295; CHECK-NEXT:    br label [[EXITING_1:%.*]]
296; CHECK:       exiting.1:
297; CHECK-NEXT:    switch i16 [[C3]], label [[DEFAULT_LOOPEXIT_LOOPEXIT]] [
298; CHECK-NEXT:    i16 45, label [[OTHEREXIT_LOOPEXIT]]
299; CHECK-NEXT:    i16 95, label [[LATCH_1:%.*]]
300; CHECK-NEXT:    ]
301; CHECK:       latch.1:
302; CHECK-NEXT:    br label [[EXITING_2:%.*]]
303; CHECK:       exiting.2:
304; CHECK-NEXT:    switch i16 [[C3]], label [[DEFAULT_LOOPEXIT_LOOPEXIT]] [
305; CHECK-NEXT:    i16 45, label [[OTHEREXIT_LOOPEXIT]]
306; CHECK-NEXT:    i16 95, label [[LATCH_2:%.*]]
307; CHECK-NEXT:    ]
308; CHECK:       latch.2:
309; CHECK-NEXT:    br label [[EXITING_3:%.*]]
310; CHECK:       exiting.3:
311; CHECK-NEXT:    switch i16 [[C3]], label [[DEFAULT_LOOPEXIT_LOOPEXIT]] [
312; CHECK-NEXT:    i16 45, label [[OTHEREXIT_LOOPEXIT]]
313; CHECK-NEXT:    i16 95, label [[LATCH_3]]
314; CHECK-NEXT:    ]
315; CHECK:       latch.3:
316; CHECK-NEXT:    [[INDVARS_IV_NEXT_3]] = add nuw nsw i64 [[INDVARS_IV]], 4
317; CHECK-NEXT:    [[C2_3:%.*]] = icmp ult i64 [[INDVARS_IV_NEXT_3]], [[C1]]
318; CHECK-NEXT:    br i1 [[C2_3]], label [[HEADER]], label [[LATCHEXIT_UNR_LCSSA:%.*]], !llvm.loop [[LOOP5:![0-9]+]]
319; CHECK:       latchexit.unr-lcssa:
320; CHECK-NEXT:    br label [[LATCHEXIT]]
321; CHECK:       latchexit:
322; CHECK-NEXT:    ret void
323; CHECK:       default.loopexit.loopexit:
324; CHECK-NEXT:    br label [[DEFAULT_LOOPEXIT:%.*]]
325; CHECK:       default.loopexit.loopexit1:
326; CHECK-NEXT:    br label [[DEFAULT_LOOPEXIT]]
327; CHECK:       default.loopexit:
328; CHECK-NEXT:    br label [[DEFAULT:%.*]]
329; CHECK:       default:
330; CHECK-NEXT:    ret void
331; CHECK:       otherexit.loopexit:
332; CHECK-NEXT:    br label [[OTHEREXIT:%.*]]
333; CHECK:       otherexit.loopexit2:
334; CHECK-NEXT:    br label [[OTHEREXIT]]
335; CHECK:       otherexit:
336; CHECK-NEXT:    br label [[DEFAULT]]
337;
338preheader:
339  %c1 = zext i32 undef to i64
340  br label %header
341
342header:                                       ; preds = %latch, %preheader
343  %indvars.iv = phi i64 [ 0, %preheader ], [ %indvars.iv.next, %latch ]
344  br label %exiting
345
346exiting:                                           ; preds = %header
347  switch i16 %c3, label %default [
348  i16 45, label %otherexit
349  i16 95, label %latch
350  ]
351
352latch:                                          ; preds = %exiting
353  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
354  %c2 = icmp ult i64 %indvars.iv.next, %c1
355  br i1 %c2, label %header, label %latchexit
356
357latchexit:                                          ; preds = %latch
358  ret void
359
360default:                                          ; preds = %otherexit, %exiting
361  ret void
362
363otherexit:                                           ; preds = %exiting
364  br label %default
365}
366
367; exit block (%exitB) has an exiting block and another exit block as predecessors.
368; exiting block comes from inner loop.
369define void @test5() {
370; CHECK-LABEL: @test5(
371; CHECK-NEXT:  bb:
372; CHECK-NEXT:    [[TMP:%.*]] = icmp sgt i32 undef, 79
373; CHECK-NEXT:    br i1 [[TMP]], label [[OUTERLATCHEXIT:%.*]], label [[BB1:%.*]]
374; CHECK:       bb1:
375; CHECK-NEXT:    [[TMP0:%.*]] = freeze i32 undef
376; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[TMP0]], -1
377; CHECK-NEXT:    [[XTRAITER:%.*]] = and i32 [[TMP0]], 3
378; CHECK-NEXT:    [[LCMP_MOD:%.*]] = icmp ne i32 [[XTRAITER]], 0
379; CHECK-NEXT:    br i1 [[LCMP_MOD]], label [[OUTERH_PROL_PREHEADER:%.*]], label [[OUTERH_PROL_LOOPEXIT:%.*]]
380; CHECK:       outerH.prol.preheader:
381; CHECK-NEXT:    br label [[OUTERH_PROL:%.*]]
382; CHECK:       outerH.prol:
383; CHECK-NEXT:    [[TMP4_PROL:%.*]] = phi i32 [ [[TMP6_PROL:%.*]], [[OUTERLATCH_PROL:%.*]] ], [ undef, [[OUTERH_PROL_PREHEADER]] ]
384; CHECK-NEXT:    [[PROL_ITER:%.*]] = phi i32 [ 0, [[OUTERH_PROL_PREHEADER]] ], [ [[PROL_ITER_NEXT:%.*]], [[OUTERLATCH_PROL]] ]
385; CHECK-NEXT:    br label [[INNERH_PROL:%.*]]
386; CHECK:       innerH.prol:
387; CHECK-NEXT:    [[C1_PROL:%.*]] = call i1 @unknown(i32 0)
388; CHECK-NEXT:    br i1 [[C1_PROL]], label [[INNEREXITING_PROL:%.*]], label [[OTHEREXITB_LOOPEXIT1:%.*]]
389; CHECK:       innerexiting.prol:
390; CHECK-NEXT:    [[C2_PROL:%.*]] = call i1 @unknown(i32 0)
391; CHECK-NEXT:    br i1 [[C2_PROL]], label [[INNERLATCH_PROL:%.*]], label [[EXITB_LOOPEXIT_LOOPEXIT2:%.*]]
392; CHECK:       innerLatch.prol:
393; CHECK-NEXT:    br i1 false, label [[INNERH_1_PROL:%.*]], label [[OUTERLATCH_PROL]]
394; CHECK:       innerH.1.prol:
395; CHECK-NEXT:    [[C1_1_PROL:%.*]] = call i1 @unknown(i32 0)
396; CHECK-NEXT:    br i1 [[C1_1_PROL]], label [[INNEREXITING_1_PROL:%.*]], label [[OTHEREXITB_LOOPEXIT1]]
397; CHECK:       innerexiting.1.prol:
398; CHECK-NEXT:    [[C2_1_PROL:%.*]] = call i1 @unknown(i32 0)
399; CHECK-NEXT:    br i1 [[C2_1_PROL]], label [[INNERLATCH_1_PROL:%.*]], label [[EXITB_LOOPEXIT_LOOPEXIT2]]
400; CHECK:       innerLatch.1.prol:
401; CHECK-NEXT:    br i1 false, label [[INNERH_2_PROL:%.*]], label [[OUTERLATCH_PROL]]
402; CHECK:       innerH.2.prol:
403; CHECK-NEXT:    [[C1_2_PROL:%.*]] = call i1 @unknown(i32 0)
404; CHECK-NEXT:    br i1 [[C1_2_PROL]], label [[INNEREXITING_2_PROL:%.*]], label [[OTHEREXITB_LOOPEXIT1]]
405; CHECK:       innerexiting.2.prol:
406; CHECK-NEXT:    [[C2_2_PROL:%.*]] = call i1 @unknown(i32 0)
407; CHECK-NEXT:    br i1 [[C2_2_PROL]], label [[INNERLATCH_2_PROL:%.*]], label [[EXITB_LOOPEXIT_LOOPEXIT2]]
408; CHECK:       innerLatch.2.prol:
409; CHECK-NEXT:    br i1 false, label [[INNERH_3_PROL:%.*]], label [[OUTERLATCH_PROL]]
410; CHECK:       innerH.3.prol:
411; CHECK-NEXT:    [[C1_3_PROL:%.*]] = call i1 @unknown(i32 0)
412; CHECK-NEXT:    br i1 [[C1_3_PROL]], label [[INNEREXITING_3_PROL:%.*]], label [[OTHEREXITB_LOOPEXIT1]]
413; CHECK:       innerexiting.3.prol:
414; CHECK-NEXT:    [[C2_3_PROL:%.*]] = call i1 @unknown(i32 0)
415; CHECK-NEXT:    br i1 [[C2_3_PROL]], label [[INNERLATCH_3_PROL:%.*]], label [[EXITB_LOOPEXIT_LOOPEXIT2]]
416; CHECK:       innerLatch.3.prol:
417; CHECK-NEXT:    br i1 false, label [[INNERH_PROL]], label [[OUTERLATCH_PROL]], !llvm.loop [[LOOP6:![0-9]+]]
418; CHECK:       outerLatch.prol:
419; CHECK-NEXT:    [[TMP6_PROL]] = add i32 [[TMP4_PROL]], 1
420; CHECK-NEXT:    [[TMP7_PROL:%.*]] = icmp sgt i32 [[TMP6_PROL]], 79
421; CHECK-NEXT:    [[PROL_ITER_NEXT]] = add i32 [[PROL_ITER]], 1
422; CHECK-NEXT:    [[PROL_ITER_CMP:%.*]] = icmp ne i32 [[PROL_ITER_NEXT]], [[XTRAITER]]
423; CHECK-NEXT:    br i1 [[PROL_ITER_CMP]], label [[OUTERH_PROL]], label [[OUTERH_PROL_LOOPEXIT_UNR_LCSSA:%.*]], !llvm.loop [[LOOP7:![0-9]+]]
424; CHECK:       outerH.prol.loopexit.unr-lcssa:
425; CHECK-NEXT:    [[TMP4_UNR_PH:%.*]] = phi i32 [ [[TMP6_PROL]], [[OUTERLATCH_PROL]] ]
426; CHECK-NEXT:    br label [[OUTERH_PROL_LOOPEXIT]]
427; CHECK:       outerH.prol.loopexit:
428; CHECK-NEXT:    [[TMP4_UNR:%.*]] = phi i32 [ undef, [[BB1]] ], [ [[TMP4_UNR_PH]], [[OUTERH_PROL_LOOPEXIT_UNR_LCSSA]] ]
429; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 [[TMP1]], 3
430; CHECK-NEXT:    br i1 [[TMP2]], label [[OUTERLATCHEXIT_LOOPEXIT:%.*]], label [[BB1_NEW:%.*]]
431; CHECK:       bb1.new:
432; CHECK-NEXT:    br label [[OUTERH:%.*]]
433; CHECK:       outerH:
434; CHECK-NEXT:    [[TMP4:%.*]] = phi i32 [ [[TMP4_UNR]], [[BB1_NEW]] ], [ [[TMP6_3:%.*]], [[OUTERLATCH_3:%.*]] ]
435; CHECK-NEXT:    br label [[INNERH:%.*]]
436; CHECK:       innerH:
437; CHECK-NEXT:    [[C1:%.*]] = call i1 @unknown(i32 0)
438; CHECK-NEXT:    br i1 [[C1]], label [[INNEREXITING:%.*]], label [[OTHEREXITB_LOOPEXIT_LOOPEXIT:%.*]]
439; CHECK:       innerexiting:
440; CHECK-NEXT:    [[C2:%.*]] = call i1 @unknown(i32 0)
441; CHECK-NEXT:    br i1 [[C2]], label [[INNERLATCH:%.*]], label [[EXITB_LOOPEXIT_LOOPEXIT_LOOPEXIT:%.*]]
442; CHECK:       innerLatch:
443; CHECK-NEXT:    br i1 false, label [[INNERH_1:%.*]], label [[OUTERLATCH:%.*]]
444; CHECK:       innerH.1:
445; CHECK-NEXT:    [[C1_1:%.*]] = call i1 @unknown(i32 0)
446; CHECK-NEXT:    br i1 [[C1_1]], label [[INNEREXITING_1:%.*]], label [[OTHEREXITB_LOOPEXIT_LOOPEXIT]]
447; CHECK:       innerexiting.1:
448; CHECK-NEXT:    [[C2_1:%.*]] = call i1 @unknown(i32 0)
449; CHECK-NEXT:    br i1 [[C2_1]], label [[INNERLATCH_1:%.*]], label [[EXITB_LOOPEXIT_LOOPEXIT_LOOPEXIT]]
450; CHECK:       innerLatch.1:
451; CHECK-NEXT:    br i1 false, label [[INNERH_2:%.*]], label [[OUTERLATCH]]
452; CHECK:       innerH.2:
453; CHECK-NEXT:    [[C1_2:%.*]] = call i1 @unknown(i32 0)
454; CHECK-NEXT:    br i1 [[C1_2]], label [[INNEREXITING_2:%.*]], label [[OTHEREXITB_LOOPEXIT_LOOPEXIT]]
455; CHECK:       innerexiting.2:
456; CHECK-NEXT:    [[C2_2:%.*]] = call i1 @unknown(i32 0)
457; CHECK-NEXT:    br i1 [[C2_2]], label [[INNERLATCH_2:%.*]], label [[EXITB_LOOPEXIT_LOOPEXIT_LOOPEXIT]]
458; CHECK:       innerLatch.2:
459; CHECK-NEXT:    br i1 false, label [[INNERH_3:%.*]], label [[OUTERLATCH]]
460; CHECK:       innerH.3:
461; CHECK-NEXT:    [[C1_3:%.*]] = call i1 @unknown(i32 0)
462; CHECK-NEXT:    br i1 [[C1_3]], label [[INNEREXITING_3:%.*]], label [[OTHEREXITB_LOOPEXIT_LOOPEXIT]]
463; CHECK:       innerexiting.3:
464; CHECK-NEXT:    [[C2_3:%.*]] = call i1 @unknown(i32 0)
465; CHECK-NEXT:    br i1 [[C2_3]], label [[INNERLATCH_3:%.*]], label [[EXITB_LOOPEXIT_LOOPEXIT_LOOPEXIT]]
466; CHECK:       innerLatch.3:
467; CHECK-NEXT:    br i1 false, label [[INNERH]], label [[OUTERLATCH]], !llvm.loop [[LOOP6]]
468; CHECK:       outerLatch:
469; CHECK-NEXT:    br label [[INNERH_14:%.*]]
470; CHECK:       innerH.14:
471; CHECK-NEXT:    [[C1_13:%.*]] = call i1 @unknown(i32 0)
472; CHECK-NEXT:    br i1 [[C1_13]], label [[INNEREXITING_16:%.*]], label [[OTHEREXITB_LOOPEXIT_LOOPEXIT18:%.*]]
473; CHECK:       innerexiting.16:
474; CHECK-NEXT:    [[C2_15:%.*]] = call i1 @unknown(i32 0)
475; CHECK-NEXT:    br i1 [[C2_15]], label [[INNERLATCH_17:%.*]], label [[EXITB_LOOPEXIT_LOOPEXIT_LOOPEXIT19:%.*]]
476; CHECK:       innerLatch.17:
477; CHECK-NEXT:    br i1 false, label [[INNERH_1_1:%.*]], label [[OUTERLATCH_1:%.*]]
478; CHECK:       innerH.1.1:
479; CHECK-NEXT:    [[C1_1_1:%.*]] = call i1 @unknown(i32 0)
480; CHECK-NEXT:    br i1 [[C1_1_1]], label [[INNEREXITING_1_1:%.*]], label [[OTHEREXITB_LOOPEXIT_LOOPEXIT18]]
481; CHECK:       innerexiting.1.1:
482; CHECK-NEXT:    [[C2_1_1:%.*]] = call i1 @unknown(i32 0)
483; CHECK-NEXT:    br i1 [[C2_1_1]], label [[INNERLATCH_1_1:%.*]], label [[EXITB_LOOPEXIT_LOOPEXIT_LOOPEXIT19]]
484; CHECK:       innerLatch.1.1:
485; CHECK-NEXT:    br i1 false, label [[INNERH_2_1:%.*]], label [[OUTERLATCH_1]]
486; CHECK:       innerH.2.1:
487; CHECK-NEXT:    [[C1_2_1:%.*]] = call i1 @unknown(i32 0)
488; CHECK-NEXT:    br i1 [[C1_2_1]], label [[INNEREXITING_2_1:%.*]], label [[OTHEREXITB_LOOPEXIT_LOOPEXIT18]]
489; CHECK:       innerexiting.2.1:
490; CHECK-NEXT:    [[C2_2_1:%.*]] = call i1 @unknown(i32 0)
491; CHECK-NEXT:    br i1 [[C2_2_1]], label [[INNERLATCH_2_1:%.*]], label [[EXITB_LOOPEXIT_LOOPEXIT_LOOPEXIT19]]
492; CHECK:       innerLatch.2.1:
493; CHECK-NEXT:    br i1 false, label [[INNERH_3_1:%.*]], label [[OUTERLATCH_1]]
494; CHECK:       innerH.3.1:
495; CHECK-NEXT:    [[C1_3_1:%.*]] = call i1 @unknown(i32 0)
496; CHECK-NEXT:    br i1 [[C1_3_1]], label [[INNEREXITING_3_1:%.*]], label [[OTHEREXITB_LOOPEXIT_LOOPEXIT18]]
497; CHECK:       innerexiting.3.1:
498; CHECK-NEXT:    [[C2_3_1:%.*]] = call i1 @unknown(i32 0)
499; CHECK-NEXT:    br i1 [[C2_3_1]], label [[INNERLATCH_3_1:%.*]], label [[EXITB_LOOPEXIT_LOOPEXIT_LOOPEXIT19]]
500; CHECK:       innerLatch.3.1:
501; CHECK-NEXT:    br i1 false, label [[INNERH_14]], label [[OUTERLATCH_1]], !llvm.loop [[LOOP6]]
502; CHECK:       outerLatch.1:
503; CHECK-NEXT:    br label [[INNERH_29:%.*]]
504; CHECK:       innerH.29:
505; CHECK-NEXT:    [[C1_28:%.*]] = call i1 @unknown(i32 0)
506; CHECK-NEXT:    br i1 [[C1_28]], label [[INNEREXITING_211:%.*]], label [[OTHEREXITB_LOOPEXIT_LOOPEXIT20:%.*]]
507; CHECK:       innerexiting.211:
508; CHECK-NEXT:    [[C2_210:%.*]] = call i1 @unknown(i32 0)
509; CHECK-NEXT:    br i1 [[C2_210]], label [[INNERLATCH_212:%.*]], label [[EXITB_LOOPEXIT_LOOPEXIT_LOOPEXIT21:%.*]]
510; CHECK:       innerLatch.212:
511; CHECK-NEXT:    br i1 false, label [[INNERH_1_2:%.*]], label [[OUTERLATCH_2:%.*]]
512; CHECK:       innerH.1.2:
513; CHECK-NEXT:    [[C1_1_2:%.*]] = call i1 @unknown(i32 0)
514; CHECK-NEXT:    br i1 [[C1_1_2]], label [[INNEREXITING_1_2:%.*]], label [[OTHEREXITB_LOOPEXIT_LOOPEXIT20]]
515; CHECK:       innerexiting.1.2:
516; CHECK-NEXT:    [[C2_1_2:%.*]] = call i1 @unknown(i32 0)
517; CHECK-NEXT:    br i1 [[C2_1_2]], label [[INNERLATCH_1_2:%.*]], label [[EXITB_LOOPEXIT_LOOPEXIT_LOOPEXIT21]]
518; CHECK:       innerLatch.1.2:
519; CHECK-NEXT:    br i1 false, label [[INNERH_2_2:%.*]], label [[OUTERLATCH_2]]
520; CHECK:       innerH.2.2:
521; CHECK-NEXT:    [[C1_2_2:%.*]] = call i1 @unknown(i32 0)
522; CHECK-NEXT:    br i1 [[C1_2_2]], label [[INNEREXITING_2_2:%.*]], label [[OTHEREXITB_LOOPEXIT_LOOPEXIT20]]
523; CHECK:       innerexiting.2.2:
524; CHECK-NEXT:    [[C2_2_2:%.*]] = call i1 @unknown(i32 0)
525; CHECK-NEXT:    br i1 [[C2_2_2]], label [[INNERLATCH_2_2:%.*]], label [[EXITB_LOOPEXIT_LOOPEXIT_LOOPEXIT21]]
526; CHECK:       innerLatch.2.2:
527; CHECK-NEXT:    br i1 false, label [[INNERH_3_2:%.*]], label [[OUTERLATCH_2]]
528; CHECK:       innerH.3.2:
529; CHECK-NEXT:    [[C1_3_2:%.*]] = call i1 @unknown(i32 0)
530; CHECK-NEXT:    br i1 [[C1_3_2]], label [[INNEREXITING_3_2:%.*]], label [[OTHEREXITB_LOOPEXIT_LOOPEXIT20]]
531; CHECK:       innerexiting.3.2:
532; CHECK-NEXT:    [[C2_3_2:%.*]] = call i1 @unknown(i32 0)
533; CHECK-NEXT:    br i1 [[C2_3_2]], label [[INNERLATCH_3_2:%.*]], label [[EXITB_LOOPEXIT_LOOPEXIT_LOOPEXIT21]]
534; CHECK:       innerLatch.3.2:
535; CHECK-NEXT:    br i1 false, label [[INNERH_29]], label [[OUTERLATCH_2]], !llvm.loop [[LOOP6]]
536; CHECK:       outerLatch.2:
537; CHECK-NEXT:    br label [[INNERH_314:%.*]]
538; CHECK:       innerH.314:
539; CHECK-NEXT:    [[C1_313:%.*]] = call i1 @unknown(i32 0)
540; CHECK-NEXT:    br i1 [[C1_313]], label [[INNEREXITING_316:%.*]], label [[OTHEREXITB_LOOPEXIT_LOOPEXIT22:%.*]]
541; CHECK:       innerexiting.316:
542; CHECK-NEXT:    [[C2_315:%.*]] = call i1 @unknown(i32 0)
543; CHECK-NEXT:    br i1 [[C2_315]], label [[INNERLATCH_317:%.*]], label [[EXITB_LOOPEXIT_LOOPEXIT_LOOPEXIT23:%.*]]
544; CHECK:       innerLatch.317:
545; CHECK-NEXT:    br i1 false, label [[INNERH_1_3:%.*]], label [[OUTERLATCH_3]]
546; CHECK:       innerH.1.3:
547; CHECK-NEXT:    [[C1_1_3:%.*]] = call i1 @unknown(i32 0)
548; CHECK-NEXT:    br i1 [[C1_1_3]], label [[INNEREXITING_1_3:%.*]], label [[OTHEREXITB_LOOPEXIT_LOOPEXIT22]]
549; CHECK:       innerexiting.1.3:
550; CHECK-NEXT:    [[C2_1_3:%.*]] = call i1 @unknown(i32 0)
551; CHECK-NEXT:    br i1 [[C2_1_3]], label [[INNERLATCH_1_3:%.*]], label [[EXITB_LOOPEXIT_LOOPEXIT_LOOPEXIT23]]
552; CHECK:       innerLatch.1.3:
553; CHECK-NEXT:    br i1 false, label [[INNERH_2_3:%.*]], label [[OUTERLATCH_3]]
554; CHECK:       innerH.2.3:
555; CHECK-NEXT:    [[C1_2_3:%.*]] = call i1 @unknown(i32 0)
556; CHECK-NEXT:    br i1 [[C1_2_3]], label [[INNEREXITING_2_3:%.*]], label [[OTHEREXITB_LOOPEXIT_LOOPEXIT22]]
557; CHECK:       innerexiting.2.3:
558; CHECK-NEXT:    [[C2_2_3:%.*]] = call i1 @unknown(i32 0)
559; CHECK-NEXT:    br i1 [[C2_2_3]], label [[INNERLATCH_2_3:%.*]], label [[EXITB_LOOPEXIT_LOOPEXIT_LOOPEXIT23]]
560; CHECK:       innerLatch.2.3:
561; CHECK-NEXT:    br i1 false, label [[INNERH_3_3:%.*]], label [[OUTERLATCH_3]]
562; CHECK:       innerH.3.3:
563; CHECK-NEXT:    [[C1_3_3:%.*]] = call i1 @unknown(i32 0)
564; CHECK-NEXT:    br i1 [[C1_3_3]], label [[INNEREXITING_3_3:%.*]], label [[OTHEREXITB_LOOPEXIT_LOOPEXIT22]]
565; CHECK:       innerexiting.3.3:
566; CHECK-NEXT:    [[C2_3_3:%.*]] = call i1 @unknown(i32 0)
567; CHECK-NEXT:    br i1 [[C2_3_3]], label [[INNERLATCH_3_3:%.*]], label [[EXITB_LOOPEXIT_LOOPEXIT_LOOPEXIT23]]
568; CHECK:       innerLatch.3.3:
569; CHECK-NEXT:    br i1 false, label [[INNERH_314]], label [[OUTERLATCH_3]], !llvm.loop [[LOOP6]]
570; CHECK:       outerLatch.3:
571; CHECK-NEXT:    [[TMP6_3]] = add i32 [[TMP4]], 4
572; CHECK-NEXT:    [[TMP7_3:%.*]] = icmp sgt i32 [[TMP6_3]], 79
573; CHECK-NEXT:    br i1 [[TMP7_3]], label [[OUTERLATCHEXIT_LOOPEXIT_UNR_LCSSA:%.*]], label [[OUTERH]], !llvm.loop [[LOOP8:![0-9]+]]
574; CHECK:       outerLatchExit.loopexit.unr-lcssa:
575; CHECK-NEXT:    br label [[OUTERLATCHEXIT_LOOPEXIT]]
576; CHECK:       outerLatchExit.loopexit:
577; CHECK-NEXT:    br label [[OUTERLATCHEXIT]]
578; CHECK:       outerLatchExit:
579; CHECK-NEXT:    ret void
580; CHECK:       exitB.loopexit.loopexit.loopexit:
581; CHECK-NEXT:    br label [[EXITB_LOOPEXIT_LOOPEXIT:%.*]]
582; CHECK:       exitB.loopexit.loopexit.loopexit19:
583; CHECK-NEXT:    br label [[EXITB_LOOPEXIT_LOOPEXIT]]
584; CHECK:       exitB.loopexit.loopexit.loopexit21:
585; CHECK-NEXT:    br label [[EXITB_LOOPEXIT_LOOPEXIT]]
586; CHECK:       exitB.loopexit.loopexit.loopexit23:
587; CHECK-NEXT:    br label [[EXITB_LOOPEXIT_LOOPEXIT]]
588; CHECK:       exitB.loopexit.loopexit:
589; CHECK-NEXT:    br label [[EXITB_LOOPEXIT:%.*]]
590; CHECK:       exitB.loopexit.loopexit2:
591; CHECK-NEXT:    br label [[EXITB_LOOPEXIT]]
592; CHECK:       exitB.loopexit:
593; CHECK-NEXT:    br label [[EXITB:%.*]]
594; CHECK:       exitB:
595; CHECK-NEXT:    ret void
596; CHECK:       otherexitB.loopexit.loopexit:
597; CHECK-NEXT:    br label [[OTHEREXITB_LOOPEXIT:%.*]]
598; CHECK:       otherexitB.loopexit.loopexit18:
599; CHECK-NEXT:    br label [[OTHEREXITB_LOOPEXIT]]
600; CHECK:       otherexitB.loopexit.loopexit20:
601; CHECK-NEXT:    br label [[OTHEREXITB_LOOPEXIT]]
602; CHECK:       otherexitB.loopexit.loopexit22:
603; CHECK-NEXT:    br label [[OTHEREXITB_LOOPEXIT]]
604; CHECK:       otherexitB.loopexit:
605; CHECK-NEXT:    br label [[OTHEREXITB:%.*]]
606; CHECK:       otherexitB.loopexit1:
607; CHECK-NEXT:    br label [[OTHEREXITB]]
608; CHECK:       otherexitB:
609; CHECK-NEXT:    br label [[EXITB]]
610;
611bb:
612  %tmp = icmp sgt i32 undef, 79
613  br i1 %tmp, label %outerLatchExit, label %bb1
614
615bb1:                                              ; preds = %bb
616  br label %outerH
617
618outerH:                                              ; preds = %outerLatch, %bb1
619  %tmp4 = phi i32 [ %tmp6, %outerLatch ], [ undef, %bb1 ]
620  br label %innerH
621
622innerH:                                              ; preds = %innerLatch, %outerH
623  %c1 = call i1 @unknown(i32 0)
624  br i1 %c1, label %innerexiting, label %otherexitB
625
626innerexiting:                                             ; preds = %innerH
627  %c2 = call i1 @unknown(i32 0)
628  br i1 %c2, label %innerLatch, label %exitB
629
630innerLatch:                                             ; preds = %innerexiting
631  %tmp13 = fcmp olt double undef, 2.000000e+00
632  br i1 %tmp13, label %innerH, label %outerLatch
633
634outerLatch:                                              ; preds = %innerLatch
635  %tmp6 = add i32 %tmp4, 1
636  %tmp7 = icmp sgt i32 %tmp6, 79
637  br i1 %tmp7, label %outerLatchExit, label %outerH
638
639outerLatchExit:                                              ; preds = %outerLatch, %bb
640  ret void
641
642exitB:                                             ; preds = %innerexiting, %otherexitB
643  ret void
644
645otherexitB:                                              ; preds = %innerH
646  br label %exitB
647
648}
649
650; Blocks reachable from exits (not_zero44) have the IDom as the block within the loop (Header).
651; Update the IDom to the preheader.
652define void @test6(i64 %start) {
653; CHECK-LABEL: @test6(
654; CHECK-NEXT:  entry:
655; CHECK-NEXT:    [[TMP0:%.*]] = add i64 [[START:%.*]], 2
656; CHECK-NEXT:    [[SMAX:%.*]] = call i64 @llvm.smax.i64(i64 [[TMP0]], i64 616)
657; CHECK-NEXT:    [[TMP1:%.*]] = add i64 [[SMAX]], -1
658; CHECK-NEXT:    [[TMP2:%.*]] = sub i64 [[TMP1]], [[START]]
659; CHECK-NEXT:    [[TMP3:%.*]] = lshr i64 [[TMP2]], 1
660; CHECK-NEXT:    [[TMP4:%.*]] = add nuw i64 [[TMP3]], 1
661; CHECK-NEXT:    [[TMP5:%.*]] = freeze i64 [[TMP4]]
662; CHECK-NEXT:    [[TMP6:%.*]] = add i64 [[TMP5]], -1
663; CHECK-NEXT:    [[XTRAITER:%.*]] = and i64 [[TMP5]], 3
664; CHECK-NEXT:    [[LCMP_MOD:%.*]] = icmp ne i64 [[XTRAITER]], 0
665; CHECK-NEXT:    br i1 [[LCMP_MOD]], label [[HEADER_PROL_PREHEADER:%.*]], label [[HEADER_PROL_LOOPEXIT:%.*]]
666; CHECK:       header.prol.preheader:
667; CHECK-NEXT:    br label [[HEADER_PROL:%.*]]
668; CHECK:       header.prol:
669; CHECK-NEXT:    [[INDVARS_IV_PROL:%.*]] = phi i64 [ [[START]], [[HEADER_PROL_PREHEADER]] ], [ [[INDVARS_IV_NEXT_PROL:%.*]], [[LATCH_PROL:%.*]] ]
670; CHECK-NEXT:    [[PROL_ITER:%.*]] = phi i64 [ 0, [[HEADER_PROL_PREHEADER]] ], [ [[PROL_ITER_NEXT:%.*]], [[LATCH_PROL]] ]
671; CHECK-NEXT:    [[IV_I32_PROL:%.*]] = trunc i64 [[INDVARS_IV_PROL]] to i32
672; CHECK-NEXT:    [[C1_PROL:%.*]] = call i1 @unknown(i32 [[IV_I32_PROL]])
673; CHECK-NEXT:    br i1 [[C1_PROL]], label [[LATCH_PROL]], label [[OTHEREXIT_LOOPEXIT1:%.*]]
674; CHECK:       latch.prol:
675; CHECK-NEXT:    [[INDVARS_IV_NEXT_PROL]] = add nsw i64 [[INDVARS_IV_PROL]], 2
676; CHECK-NEXT:    [[TMP7:%.*]] = icmp slt i64 [[INDVARS_IV_NEXT_PROL]], 616
677; CHECK-NEXT:    [[PROL_ITER_NEXT]] = add i64 [[PROL_ITER]], 1
678; CHECK-NEXT:    [[PROL_ITER_CMP:%.*]] = icmp ne i64 [[PROL_ITER_NEXT]], [[XTRAITER]]
679; CHECK-NEXT:    br i1 [[PROL_ITER_CMP]], label [[HEADER_PROL]], label [[HEADER_PROL_LOOPEXIT_UNR_LCSSA:%.*]], !llvm.loop [[LOOP9:![0-9]+]]
680; CHECK:       header.prol.loopexit.unr-lcssa:
681; CHECK-NEXT:    [[INDVARS_IV_UNR_PH:%.*]] = phi i64 [ [[INDVARS_IV_NEXT_PROL]], [[LATCH_PROL]] ]
682; CHECK-NEXT:    br label [[HEADER_PROL_LOOPEXIT]]
683; CHECK:       header.prol.loopexit:
684; CHECK-NEXT:    [[INDVARS_IV_UNR:%.*]] = phi i64 [ [[START]], [[ENTRY:%.*]] ], [ [[INDVARS_IV_UNR_PH]], [[HEADER_PROL_LOOPEXIT_UNR_LCSSA]] ]
685; CHECK-NEXT:    [[TMP8:%.*]] = icmp ult i64 [[TMP6]], 3
686; CHECK-NEXT:    br i1 [[TMP8]], label [[LATCHEXIT:%.*]], label [[ENTRY_NEW:%.*]]
687; CHECK:       entry.new:
688; CHECK-NEXT:    br label [[HEADER:%.*]]
689; CHECK:       header:
690; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_UNR]], [[ENTRY_NEW]] ], [ [[INDVARS_IV_NEXT_3:%.*]], [[LATCH_3:%.*]] ]
691; CHECK-NEXT:    [[IV_I32:%.*]] = trunc i64 [[INDVARS_IV]] to i32
692; CHECK-NEXT:    [[C1:%.*]] = call i1 @unknown(i32 [[IV_I32]])
693; CHECK-NEXT:    br i1 [[C1]], label [[LATCH:%.*]], label [[OTHEREXIT_LOOPEXIT:%.*]]
694; CHECK:       latch:
695; CHECK-NEXT:    [[INDVARS_IV_NEXT:%.*]] = add nsw i64 [[INDVARS_IV]], 2
696; CHECK-NEXT:    [[IV_I32_1:%.*]] = trunc i64 [[INDVARS_IV_NEXT]] to i32
697; CHECK-NEXT:    [[C1_1:%.*]] = call i1 @unknown(i32 [[IV_I32_1]])
698; CHECK-NEXT:    br i1 [[C1_1]], label [[LATCH_1:%.*]], label [[OTHEREXIT_LOOPEXIT]]
699; CHECK:       latch.1:
700; CHECK-NEXT:    [[INDVARS_IV_NEXT_1:%.*]] = add nsw i64 [[INDVARS_IV]], 4
701; CHECK-NEXT:    [[IV_I32_2:%.*]] = trunc i64 [[INDVARS_IV_NEXT_1]] to i32
702; CHECK-NEXT:    [[C1_2:%.*]] = call i1 @unknown(i32 [[IV_I32_2]])
703; CHECK-NEXT:    br i1 [[C1_2]], label [[LATCH_2:%.*]], label [[OTHEREXIT_LOOPEXIT]]
704; CHECK:       latch.2:
705; CHECK-NEXT:    [[INDVARS_IV_NEXT_2:%.*]] = add nsw i64 [[INDVARS_IV]], 6
706; CHECK-NEXT:    [[IV_I32_3:%.*]] = trunc i64 [[INDVARS_IV_NEXT_2]] to i32
707; CHECK-NEXT:    [[C1_3:%.*]] = call i1 @unknown(i32 [[IV_I32_3]])
708; CHECK-NEXT:    br i1 [[C1_3]], label [[LATCH_3]], label [[OTHEREXIT_LOOPEXIT]]
709; CHECK:       latch.3:
710; CHECK-NEXT:    [[INDVARS_IV_NEXT_3]] = add nsw i64 [[INDVARS_IV]], 8
711; CHECK-NEXT:    [[TMP9:%.*]] = icmp slt i64 [[INDVARS_IV_NEXT_3]], 616
712; CHECK-NEXT:    br i1 [[TMP9]], label [[HEADER]], label [[LATCHEXIT_UNR_LCSSA:%.*]], !llvm.loop [[LOOP10:![0-9]+]]
713; CHECK:       latchexit.unr-lcssa:
714; CHECK-NEXT:    br label [[LATCHEXIT]]
715; CHECK:       latchexit:
716; CHECK-NEXT:    br label [[LATCHEXITSUCC:%.*]]
717; CHECK:       otherexit.loopexit:
718; CHECK-NEXT:    br label [[OTHEREXIT:%.*]]
719; CHECK:       otherexit.loopexit1:
720; CHECK-NEXT:    br label [[OTHEREXIT]]
721; CHECK:       otherexit:
722; CHECK-NEXT:    br label [[OTHEREXITSUCC:%.*]]
723; CHECK:       otherexitsucc:
724; CHECK-NEXT:    br label [[NOT_ZERO44:%.*]]
725; CHECK:       not_zero44:
726; CHECK-NEXT:    unreachable
727; CHECK:       latchexitsucc:
728; CHECK-NEXT:    br label [[NOT_ZERO44]]
729;
730entry:
731  br label %header
732
733header:                                          ; preds = %latch, %entry
734  %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %latch ]
735  %iv.i32 = trunc i64 %indvars.iv to i32
736  %c1 = call i1 @unknown(i32 %iv.i32)
737  br i1 %c1, label %latch, label %otherexit
738
739latch:                                         ; preds = %header
740  %indvars.iv.next = add nsw i64 %indvars.iv, 2
741  %0 = icmp slt i64 %indvars.iv.next, 616
742  br i1 %0, label %header, label %latchexit
743
744latchexit:                                          ; preds = %latch
745  br label %latchexitsucc
746
747otherexit:                                 ; preds = %header
748  br label %otherexitsucc
749
750otherexitsucc:                                          ; preds = %otherexit
751  br label %not_zero44
752
753not_zero44:                                       ; preds = %latchexitsucc, %otherexitsucc
754  unreachable
755
756latchexitsucc:                                      ; preds = %latchexit
757  br label %not_zero44
758}
759
760