1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -unroll-runtime-other-exit-predictable=false -loop-unroll -unroll-runtime=true -verify-dom-info -verify-loop-info -instcombine -S | FileCheck %s
3; RUN: opt < %s -unroll-runtime-other-exit-predictable=false -loop-unroll -unroll-runtime=true -verify-dom-info -unroll-runtime-multi-exit=false -verify-loop-info -S | FileCheck %s -check-prefix=NOUNROLL
4; RUN: opt < %s -unroll-runtime-other-exit-predictable=false -loop-unroll -unroll-runtime=true -verify-dom-info -unroll-runtime-multi-exit=true -verify-loop-info -S | FileCheck %s -check-prefix=ENABLED
5
6; The purpose of these tests is to exercise the heuristics which decide whether
7; to unroll multiple exit loops - specifically, the multiple exit reasoning.
8; Currently, we have heuristics both at the pass level, and controlled by a
9; flag in the implementation, so we need to test all three states of the flag
10; to cover all the logic completely.  Note that the unroll factor is not
11; manually specified in these tests - see runtime-loop-multiple-exits.ll for
12; functional tests with forced unroll factors.
13
14; the second exit block is a deopt block. The loop has one exiting block other than the latch.
15define i32 @test1(i32* nocapture %a, i64 %n) {
16; CHECK-LABEL: @test1(
17; CHECK-NEXT:  entry:
18; CHECK-NEXT:    [[TMP0:%.*]] = freeze i64 [[N:%.*]]
19; CHECK-NEXT:    [[TMP1:%.*]] = add i64 [[TMP0]], -1
20; CHECK-NEXT:    [[XTRAITER:%.*]] = and i64 [[TMP0]], 7
21; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i64 [[TMP1]], 7
22; CHECK-NEXT:    br i1 [[TMP2]], label [[LATCHEXIT_UNR_LCSSA:%.*]], label [[ENTRY_NEW:%.*]]
23; CHECK:       entry.new:
24; CHECK-NEXT:    [[UNROLL_ITER:%.*]] = and i64 [[TMP0]], -8
25; CHECK-NEXT:    br label [[HEADER:%.*]]
26; CHECK:       header:
27; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY_NEW]] ], [ [[INDVARS_IV_NEXT_7:%.*]], [[LATCH_7:%.*]] ]
28; CHECK-NEXT:    [[SUM_02:%.*]] = phi i32 [ 0, [[ENTRY_NEW]] ], [ [[ADD_7:%.*]], [[LATCH_7]] ]
29; CHECK-NEXT:    [[NITER:%.*]] = phi i64 [ 0, [[ENTRY_NEW]] ], [ [[NITER_NEXT_7:%.*]], [[LATCH_7]] ]
30; CHECK-NEXT:    br label [[FOR_EXITING_BLOCK:%.*]]
31; CHECK:       for.exiting_block:
32; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i64 [[TMP0]], 42
33; CHECK-NEXT:    br i1 [[CMP]], label [[OTHEREXIT_LOOPEXIT:%.*]], label [[LATCH:%.*]]
34; CHECK:       latch:
35; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i64 [[INDVARS_IV]]
36; CHECK-NEXT:    [[TMP3:%.*]] = load i32, i32* [[ARRAYIDX]], align 4
37; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[TMP3]], [[SUM_02]]
38; CHECK-NEXT:    [[INDVARS_IV_NEXT:%.*]] = or i64 [[INDVARS_IV]], 1
39; CHECK-NEXT:    br label [[FOR_EXITING_BLOCK_1:%.*]]
40; CHECK:       for.exiting_block.1:
41; CHECK-NEXT:    [[CMP_1:%.*]] = icmp eq i64 [[TMP0]], 42
42; CHECK-NEXT:    br i1 [[CMP_1]], label [[OTHEREXIT_LOOPEXIT]], label [[LATCH_1:%.*]]
43; CHECK:       latch.1:
44; CHECK-NEXT:    [[ARRAYIDX_1:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT]]
45; CHECK-NEXT:    [[TMP4:%.*]] = load i32, i32* [[ARRAYIDX_1]], align 4
46; CHECK-NEXT:    [[ADD_1:%.*]] = add nsw i32 [[TMP4]], [[ADD]]
47; CHECK-NEXT:    [[INDVARS_IV_NEXT_1:%.*]] = or i64 [[INDVARS_IV]], 2
48; CHECK-NEXT:    br label [[FOR_EXITING_BLOCK_2:%.*]]
49; CHECK:       for.exiting_block.2:
50; CHECK-NEXT:    [[CMP_2:%.*]] = icmp eq i64 [[TMP0]], 42
51; CHECK-NEXT:    br i1 [[CMP_2]], label [[OTHEREXIT_LOOPEXIT]], label [[LATCH_2:%.*]]
52; CHECK:       latch.2:
53; CHECK-NEXT:    [[ARRAYIDX_2:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT_1]]
54; CHECK-NEXT:    [[TMP5:%.*]] = load i32, i32* [[ARRAYIDX_2]], align 4
55; CHECK-NEXT:    [[ADD_2:%.*]] = add nsw i32 [[TMP5]], [[ADD_1]]
56; CHECK-NEXT:    [[INDVARS_IV_NEXT_2:%.*]] = or i64 [[INDVARS_IV]], 3
57; CHECK-NEXT:    br label [[FOR_EXITING_BLOCK_3:%.*]]
58; CHECK:       for.exiting_block.3:
59; CHECK-NEXT:    [[CMP_3:%.*]] = icmp eq i64 [[TMP0]], 42
60; CHECK-NEXT:    br i1 [[CMP_3]], label [[OTHEREXIT_LOOPEXIT]], label [[LATCH_3:%.*]]
61; CHECK:       latch.3:
62; CHECK-NEXT:    [[ARRAYIDX_3:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT_2]]
63; CHECK-NEXT:    [[TMP6:%.*]] = load i32, i32* [[ARRAYIDX_3]], align 4
64; CHECK-NEXT:    [[ADD_3:%.*]] = add nsw i32 [[TMP6]], [[ADD_2]]
65; CHECK-NEXT:    [[INDVARS_IV_NEXT_3:%.*]] = or i64 [[INDVARS_IV]], 4
66; CHECK-NEXT:    br label [[FOR_EXITING_BLOCK_4:%.*]]
67; CHECK:       for.exiting_block.4:
68; CHECK-NEXT:    [[CMP_4:%.*]] = icmp eq i64 [[TMP0]], 42
69; CHECK-NEXT:    br i1 [[CMP_4]], label [[OTHEREXIT_LOOPEXIT]], label [[LATCH_4:%.*]]
70; CHECK:       latch.4:
71; CHECK-NEXT:    [[ARRAYIDX_4:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT_3]]
72; CHECK-NEXT:    [[TMP7:%.*]] = load i32, i32* [[ARRAYIDX_4]], align 4
73; CHECK-NEXT:    [[ADD_4:%.*]] = add nsw i32 [[TMP7]], [[ADD_3]]
74; CHECK-NEXT:    [[INDVARS_IV_NEXT_4:%.*]] = or i64 [[INDVARS_IV]], 5
75; CHECK-NEXT:    br label [[FOR_EXITING_BLOCK_5:%.*]]
76; CHECK:       for.exiting_block.5:
77; CHECK-NEXT:    [[CMP_5:%.*]] = icmp eq i64 [[TMP0]], 42
78; CHECK-NEXT:    br i1 [[CMP_5]], label [[OTHEREXIT_LOOPEXIT]], label [[LATCH_5:%.*]]
79; CHECK:       latch.5:
80; CHECK-NEXT:    [[ARRAYIDX_5:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT_4]]
81; CHECK-NEXT:    [[TMP8:%.*]] = load i32, i32* [[ARRAYIDX_5]], align 4
82; CHECK-NEXT:    [[ADD_5:%.*]] = add nsw i32 [[TMP8]], [[ADD_4]]
83; CHECK-NEXT:    [[INDVARS_IV_NEXT_5:%.*]] = or i64 [[INDVARS_IV]], 6
84; CHECK-NEXT:    br label [[FOR_EXITING_BLOCK_6:%.*]]
85; CHECK:       for.exiting_block.6:
86; CHECK-NEXT:    [[CMP_6:%.*]] = icmp eq i64 [[TMP0]], 42
87; CHECK-NEXT:    br i1 [[CMP_6]], label [[OTHEREXIT_LOOPEXIT]], label [[LATCH_6:%.*]]
88; CHECK:       latch.6:
89; CHECK-NEXT:    [[ARRAYIDX_6:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT_5]]
90; CHECK-NEXT:    [[TMP9:%.*]] = load i32, i32* [[ARRAYIDX_6]], align 4
91; CHECK-NEXT:    [[ADD_6:%.*]] = add nsw i32 [[TMP9]], [[ADD_5]]
92; CHECK-NEXT:    [[INDVARS_IV_NEXT_6:%.*]] = or i64 [[INDVARS_IV]], 7
93; CHECK-NEXT:    br label [[FOR_EXITING_BLOCK_7:%.*]]
94; CHECK:       for.exiting_block.7:
95; CHECK-NEXT:    [[CMP_7:%.*]] = icmp eq i64 [[TMP0]], 42
96; CHECK-NEXT:    br i1 [[CMP_7]], label [[OTHEREXIT_LOOPEXIT]], label [[LATCH_7]]
97; CHECK:       latch.7:
98; CHECK-NEXT:    [[ARRAYIDX_7:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT_6]]
99; CHECK-NEXT:    [[TMP10:%.*]] = load i32, i32* [[ARRAYIDX_7]], align 4
100; CHECK-NEXT:    [[ADD_7]] = add nsw i32 [[TMP10]], [[ADD_6]]
101; CHECK-NEXT:    [[INDVARS_IV_NEXT_7]] = add i64 [[INDVARS_IV]], 8
102; CHECK-NEXT:    [[NITER_NEXT_7]] = add i64 [[NITER]], 8
103; CHECK-NEXT:    [[NITER_NCMP_7:%.*]] = icmp eq i64 [[NITER_NEXT_7]], [[UNROLL_ITER]]
104; CHECK-NEXT:    br i1 [[NITER_NCMP_7]], label [[LATCHEXIT_UNR_LCSSA_LOOPEXIT:%.*]], label [[HEADER]]
105; CHECK:       latchexit.unr-lcssa.loopexit:
106; CHECK-NEXT:    br label [[LATCHEXIT_UNR_LCSSA]]
107; CHECK:       latchexit.unr-lcssa:
108; CHECK-NEXT:    [[SUM_0_LCSSA_PH:%.*]] = phi i32 [ undef, [[ENTRY:%.*]] ], [ [[ADD_7]], [[LATCHEXIT_UNR_LCSSA_LOOPEXIT]] ]
109; CHECK-NEXT:    [[INDVARS_IV_UNR:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[INDVARS_IV_NEXT_7]], [[LATCHEXIT_UNR_LCSSA_LOOPEXIT]] ]
110; CHECK-NEXT:    [[SUM_02_UNR:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD_7]], [[LATCHEXIT_UNR_LCSSA_LOOPEXIT]] ]
111; CHECK-NEXT:    [[LCMP_MOD_NOT:%.*]] = icmp eq i64 [[XTRAITER]], 0
112; CHECK-NEXT:    br i1 [[LCMP_MOD_NOT]], label [[LATCHEXIT:%.*]], label [[HEADER_EPIL_PREHEADER:%.*]]
113; CHECK:       header.epil.preheader:
114; CHECK-NEXT:    br label [[HEADER_EPIL:%.*]]
115; CHECK:       header.epil:
116; CHECK-NEXT:    [[INDVARS_IV_EPIL:%.*]] = phi i64 [ [[INDVARS_IV_NEXT_EPIL:%.*]], [[LATCH_EPIL:%.*]] ], [ [[INDVARS_IV_UNR]], [[HEADER_EPIL_PREHEADER]] ]
117; CHECK-NEXT:    [[SUM_02_EPIL:%.*]] = phi i32 [ [[ADD_EPIL:%.*]], [[LATCH_EPIL]] ], [ [[SUM_02_UNR]], [[HEADER_EPIL_PREHEADER]] ]
118; CHECK-NEXT:    [[EPIL_ITER:%.*]] = phi i64 [ [[EPIL_ITER_NEXT:%.*]], [[LATCH_EPIL]] ], [ 0, [[HEADER_EPIL_PREHEADER]] ]
119; CHECK-NEXT:    br label [[FOR_EXITING_BLOCK_EPIL:%.*]]
120; CHECK:       for.exiting_block.epil:
121; CHECK-NEXT:    [[CMP_EPIL:%.*]] = icmp eq i64 [[TMP0]], 42
122; CHECK-NEXT:    br i1 [[CMP_EPIL]], label [[OTHEREXIT_LOOPEXIT3:%.*]], label [[LATCH_EPIL]]
123; CHECK:       latch.epil:
124; CHECK-NEXT:    [[ARRAYIDX_EPIL:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_EPIL]]
125; CHECK-NEXT:    [[TMP11:%.*]] = load i32, i32* [[ARRAYIDX_EPIL]], align 4
126; CHECK-NEXT:    [[ADD_EPIL]] = add nsw i32 [[TMP11]], [[SUM_02_EPIL]]
127; CHECK-NEXT:    [[INDVARS_IV_NEXT_EPIL]] = add i64 [[INDVARS_IV_EPIL]], 1
128; CHECK-NEXT:    [[EPIL_ITER_NEXT]] = add i64 [[EPIL_ITER]], 1
129; CHECK-NEXT:    [[EPIL_ITER_CMP_NOT:%.*]] = icmp eq i64 [[EPIL_ITER_NEXT]], [[XTRAITER]]
130; CHECK-NEXT:    br i1 [[EPIL_ITER_CMP_NOT]], label [[LATCHEXIT_EPILOG_LCSSA:%.*]], label [[HEADER_EPIL]], !llvm.loop [[LOOP0:![0-9]+]]
131; CHECK:       latchexit.epilog-lcssa:
132; CHECK-NEXT:    br label [[LATCHEXIT]]
133; CHECK:       latchexit:
134; CHECK-NEXT:    [[SUM_0_LCSSA:%.*]] = phi i32 [ [[SUM_0_LCSSA_PH]], [[LATCHEXIT_UNR_LCSSA]] ], [ [[ADD_EPIL]], [[LATCHEXIT_EPILOG_LCSSA]] ]
135; CHECK-NEXT:    ret i32 [[SUM_0_LCSSA]]
136; CHECK:       otherexit.loopexit:
137; CHECK-NEXT:    [[SUM_02_LCSSA_PH:%.*]] = phi i32 [ [[SUM_02]], [[FOR_EXITING_BLOCK]] ], [ [[ADD]], [[FOR_EXITING_BLOCK_1]] ], [ [[ADD_1]], [[FOR_EXITING_BLOCK_2]] ], [ [[ADD_2]], [[FOR_EXITING_BLOCK_3]] ], [ [[ADD_3]], [[FOR_EXITING_BLOCK_4]] ], [ [[ADD_4]], [[FOR_EXITING_BLOCK_5]] ], [ [[ADD_5]], [[FOR_EXITING_BLOCK_6]] ], [ [[ADD_6]], [[FOR_EXITING_BLOCK_7]] ]
138; CHECK-NEXT:    br label [[OTHEREXIT:%.*]]
139; CHECK:       otherexit.loopexit3:
140; CHECK-NEXT:    br label [[OTHEREXIT]]
141; CHECK:       otherexit:
142; CHECK-NEXT:    [[SUM_02_LCSSA:%.*]] = phi i32 [ [[SUM_02_LCSSA_PH]], [[OTHEREXIT_LOOPEXIT]] ], [ [[SUM_02_EPIL]], [[OTHEREXIT_LOOPEXIT3]] ]
143; CHECK-NEXT:    [[RVAL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"(i32 [[SUM_02_LCSSA]]) ]
144; CHECK-NEXT:    ret i32 [[RVAL]]
145;
146; NOUNROLL-LABEL: @test1(
147; NOUNROLL-NEXT:  entry:
148; NOUNROLL-NEXT:    br label [[HEADER:%.*]]
149; NOUNROLL:       header:
150; NOUNROLL-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LATCH:%.*]] ], [ 0, [[ENTRY:%.*]] ]
151; NOUNROLL-NEXT:    [[SUM_02:%.*]] = phi i32 [ [[ADD:%.*]], [[LATCH]] ], [ 0, [[ENTRY]] ]
152; NOUNROLL-NEXT:    br label [[FOR_EXITING_BLOCK:%.*]]
153; NOUNROLL:       for.exiting_block:
154; NOUNROLL-NEXT:    [[CMP:%.*]] = icmp eq i64 [[N:%.*]], 42
155; NOUNROLL-NEXT:    br i1 [[CMP]], label [[OTHEREXIT:%.*]], label [[LATCH]]
156; NOUNROLL:       latch:
157; NOUNROLL-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i64 [[INDVARS_IV]]
158; NOUNROLL-NEXT:    [[TMP0:%.*]] = load i32, i32* [[ARRAYIDX]], align 4
159; NOUNROLL-NEXT:    [[ADD]] = add nsw i32 [[TMP0]], [[SUM_02]]
160; NOUNROLL-NEXT:    [[INDVARS_IV_NEXT]] = add i64 [[INDVARS_IV]], 1
161; NOUNROLL-NEXT:    [[EXITCOND:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], [[N]]
162; NOUNROLL-NEXT:    br i1 [[EXITCOND]], label [[LATCHEXIT:%.*]], label [[HEADER]]
163; NOUNROLL:       latchexit:
164; NOUNROLL-NEXT:    [[SUM_0_LCSSA:%.*]] = phi i32 [ [[ADD]], [[LATCH]] ]
165; NOUNROLL-NEXT:    ret i32 [[SUM_0_LCSSA]]
166; NOUNROLL:       otherexit:
167; NOUNROLL-NEXT:    [[SUM_02_LCSSA:%.*]] = phi i32 [ [[SUM_02]], [[FOR_EXITING_BLOCK]] ]
168; NOUNROLL-NEXT:    [[RVAL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"(i32 [[SUM_02_LCSSA]]) ]
169; NOUNROLL-NEXT:    ret i32 [[RVAL]]
170;
171; ENABLED-LABEL: @test1(
172; ENABLED-NEXT:  entry:
173; ENABLED-NEXT:    [[TMP0:%.*]] = freeze i64 [[N:%.*]]
174; ENABLED-NEXT:    [[TMP1:%.*]] = add i64 [[TMP0]], -1
175; ENABLED-NEXT:    [[XTRAITER:%.*]] = and i64 [[TMP0]], 7
176; ENABLED-NEXT:    [[TMP2:%.*]] = icmp ult i64 [[TMP1]], 7
177; ENABLED-NEXT:    br i1 [[TMP2]], label [[LATCHEXIT_UNR_LCSSA:%.*]], label [[ENTRY_NEW:%.*]]
178; ENABLED:       entry.new:
179; ENABLED-NEXT:    [[UNROLL_ITER:%.*]] = sub i64 [[TMP0]], [[XTRAITER]]
180; ENABLED-NEXT:    br label [[HEADER:%.*]]
181; ENABLED:       header:
182; ENABLED-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY_NEW]] ], [ [[INDVARS_IV_NEXT_7:%.*]], [[LATCH_7:%.*]] ]
183; ENABLED-NEXT:    [[SUM_02:%.*]] = phi i32 [ 0, [[ENTRY_NEW]] ], [ [[ADD_7:%.*]], [[LATCH_7]] ]
184; ENABLED-NEXT:    [[NITER:%.*]] = phi i64 [ 0, [[ENTRY_NEW]] ], [ [[NITER_NEXT_7:%.*]], [[LATCH_7]] ]
185; ENABLED-NEXT:    br label [[FOR_EXITING_BLOCK:%.*]]
186; ENABLED:       for.exiting_block:
187; ENABLED-NEXT:    [[CMP:%.*]] = icmp eq i64 [[N]], 42
188; ENABLED-NEXT:    br i1 [[CMP]], label [[OTHEREXIT_LOOPEXIT:%.*]], label [[LATCH:%.*]]
189; ENABLED:       latch:
190; ENABLED-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i64 [[INDVARS_IV]]
191; ENABLED-NEXT:    [[TMP3:%.*]] = load i32, i32* [[ARRAYIDX]], align 4
192; ENABLED-NEXT:    [[ADD:%.*]] = add nsw i32 [[TMP3]], [[SUM_02]]
193; ENABLED-NEXT:    [[INDVARS_IV_NEXT:%.*]] = add nuw nsw i64 [[INDVARS_IV]], 1
194; ENABLED-NEXT:    [[NITER_NEXT:%.*]] = add nuw nsw i64 [[NITER]], 1
195; ENABLED-NEXT:    br label [[FOR_EXITING_BLOCK_1:%.*]]
196; ENABLED:       for.exiting_block.1:
197; ENABLED-NEXT:    [[CMP_1:%.*]] = icmp eq i64 [[N]], 42
198; ENABLED-NEXT:    br i1 [[CMP_1]], label [[OTHEREXIT_LOOPEXIT]], label [[LATCH_1:%.*]]
199; ENABLED:       latch.1:
200; ENABLED-NEXT:    [[ARRAYIDX_1:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT]]
201; ENABLED-NEXT:    [[TMP4:%.*]] = load i32, i32* [[ARRAYIDX_1]], align 4
202; ENABLED-NEXT:    [[ADD_1:%.*]] = add nsw i32 [[TMP4]], [[ADD]]
203; ENABLED-NEXT:    [[INDVARS_IV_NEXT_1:%.*]] = add nuw nsw i64 [[INDVARS_IV_NEXT]], 1
204; ENABLED-NEXT:    [[NITER_NEXT_1:%.*]] = add nuw nsw i64 [[NITER_NEXT]], 1
205; ENABLED-NEXT:    br label [[FOR_EXITING_BLOCK_2:%.*]]
206; ENABLED:       for.exiting_block.2:
207; ENABLED-NEXT:    [[CMP_2:%.*]] = icmp eq i64 [[N]], 42
208; ENABLED-NEXT:    br i1 [[CMP_2]], label [[OTHEREXIT_LOOPEXIT]], label [[LATCH_2:%.*]]
209; ENABLED:       latch.2:
210; ENABLED-NEXT:    [[ARRAYIDX_2:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT_1]]
211; ENABLED-NEXT:    [[TMP5:%.*]] = load i32, i32* [[ARRAYIDX_2]], align 4
212; ENABLED-NEXT:    [[ADD_2:%.*]] = add nsw i32 [[TMP5]], [[ADD_1]]
213; ENABLED-NEXT:    [[INDVARS_IV_NEXT_2:%.*]] = add nuw nsw i64 [[INDVARS_IV_NEXT_1]], 1
214; ENABLED-NEXT:    [[NITER_NEXT_2:%.*]] = add nuw nsw i64 [[NITER_NEXT_1]], 1
215; ENABLED-NEXT:    br label [[FOR_EXITING_BLOCK_3:%.*]]
216; ENABLED:       for.exiting_block.3:
217; ENABLED-NEXT:    [[CMP_3:%.*]] = icmp eq i64 [[N]], 42
218; ENABLED-NEXT:    br i1 [[CMP_3]], label [[OTHEREXIT_LOOPEXIT]], label [[LATCH_3:%.*]]
219; ENABLED:       latch.3:
220; ENABLED-NEXT:    [[ARRAYIDX_3:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT_2]]
221; ENABLED-NEXT:    [[TMP6:%.*]] = load i32, i32* [[ARRAYIDX_3]], align 4
222; ENABLED-NEXT:    [[ADD_3:%.*]] = add nsw i32 [[TMP6]], [[ADD_2]]
223; ENABLED-NEXT:    [[INDVARS_IV_NEXT_3:%.*]] = add nuw nsw i64 [[INDVARS_IV_NEXT_2]], 1
224; ENABLED-NEXT:    [[NITER_NEXT_3:%.*]] = add nuw nsw i64 [[NITER_NEXT_2]], 1
225; ENABLED-NEXT:    br label [[FOR_EXITING_BLOCK_4:%.*]]
226; ENABLED:       for.exiting_block.4:
227; ENABLED-NEXT:    [[CMP_4:%.*]] = icmp eq i64 [[N]], 42
228; ENABLED-NEXT:    br i1 [[CMP_4]], label [[OTHEREXIT_LOOPEXIT]], label [[LATCH_4:%.*]]
229; ENABLED:       latch.4:
230; ENABLED-NEXT:    [[ARRAYIDX_4:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT_3]]
231; ENABLED-NEXT:    [[TMP7:%.*]] = load i32, i32* [[ARRAYIDX_4]], align 4
232; ENABLED-NEXT:    [[ADD_4:%.*]] = add nsw i32 [[TMP7]], [[ADD_3]]
233; ENABLED-NEXT:    [[INDVARS_IV_NEXT_4:%.*]] = add nuw nsw i64 [[INDVARS_IV_NEXT_3]], 1
234; ENABLED-NEXT:    [[NITER_NEXT_4:%.*]] = add nuw nsw i64 [[NITER_NEXT_3]], 1
235; ENABLED-NEXT:    br label [[FOR_EXITING_BLOCK_5:%.*]]
236; ENABLED:       for.exiting_block.5:
237; ENABLED-NEXT:    [[CMP_5:%.*]] = icmp eq i64 [[N]], 42
238; ENABLED-NEXT:    br i1 [[CMP_5]], label [[OTHEREXIT_LOOPEXIT]], label [[LATCH_5:%.*]]
239; ENABLED:       latch.5:
240; ENABLED-NEXT:    [[ARRAYIDX_5:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT_4]]
241; ENABLED-NEXT:    [[TMP8:%.*]] = load i32, i32* [[ARRAYIDX_5]], align 4
242; ENABLED-NEXT:    [[ADD_5:%.*]] = add nsw i32 [[TMP8]], [[ADD_4]]
243; ENABLED-NEXT:    [[INDVARS_IV_NEXT_5:%.*]] = add nuw nsw i64 [[INDVARS_IV_NEXT_4]], 1
244; ENABLED-NEXT:    [[NITER_NEXT_5:%.*]] = add nuw nsw i64 [[NITER_NEXT_4]], 1
245; ENABLED-NEXT:    br label [[FOR_EXITING_BLOCK_6:%.*]]
246; ENABLED:       for.exiting_block.6:
247; ENABLED-NEXT:    [[CMP_6:%.*]] = icmp eq i64 [[N]], 42
248; ENABLED-NEXT:    br i1 [[CMP_6]], label [[OTHEREXIT_LOOPEXIT]], label [[LATCH_6:%.*]]
249; ENABLED:       latch.6:
250; ENABLED-NEXT:    [[ARRAYIDX_6:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT_5]]
251; ENABLED-NEXT:    [[TMP9:%.*]] = load i32, i32* [[ARRAYIDX_6]], align 4
252; ENABLED-NEXT:    [[ADD_6:%.*]] = add nsw i32 [[TMP9]], [[ADD_5]]
253; ENABLED-NEXT:    [[INDVARS_IV_NEXT_6:%.*]] = add nuw nsw i64 [[INDVARS_IV_NEXT_5]], 1
254; ENABLED-NEXT:    [[NITER_NEXT_6:%.*]] = add nuw nsw i64 [[NITER_NEXT_5]], 1
255; ENABLED-NEXT:    br label [[FOR_EXITING_BLOCK_7:%.*]]
256; ENABLED:       for.exiting_block.7:
257; ENABLED-NEXT:    [[CMP_7:%.*]] = icmp eq i64 [[N]], 42
258; ENABLED-NEXT:    br i1 [[CMP_7]], label [[OTHEREXIT_LOOPEXIT]], label [[LATCH_7]]
259; ENABLED:       latch.7:
260; ENABLED-NEXT:    [[ARRAYIDX_7:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT_6]]
261; ENABLED-NEXT:    [[TMP10:%.*]] = load i32, i32* [[ARRAYIDX_7]], align 4
262; ENABLED-NEXT:    [[ADD_7]] = add nsw i32 [[TMP10]], [[ADD_6]]
263; ENABLED-NEXT:    [[INDVARS_IV_NEXT_7]] = add i64 [[INDVARS_IV_NEXT_6]], 1
264; ENABLED-NEXT:    [[NITER_NEXT_7]] = add i64 [[NITER_NEXT_6]], 1
265; ENABLED-NEXT:    [[NITER_NCMP_7:%.*]] = icmp eq i64 [[NITER_NEXT_7]], [[UNROLL_ITER]]
266; ENABLED-NEXT:    br i1 [[NITER_NCMP_7]], label [[LATCHEXIT_UNR_LCSSA_LOOPEXIT:%.*]], label [[HEADER]]
267; ENABLED:       latchexit.unr-lcssa.loopexit:
268; ENABLED-NEXT:    [[SUM_0_LCSSA_PH_PH:%.*]] = phi i32 [ [[ADD_7]], [[LATCH_7]] ]
269; ENABLED-NEXT:    [[INDVARS_IV_UNR_PH:%.*]] = phi i64 [ [[INDVARS_IV_NEXT_7]], [[LATCH_7]] ]
270; ENABLED-NEXT:    [[SUM_02_UNR_PH:%.*]] = phi i32 [ [[ADD_7]], [[LATCH_7]] ]
271; ENABLED-NEXT:    br label [[LATCHEXIT_UNR_LCSSA]]
272; ENABLED:       latchexit.unr-lcssa:
273; ENABLED-NEXT:    [[SUM_0_LCSSA_PH:%.*]] = phi i32 [ undef, [[ENTRY:%.*]] ], [ [[SUM_0_LCSSA_PH_PH]], [[LATCHEXIT_UNR_LCSSA_LOOPEXIT]] ]
274; ENABLED-NEXT:    [[INDVARS_IV_UNR:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[INDVARS_IV_UNR_PH]], [[LATCHEXIT_UNR_LCSSA_LOOPEXIT]] ]
275; ENABLED-NEXT:    [[SUM_02_UNR:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[SUM_02_UNR_PH]], [[LATCHEXIT_UNR_LCSSA_LOOPEXIT]] ]
276; ENABLED-NEXT:    [[LCMP_MOD:%.*]] = icmp ne i64 [[XTRAITER]], 0
277; ENABLED-NEXT:    br i1 [[LCMP_MOD]], label [[HEADER_EPIL_PREHEADER:%.*]], label [[LATCHEXIT:%.*]]
278; ENABLED:       header.epil.preheader:
279; ENABLED-NEXT:    br label [[HEADER_EPIL:%.*]]
280; ENABLED:       header.epil:
281; ENABLED-NEXT:    [[INDVARS_IV_EPIL:%.*]] = phi i64 [ [[INDVARS_IV_NEXT_EPIL:%.*]], [[LATCH_EPIL:%.*]] ], [ [[INDVARS_IV_UNR]], [[HEADER_EPIL_PREHEADER]] ]
282; ENABLED-NEXT:    [[SUM_02_EPIL:%.*]] = phi i32 [ [[ADD_EPIL:%.*]], [[LATCH_EPIL]] ], [ [[SUM_02_UNR]], [[HEADER_EPIL_PREHEADER]] ]
283; ENABLED-NEXT:    [[EPIL_ITER:%.*]] = phi i64 [ 0, [[HEADER_EPIL_PREHEADER]] ], [ [[EPIL_ITER_NEXT:%.*]], [[LATCH_EPIL]] ]
284; ENABLED-NEXT:    br label [[FOR_EXITING_BLOCK_EPIL:%.*]]
285; ENABLED:       for.exiting_block.epil:
286; ENABLED-NEXT:    [[CMP_EPIL:%.*]] = icmp eq i64 [[N]], 42
287; ENABLED-NEXT:    br i1 [[CMP_EPIL]], label [[OTHEREXIT_LOOPEXIT3:%.*]], label [[LATCH_EPIL]]
288; ENABLED:       latch.epil:
289; ENABLED-NEXT:    [[ARRAYIDX_EPIL:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_EPIL]]
290; ENABLED-NEXT:    [[TMP11:%.*]] = load i32, i32* [[ARRAYIDX_EPIL]], align 4
291; ENABLED-NEXT:    [[ADD_EPIL]] = add nsw i32 [[TMP11]], [[SUM_02_EPIL]]
292; ENABLED-NEXT:    [[INDVARS_IV_NEXT_EPIL]] = add i64 [[INDVARS_IV_EPIL]], 1
293; ENABLED-NEXT:    [[EXITCOND_EPIL:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT_EPIL]], [[N]]
294; ENABLED-NEXT:    [[EPIL_ITER_NEXT]] = add i64 [[EPIL_ITER]], 1
295; ENABLED-NEXT:    [[EPIL_ITER_CMP:%.*]] = icmp ne i64 [[EPIL_ITER_NEXT]], [[XTRAITER]]
296; ENABLED-NEXT:    br i1 [[EPIL_ITER_CMP]], label [[HEADER_EPIL]], label [[LATCHEXIT_EPILOG_LCSSA:%.*]], !llvm.loop [[LOOP0:![0-9]+]]
297; ENABLED:       latchexit.epilog-lcssa:
298; ENABLED-NEXT:    [[SUM_0_LCSSA_PH2:%.*]] = phi i32 [ [[ADD_EPIL]], [[LATCH_EPIL]] ]
299; ENABLED-NEXT:    br label [[LATCHEXIT]]
300; ENABLED:       latchexit:
301; ENABLED-NEXT:    [[SUM_0_LCSSA:%.*]] = phi i32 [ [[SUM_0_LCSSA_PH]], [[LATCHEXIT_UNR_LCSSA]] ], [ [[SUM_0_LCSSA_PH2]], [[LATCHEXIT_EPILOG_LCSSA]] ]
302; ENABLED-NEXT:    ret i32 [[SUM_0_LCSSA]]
303; ENABLED:       otherexit.loopexit:
304; ENABLED-NEXT:    [[SUM_02_LCSSA_PH:%.*]] = phi i32 [ [[SUM_02]], [[FOR_EXITING_BLOCK]] ], [ [[ADD]], [[FOR_EXITING_BLOCK_1]] ], [ [[ADD_1]], [[FOR_EXITING_BLOCK_2]] ], [ [[ADD_2]], [[FOR_EXITING_BLOCK_3]] ], [ [[ADD_3]], [[FOR_EXITING_BLOCK_4]] ], [ [[ADD_4]], [[FOR_EXITING_BLOCK_5]] ], [ [[ADD_5]], [[FOR_EXITING_BLOCK_6]] ], [ [[ADD_6]], [[FOR_EXITING_BLOCK_7]] ]
305; ENABLED-NEXT:    br label [[OTHEREXIT:%.*]]
306; ENABLED:       otherexit.loopexit3:
307; ENABLED-NEXT:    [[SUM_02_LCSSA_PH4:%.*]] = phi i32 [ [[SUM_02_EPIL]], [[FOR_EXITING_BLOCK_EPIL]] ]
308; ENABLED-NEXT:    br label [[OTHEREXIT]]
309; ENABLED:       otherexit:
310; ENABLED-NEXT:    [[SUM_02_LCSSA:%.*]] = phi i32 [ [[SUM_02_LCSSA_PH]], [[OTHEREXIT_LOOPEXIT]] ], [ [[SUM_02_LCSSA_PH4]], [[OTHEREXIT_LOOPEXIT3]] ]
311; ENABLED-NEXT:    [[RVAL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"(i32 [[SUM_02_LCSSA]]) ]
312; ENABLED-NEXT:    ret i32 [[RVAL]]
313;
314entry:
315  br label %header
316
317header:
318  %indvars.iv = phi i64 [ %indvars.iv.next, %latch ], [ 0, %entry ]
319  %sum.02 = phi i32 [ %add, %latch ], [ 0, %entry ]
320  br label %for.exiting_block
321
322for.exiting_block:
323  %cmp = icmp eq i64 %n, 42
324  br i1 %cmp, label %otherexit, label %latch
325
326latch:
327  %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
328  %0 = load i32, i32* %arrayidx, align 4
329  %add = add nsw i32 %0, %sum.02
330  %indvars.iv.next = add i64 %indvars.iv, 1
331  %exitcond = icmp eq i64 %indvars.iv.next, %n
332  br i1 %exitcond, label %latchexit, label %header
333
334latchexit:                                          ; preds = %latch
335  %sum.0.lcssa = phi i32 [ %add, %latch ]
336  ret i32 %sum.0.lcssa
337
338otherexit:
339  %rval = call i32(...) @llvm.experimental.deoptimize.i32() [ "deopt"(i32 %sum.02) ]
340  ret i32 %rval
341}
342
343; the exit block is not a deopt block.
344define i32 @test2(i32* nocapture %a, i64 %n) {
345;
346; CHECK-LABEL: @test2(
347; CHECK-NEXT:  entry:
348; CHECK-NEXT:    br label [[HEADER:%.*]]
349; CHECK:       header:
350; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LATCH:%.*]] ], [ 0, [[ENTRY:%.*]] ]
351; CHECK-NEXT:    [[SUM_02:%.*]] = phi i32 [ [[ADD:%.*]], [[LATCH]] ], [ 0, [[ENTRY]] ]
352; CHECK-NEXT:    br label [[FOR_EXITING_BLOCK:%.*]]
353; CHECK:       for.exiting_block:
354; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i64 [[N:%.*]], 42
355; CHECK-NEXT:    br i1 [[CMP]], label [[OTHEREXIT:%.*]], label [[LATCH]]
356; CHECK:       latch:
357; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i64 [[INDVARS_IV]]
358; CHECK-NEXT:    [[TMP0:%.*]] = load i32, i32* [[ARRAYIDX]], align 4
359; CHECK-NEXT:    [[ADD]] = add nsw i32 [[TMP0]], [[SUM_02]]
360; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add i64 [[INDVARS_IV]], 1
361; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], [[N]]
362; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LATCHEXIT:%.*]], label [[HEADER]]
363; CHECK:       latchexit:
364; CHECK-NEXT:    ret i32 [[ADD]]
365; CHECK:       otherexit:
366; CHECK-NEXT:    ret i32 [[SUM_02]]
367;
368; NOUNROLL-LABEL: @test2(
369; NOUNROLL-NEXT:  entry:
370; NOUNROLL-NEXT:    br label [[HEADER:%.*]]
371; NOUNROLL:       header:
372; NOUNROLL-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LATCH:%.*]] ], [ 0, [[ENTRY:%.*]] ]
373; NOUNROLL-NEXT:    [[SUM_02:%.*]] = phi i32 [ [[ADD:%.*]], [[LATCH]] ], [ 0, [[ENTRY]] ]
374; NOUNROLL-NEXT:    br label [[FOR_EXITING_BLOCK:%.*]]
375; NOUNROLL:       for.exiting_block:
376; NOUNROLL-NEXT:    [[CMP:%.*]] = icmp eq i64 [[N:%.*]], 42
377; NOUNROLL-NEXT:    br i1 [[CMP]], label [[OTHEREXIT:%.*]], label [[LATCH]]
378; NOUNROLL:       latch:
379; NOUNROLL-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i64 [[INDVARS_IV]]
380; NOUNROLL-NEXT:    [[TMP0:%.*]] = load i32, i32* [[ARRAYIDX]], align 4
381; NOUNROLL-NEXT:    [[ADD]] = add nsw i32 [[TMP0]], [[SUM_02]]
382; NOUNROLL-NEXT:    [[INDVARS_IV_NEXT]] = add i64 [[INDVARS_IV]], 1
383; NOUNROLL-NEXT:    [[EXITCOND:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], [[N]]
384; NOUNROLL-NEXT:    br i1 [[EXITCOND]], label [[LATCHEXIT:%.*]], label [[HEADER]]
385; NOUNROLL:       latchexit:
386; NOUNROLL-NEXT:    [[SUM_0_LCSSA:%.*]] = phi i32 [ [[ADD]], [[LATCH]] ]
387; NOUNROLL-NEXT:    ret i32 [[SUM_0_LCSSA]]
388; NOUNROLL:       otherexit:
389; NOUNROLL-NEXT:    [[RVAL:%.*]] = phi i32 [ [[SUM_02]], [[FOR_EXITING_BLOCK]] ]
390; NOUNROLL-NEXT:    ret i32 [[RVAL]]
391;
392; ENABLED-LABEL: @test2(
393; ENABLED-NEXT:  entry:
394; ENABLED-NEXT:    [[TMP0:%.*]] = freeze i64 [[N:%.*]]
395; ENABLED-NEXT:    [[TMP1:%.*]] = add i64 [[TMP0]], -1
396; ENABLED-NEXT:    [[XTRAITER:%.*]] = and i64 [[TMP0]], 7
397; ENABLED-NEXT:    [[TMP2:%.*]] = icmp ult i64 [[TMP1]], 7
398; ENABLED-NEXT:    br i1 [[TMP2]], label [[LATCHEXIT_UNR_LCSSA:%.*]], label [[ENTRY_NEW:%.*]]
399; ENABLED:       entry.new:
400; ENABLED-NEXT:    [[UNROLL_ITER:%.*]] = sub i64 [[TMP0]], [[XTRAITER]]
401; ENABLED-NEXT:    br label [[HEADER:%.*]]
402; ENABLED:       header:
403; ENABLED-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY_NEW]] ], [ [[INDVARS_IV_NEXT_7:%.*]], [[LATCH_7:%.*]] ]
404; ENABLED-NEXT:    [[SUM_02:%.*]] = phi i32 [ 0, [[ENTRY_NEW]] ], [ [[ADD_7:%.*]], [[LATCH_7]] ]
405; ENABLED-NEXT:    [[NITER:%.*]] = phi i64 [ 0, [[ENTRY_NEW]] ], [ [[NITER_NEXT_7:%.*]], [[LATCH_7]] ]
406; ENABLED-NEXT:    br label [[FOR_EXITING_BLOCK:%.*]]
407; ENABLED:       for.exiting_block:
408; ENABLED-NEXT:    [[CMP:%.*]] = icmp eq i64 [[N]], 42
409; ENABLED-NEXT:    br i1 [[CMP]], label [[OTHEREXIT_LOOPEXIT:%.*]], label [[LATCH:%.*]]
410; ENABLED:       latch:
411; ENABLED-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i64 [[INDVARS_IV]]
412; ENABLED-NEXT:    [[TMP3:%.*]] = load i32, i32* [[ARRAYIDX]], align 4
413; ENABLED-NEXT:    [[ADD:%.*]] = add nsw i32 [[TMP3]], [[SUM_02]]
414; ENABLED-NEXT:    [[INDVARS_IV_NEXT:%.*]] = add nuw nsw i64 [[INDVARS_IV]], 1
415; ENABLED-NEXT:    [[NITER_NEXT:%.*]] = add nuw nsw i64 [[NITER]], 1
416; ENABLED-NEXT:    br label [[FOR_EXITING_BLOCK_1:%.*]]
417; ENABLED:       for.exiting_block.1:
418; ENABLED-NEXT:    [[CMP_1:%.*]] = icmp eq i64 [[N]], 42
419; ENABLED-NEXT:    br i1 [[CMP_1]], label [[OTHEREXIT_LOOPEXIT]], label [[LATCH_1:%.*]]
420; ENABLED:       latch.1:
421; ENABLED-NEXT:    [[ARRAYIDX_1:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT]]
422; ENABLED-NEXT:    [[TMP4:%.*]] = load i32, i32* [[ARRAYIDX_1]], align 4
423; ENABLED-NEXT:    [[ADD_1:%.*]] = add nsw i32 [[TMP4]], [[ADD]]
424; ENABLED-NEXT:    [[INDVARS_IV_NEXT_1:%.*]] = add nuw nsw i64 [[INDVARS_IV_NEXT]], 1
425; ENABLED-NEXT:    [[NITER_NEXT_1:%.*]] = add nuw nsw i64 [[NITER_NEXT]], 1
426; ENABLED-NEXT:    br label [[FOR_EXITING_BLOCK_2:%.*]]
427; ENABLED:       for.exiting_block.2:
428; ENABLED-NEXT:    [[CMP_2:%.*]] = icmp eq i64 [[N]], 42
429; ENABLED-NEXT:    br i1 [[CMP_2]], label [[OTHEREXIT_LOOPEXIT]], label [[LATCH_2:%.*]]
430; ENABLED:       latch.2:
431; ENABLED-NEXT:    [[ARRAYIDX_2:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT_1]]
432; ENABLED-NEXT:    [[TMP5:%.*]] = load i32, i32* [[ARRAYIDX_2]], align 4
433; ENABLED-NEXT:    [[ADD_2:%.*]] = add nsw i32 [[TMP5]], [[ADD_1]]
434; ENABLED-NEXT:    [[INDVARS_IV_NEXT_2:%.*]] = add nuw nsw i64 [[INDVARS_IV_NEXT_1]], 1
435; ENABLED-NEXT:    [[NITER_NEXT_2:%.*]] = add nuw nsw i64 [[NITER_NEXT_1]], 1
436; ENABLED-NEXT:    br label [[FOR_EXITING_BLOCK_3:%.*]]
437; ENABLED:       for.exiting_block.3:
438; ENABLED-NEXT:    [[CMP_3:%.*]] = icmp eq i64 [[N]], 42
439; ENABLED-NEXT:    br i1 [[CMP_3]], label [[OTHEREXIT_LOOPEXIT]], label [[LATCH_3:%.*]]
440; ENABLED:       latch.3:
441; ENABLED-NEXT:    [[ARRAYIDX_3:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT_2]]
442; ENABLED-NEXT:    [[TMP6:%.*]] = load i32, i32* [[ARRAYIDX_3]], align 4
443; ENABLED-NEXT:    [[ADD_3:%.*]] = add nsw i32 [[TMP6]], [[ADD_2]]
444; ENABLED-NEXT:    [[INDVARS_IV_NEXT_3:%.*]] = add nuw nsw i64 [[INDVARS_IV_NEXT_2]], 1
445; ENABLED-NEXT:    [[NITER_NEXT_3:%.*]] = add nuw nsw i64 [[NITER_NEXT_2]], 1
446; ENABLED-NEXT:    br label [[FOR_EXITING_BLOCK_4:%.*]]
447; ENABLED:       for.exiting_block.4:
448; ENABLED-NEXT:    [[CMP_4:%.*]] = icmp eq i64 [[N]], 42
449; ENABLED-NEXT:    br i1 [[CMP_4]], label [[OTHEREXIT_LOOPEXIT]], label [[LATCH_4:%.*]]
450; ENABLED:       latch.4:
451; ENABLED-NEXT:    [[ARRAYIDX_4:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT_3]]
452; ENABLED-NEXT:    [[TMP7:%.*]] = load i32, i32* [[ARRAYIDX_4]], align 4
453; ENABLED-NEXT:    [[ADD_4:%.*]] = add nsw i32 [[TMP7]], [[ADD_3]]
454; ENABLED-NEXT:    [[INDVARS_IV_NEXT_4:%.*]] = add nuw nsw i64 [[INDVARS_IV_NEXT_3]], 1
455; ENABLED-NEXT:    [[NITER_NEXT_4:%.*]] = add nuw nsw i64 [[NITER_NEXT_3]], 1
456; ENABLED-NEXT:    br label [[FOR_EXITING_BLOCK_5:%.*]]
457; ENABLED:       for.exiting_block.5:
458; ENABLED-NEXT:    [[CMP_5:%.*]] = icmp eq i64 [[N]], 42
459; ENABLED-NEXT:    br i1 [[CMP_5]], label [[OTHEREXIT_LOOPEXIT]], label [[LATCH_5:%.*]]
460; ENABLED:       latch.5:
461; ENABLED-NEXT:    [[ARRAYIDX_5:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT_4]]
462; ENABLED-NEXT:    [[TMP8:%.*]] = load i32, i32* [[ARRAYIDX_5]], align 4
463; ENABLED-NEXT:    [[ADD_5:%.*]] = add nsw i32 [[TMP8]], [[ADD_4]]
464; ENABLED-NEXT:    [[INDVARS_IV_NEXT_5:%.*]] = add nuw nsw i64 [[INDVARS_IV_NEXT_4]], 1
465; ENABLED-NEXT:    [[NITER_NEXT_5:%.*]] = add nuw nsw i64 [[NITER_NEXT_4]], 1
466; ENABLED-NEXT:    br label [[FOR_EXITING_BLOCK_6:%.*]]
467; ENABLED:       for.exiting_block.6:
468; ENABLED-NEXT:    [[CMP_6:%.*]] = icmp eq i64 [[N]], 42
469; ENABLED-NEXT:    br i1 [[CMP_6]], label [[OTHEREXIT_LOOPEXIT]], label [[LATCH_6:%.*]]
470; ENABLED:       latch.6:
471; ENABLED-NEXT:    [[ARRAYIDX_6:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT_5]]
472; ENABLED-NEXT:    [[TMP9:%.*]] = load i32, i32* [[ARRAYIDX_6]], align 4
473; ENABLED-NEXT:    [[ADD_6:%.*]] = add nsw i32 [[TMP9]], [[ADD_5]]
474; ENABLED-NEXT:    [[INDVARS_IV_NEXT_6:%.*]] = add nuw nsw i64 [[INDVARS_IV_NEXT_5]], 1
475; ENABLED-NEXT:    [[NITER_NEXT_6:%.*]] = add nuw nsw i64 [[NITER_NEXT_5]], 1
476; ENABLED-NEXT:    br label [[FOR_EXITING_BLOCK_7:%.*]]
477; ENABLED:       for.exiting_block.7:
478; ENABLED-NEXT:    [[CMP_7:%.*]] = icmp eq i64 [[N]], 42
479; ENABLED-NEXT:    br i1 [[CMP_7]], label [[OTHEREXIT_LOOPEXIT]], label [[LATCH_7]]
480; ENABLED:       latch.7:
481; ENABLED-NEXT:    [[ARRAYIDX_7:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_NEXT_6]]
482; ENABLED-NEXT:    [[TMP10:%.*]] = load i32, i32* [[ARRAYIDX_7]], align 4
483; ENABLED-NEXT:    [[ADD_7]] = add nsw i32 [[TMP10]], [[ADD_6]]
484; ENABLED-NEXT:    [[INDVARS_IV_NEXT_7]] = add i64 [[INDVARS_IV_NEXT_6]], 1
485; ENABLED-NEXT:    [[NITER_NEXT_7]] = add i64 [[NITER_NEXT_6]], 1
486; ENABLED-NEXT:    [[NITER_NCMP_7:%.*]] = icmp eq i64 [[NITER_NEXT_7]], [[UNROLL_ITER]]
487; ENABLED-NEXT:    br i1 [[NITER_NCMP_7]], label [[LATCHEXIT_UNR_LCSSA_LOOPEXIT:%.*]], label [[HEADER]]
488; ENABLED:       latchexit.unr-lcssa.loopexit:
489; ENABLED-NEXT:    [[SUM_0_LCSSA_PH_PH:%.*]] = phi i32 [ [[ADD_7]], [[LATCH_7]] ]
490; ENABLED-NEXT:    [[INDVARS_IV_UNR_PH:%.*]] = phi i64 [ [[INDVARS_IV_NEXT_7]], [[LATCH_7]] ]
491; ENABLED-NEXT:    [[SUM_02_UNR_PH:%.*]] = phi i32 [ [[ADD_7]], [[LATCH_7]] ]
492; ENABLED-NEXT:    br label [[LATCHEXIT_UNR_LCSSA]]
493; ENABLED:       latchexit.unr-lcssa:
494; ENABLED-NEXT:    [[SUM_0_LCSSA_PH:%.*]] = phi i32 [ undef, [[ENTRY:%.*]] ], [ [[SUM_0_LCSSA_PH_PH]], [[LATCHEXIT_UNR_LCSSA_LOOPEXIT]] ]
495; ENABLED-NEXT:    [[INDVARS_IV_UNR:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[INDVARS_IV_UNR_PH]], [[LATCHEXIT_UNR_LCSSA_LOOPEXIT]] ]
496; ENABLED-NEXT:    [[SUM_02_UNR:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[SUM_02_UNR_PH]], [[LATCHEXIT_UNR_LCSSA_LOOPEXIT]] ]
497; ENABLED-NEXT:    [[LCMP_MOD:%.*]] = icmp ne i64 [[XTRAITER]], 0
498; ENABLED-NEXT:    br i1 [[LCMP_MOD]], label [[HEADER_EPIL_PREHEADER:%.*]], label [[LATCHEXIT:%.*]]
499; ENABLED:       header.epil.preheader:
500; ENABLED-NEXT:    br label [[HEADER_EPIL:%.*]]
501; ENABLED:       header.epil:
502; ENABLED-NEXT:    [[INDVARS_IV_EPIL:%.*]] = phi i64 [ [[INDVARS_IV_NEXT_EPIL:%.*]], [[LATCH_EPIL:%.*]] ], [ [[INDVARS_IV_UNR]], [[HEADER_EPIL_PREHEADER]] ]
503; ENABLED-NEXT:    [[SUM_02_EPIL:%.*]] = phi i32 [ [[ADD_EPIL:%.*]], [[LATCH_EPIL]] ], [ [[SUM_02_UNR]], [[HEADER_EPIL_PREHEADER]] ]
504; ENABLED-NEXT:    [[EPIL_ITER:%.*]] = phi i64 [ 0, [[HEADER_EPIL_PREHEADER]] ], [ [[EPIL_ITER_NEXT:%.*]], [[LATCH_EPIL]] ]
505; ENABLED-NEXT:    br label [[FOR_EXITING_BLOCK_EPIL:%.*]]
506; ENABLED:       for.exiting_block.epil:
507; ENABLED-NEXT:    [[CMP_EPIL:%.*]] = icmp eq i64 [[N]], 42
508; ENABLED-NEXT:    br i1 [[CMP_EPIL]], label [[OTHEREXIT_LOOPEXIT2:%.*]], label [[LATCH_EPIL]]
509; ENABLED:       latch.epil:
510; ENABLED-NEXT:    [[ARRAYIDX_EPIL:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV_EPIL]]
511; ENABLED-NEXT:    [[TMP11:%.*]] = load i32, i32* [[ARRAYIDX_EPIL]], align 4
512; ENABLED-NEXT:    [[ADD_EPIL]] = add nsw i32 [[TMP11]], [[SUM_02_EPIL]]
513; ENABLED-NEXT:    [[INDVARS_IV_NEXT_EPIL]] = add i64 [[INDVARS_IV_EPIL]], 1
514; ENABLED-NEXT:    [[EXITCOND_EPIL:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT_EPIL]], [[N]]
515; ENABLED-NEXT:    [[EPIL_ITER_NEXT]] = add i64 [[EPIL_ITER]], 1
516; ENABLED-NEXT:    [[EPIL_ITER_CMP:%.*]] = icmp ne i64 [[EPIL_ITER_NEXT]], [[XTRAITER]]
517; ENABLED-NEXT:    br i1 [[EPIL_ITER_CMP]], label [[HEADER_EPIL]], label [[LATCHEXIT_EPILOG_LCSSA:%.*]], !llvm.loop [[LOOP2:![0-9]+]]
518; ENABLED:       latchexit.epilog-lcssa:
519; ENABLED-NEXT:    [[SUM_0_LCSSA_PH1:%.*]] = phi i32 [ [[ADD_EPIL]], [[LATCH_EPIL]] ]
520; ENABLED-NEXT:    br label [[LATCHEXIT]]
521; ENABLED:       latchexit:
522; ENABLED-NEXT:    [[SUM_0_LCSSA:%.*]] = phi i32 [ [[SUM_0_LCSSA_PH]], [[LATCHEXIT_UNR_LCSSA]] ], [ [[SUM_0_LCSSA_PH1]], [[LATCHEXIT_EPILOG_LCSSA]] ]
523; ENABLED-NEXT:    ret i32 [[SUM_0_LCSSA]]
524; ENABLED:       otherexit.loopexit:
525; ENABLED-NEXT:    [[RVAL_PH:%.*]] = phi i32 [ [[SUM_02]], [[FOR_EXITING_BLOCK]] ], [ [[ADD]], [[FOR_EXITING_BLOCK_1]] ], [ [[ADD_1]], [[FOR_EXITING_BLOCK_2]] ], [ [[ADD_2]], [[FOR_EXITING_BLOCK_3]] ], [ [[ADD_3]], [[FOR_EXITING_BLOCK_4]] ], [ [[ADD_4]], [[FOR_EXITING_BLOCK_5]] ], [ [[ADD_5]], [[FOR_EXITING_BLOCK_6]] ], [ [[ADD_6]], [[FOR_EXITING_BLOCK_7]] ]
526; ENABLED-NEXT:    br label [[OTHEREXIT:%.*]]
527; ENABLED:       otherexit.loopexit2:
528; ENABLED-NEXT:    [[RVAL_PH3:%.*]] = phi i32 [ [[SUM_02_EPIL]], [[FOR_EXITING_BLOCK_EPIL]] ]
529; ENABLED-NEXT:    br label [[OTHEREXIT]]
530; ENABLED:       otherexit:
531; ENABLED-NEXT:    [[RVAL:%.*]] = phi i32 [ [[RVAL_PH]], [[OTHEREXIT_LOOPEXIT]] ], [ [[RVAL_PH3]], [[OTHEREXIT_LOOPEXIT2]] ]
532; ENABLED-NEXT:    ret i32 [[RVAL]]
533;
534entry:
535  br label %header
536
537header:
538  %indvars.iv = phi i64 [ %indvars.iv.next, %latch ], [ 0, %entry ]
539  %sum.02 = phi i32 [ %add, %latch ], [ 0, %entry ]
540  br label %for.exiting_block
541
542for.exiting_block:
543  %cmp = icmp eq i64 %n, 42
544  br i1 %cmp, label %otherexit, label %latch
545
546latch:
547  %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
548  %0 = load i32, i32* %arrayidx, align 4
549  %add = add nsw i32 %0, %sum.02
550  %indvars.iv.next = add i64 %indvars.iv, 1
551  %exitcond = icmp eq i64 %indvars.iv.next, %n
552  br i1 %exitcond, label %latchexit, label %header
553
554latchexit:                                          ; preds = %latch
555  %sum.0.lcssa = phi i32 [ %add, %latch ]
556  ret i32 %sum.0.lcssa
557
558otherexit:
559  %rval = phi i32 [%sum.02, %for.exiting_block ]
560  ret i32 %rval
561}
562
563; A multiple exit loop with an estimated trip count which is small, and thus
564; the loop is not worth unrolling.  We probably should peel said loop, but
565; currently don't.
566define i32 @test3(i32* nocapture %a, i64 %n) !prof !{!"function_entry_count", i64 2048} {
567; CHECK-LABEL: @test3(
568; CHECK-NEXT:  entry:
569; CHECK-NEXT:    br label [[HEADER:%.*]]
570; CHECK:       header:
571; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LATCH:%.*]] ], [ 0, [[ENTRY:%.*]] ]
572; CHECK-NEXT:    [[SUM_02:%.*]] = phi i32 [ [[ADD:%.*]], [[LATCH]] ], [ 0, [[ENTRY]] ]
573; CHECK-NEXT:    br label [[FOR_EXITING_BLOCK:%.*]]
574; CHECK:       for.exiting_block:
575; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i64 [[N:%.*]], 42
576; CHECK-NEXT:    br i1 [[CMP]], label [[OTHEREXIT:%.*]], label [[LATCH]]
577; CHECK:       latch:
578; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i64 [[INDVARS_IV]]
579; CHECK-NEXT:    [[TMP0:%.*]] = load i32, i32* [[ARRAYIDX]], align 4
580; CHECK-NEXT:    [[ADD]] = add nsw i32 [[TMP0]], [[SUM_02]]
581; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add i64 [[INDVARS_IV]], 1
582; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], [[N]]
583; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LATCHEXIT:%.*]], label [[HEADER]], !prof [[PROF3:![0-9]+]]
584; CHECK:       latchexit:
585; CHECK-NEXT:    ret i32 [[ADD]]
586; CHECK:       otherexit:
587; CHECK-NEXT:    ret i32 57
588;
589; NOUNROLL-LABEL: @test3(
590; NOUNROLL-NEXT:  entry:
591; NOUNROLL-NEXT:    br label [[HEADER:%.*]]
592; NOUNROLL:       header:
593; NOUNROLL-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LATCH:%.*]] ], [ 0, [[ENTRY:%.*]] ]
594; NOUNROLL-NEXT:    [[SUM_02:%.*]] = phi i32 [ [[ADD:%.*]], [[LATCH]] ], [ 0, [[ENTRY]] ]
595; NOUNROLL-NEXT:    br label [[FOR_EXITING_BLOCK:%.*]]
596; NOUNROLL:       for.exiting_block:
597; NOUNROLL-NEXT:    [[CMP:%.*]] = icmp eq i64 [[N:%.*]], 42
598; NOUNROLL-NEXT:    br i1 [[CMP]], label [[OTHEREXIT:%.*]], label [[LATCH]]
599; NOUNROLL:       latch:
600; NOUNROLL-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i64 [[INDVARS_IV]]
601; NOUNROLL-NEXT:    [[TMP0:%.*]] = load i32, i32* [[ARRAYIDX]], align 4
602; NOUNROLL-NEXT:    [[ADD]] = add nsw i32 [[TMP0]], [[SUM_02]]
603; NOUNROLL-NEXT:    [[INDVARS_IV_NEXT]] = add i64 [[INDVARS_IV]], 1
604; NOUNROLL-NEXT:    [[EXITCOND:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], [[N]]
605; NOUNROLL-NEXT:    br i1 [[EXITCOND]], label [[LATCHEXIT:%.*]], label [[HEADER]], !prof [[PROF1:![0-9]+]]
606; NOUNROLL:       latchexit:
607; NOUNROLL-NEXT:    [[SUM_0_LCSSA:%.*]] = phi i32 [ [[ADD]], [[LATCH]] ]
608; NOUNROLL-NEXT:    ret i32 [[SUM_0_LCSSA]]
609; NOUNROLL:       otherexit:
610; NOUNROLL-NEXT:    ret i32 57
611;
612; ENABLED-LABEL: @test3(
613; ENABLED-NEXT:  entry:
614; ENABLED-NEXT:    br label [[HEADER:%.*]]
615; ENABLED:       header:
616; ENABLED-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LATCH:%.*]] ], [ 0, [[ENTRY:%.*]] ]
617; ENABLED-NEXT:    [[SUM_02:%.*]] = phi i32 [ [[ADD:%.*]], [[LATCH]] ], [ 0, [[ENTRY]] ]
618; ENABLED-NEXT:    br label [[FOR_EXITING_BLOCK:%.*]]
619; ENABLED:       for.exiting_block:
620; ENABLED-NEXT:    [[CMP:%.*]] = icmp eq i64 [[N:%.*]], 42
621; ENABLED-NEXT:    br i1 [[CMP]], label [[OTHEREXIT:%.*]], label [[LATCH]]
622; ENABLED:       latch:
623; ENABLED-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i64 [[INDVARS_IV]]
624; ENABLED-NEXT:    [[TMP0:%.*]] = load i32, i32* [[ARRAYIDX]], align 4
625; ENABLED-NEXT:    [[ADD]] = add nsw i32 [[TMP0]], [[SUM_02]]
626; ENABLED-NEXT:    [[INDVARS_IV_NEXT]] = add i64 [[INDVARS_IV]], 1
627; ENABLED-NEXT:    [[EXITCOND:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], [[N]]
628; ENABLED-NEXT:    br i1 [[EXITCOND]], label [[LATCHEXIT:%.*]], label [[HEADER]], !prof [[PROF4:![0-9]+]]
629; ENABLED:       latchexit:
630; ENABLED-NEXT:    [[SUM_0_LCSSA:%.*]] = phi i32 [ [[ADD]], [[LATCH]] ]
631; ENABLED-NEXT:    ret i32 [[SUM_0_LCSSA]]
632; ENABLED:       otherexit:
633; ENABLED-NEXT:    ret i32 57
634;
635entry:
636  br label %header
637
638header:
639  %indvars.iv = phi i64 [ %indvars.iv.next, %latch ], [ 0, %entry ]
640  %sum.02 = phi i32 [ %add, %latch ], [ 0, %entry ]
641  br label %for.exiting_block
642
643for.exiting_block:
644  %cmp = icmp eq i64 %n, 42
645  br i1 %cmp, label %otherexit, label %latch
646
647latch:
648  %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
649  %0 = load i32, i32* %arrayidx, align 4
650  %add = add nsw i32 %0, %sum.02
651  %indvars.iv.next = add i64 %indvars.iv, 1
652  %exitcond = icmp eq i64 %indvars.iv.next, %n
653  br i1 %exitcond, label %latchexit, label %header, !prof !{!"branch_weights", i64 1, i64 2}
654
655latchexit:                                          ; preds = %latch
656  %sum.0.lcssa = phi i32 [ %add, %latch ]
657  ret i32 %sum.0.lcssa
658
659otherexit:
660  ret i32 57
661}
662
663; A case noticed while writing test3 where changing the early exit condition
664; seems to inhibit unrolling for some unclear reason.
665define i32 @test4(i32* nocapture %a, i64 %n) !prof !{!"function_entry_count", i64 2048} {
666;
667; CHECK-LABEL: @test4(
668; CHECK-NEXT:  entry:
669; CHECK-NEXT:    br label [[HEADER:%.*]]
670; CHECK:       header:
671; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LATCH:%.*]] ], [ 0, [[ENTRY:%.*]] ]
672; CHECK-NEXT:    [[SUM_02:%.*]] = phi i32 [ [[ADD:%.*]], [[LATCH]] ], [ 0, [[ENTRY]] ]
673; CHECK-NEXT:    br label [[FOR_EXITING_BLOCK:%.*]]
674; CHECK:       for.exiting_block:
675; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i64 [[INDVARS_IV]], 4096
676; CHECK-NEXT:    br i1 [[CMP]], label [[OTHEREXIT:%.*]], label [[LATCH]]
677; CHECK:       latch:
678; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i64 [[INDVARS_IV]]
679; CHECK-NEXT:    [[TMP0:%.*]] = load i32, i32* [[ARRAYIDX]], align 4
680; CHECK-NEXT:    [[ADD]] = add nsw i32 [[TMP0]], [[SUM_02]]
681; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add i64 [[INDVARS_IV]], 1
682; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], [[N:%.*]]
683; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LATCHEXIT:%.*]], label [[HEADER]]
684; CHECK:       latchexit:
685; CHECK-NEXT:    ret i32 [[ADD]]
686; CHECK:       otherexit:
687; CHECK-NEXT:    ret i32 57
688;
689; NOUNROLL-LABEL: @test4(
690; NOUNROLL-NEXT:  entry:
691; NOUNROLL-NEXT:    br label [[HEADER:%.*]]
692; NOUNROLL:       header:
693; NOUNROLL-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LATCH:%.*]] ], [ 0, [[ENTRY:%.*]] ]
694; NOUNROLL-NEXT:    [[SUM_02:%.*]] = phi i32 [ [[ADD:%.*]], [[LATCH]] ], [ 0, [[ENTRY]] ]
695; NOUNROLL-NEXT:    br label [[FOR_EXITING_BLOCK:%.*]]
696; NOUNROLL:       for.exiting_block:
697; NOUNROLL-NEXT:    [[CMP:%.*]] = icmp eq i64 [[INDVARS_IV]], 4096
698; NOUNROLL-NEXT:    br i1 [[CMP]], label [[OTHEREXIT:%.*]], label [[LATCH]]
699; NOUNROLL:       latch:
700; NOUNROLL-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i64 [[INDVARS_IV]]
701; NOUNROLL-NEXT:    [[TMP0:%.*]] = load i32, i32* [[ARRAYIDX]], align 4
702; NOUNROLL-NEXT:    [[ADD]] = add nsw i32 [[TMP0]], [[SUM_02]]
703; NOUNROLL-NEXT:    [[INDVARS_IV_NEXT]] = add i64 [[INDVARS_IV]], 1
704; NOUNROLL-NEXT:    [[EXITCOND:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], [[N:%.*]]
705; NOUNROLL-NEXT:    br i1 [[EXITCOND]], label [[LATCHEXIT:%.*]], label [[HEADER]]
706; NOUNROLL:       latchexit:
707; NOUNROLL-NEXT:    [[SUM_0_LCSSA:%.*]] = phi i32 [ [[ADD]], [[LATCH]] ]
708; NOUNROLL-NEXT:    ret i32 [[SUM_0_LCSSA]]
709; NOUNROLL:       otherexit:
710; NOUNROLL-NEXT:    ret i32 57
711;
712; ENABLED-LABEL: @test4(
713; ENABLED-NEXT:  entry:
714; ENABLED-NEXT:    br label [[HEADER:%.*]]
715; ENABLED:       header:
716; ENABLED-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LATCH:%.*]] ], [ 0, [[ENTRY:%.*]] ]
717; ENABLED-NEXT:    [[SUM_02:%.*]] = phi i32 [ [[ADD:%.*]], [[LATCH]] ], [ 0, [[ENTRY]] ]
718; ENABLED-NEXT:    br label [[FOR_EXITING_BLOCK:%.*]]
719; ENABLED:       for.exiting_block:
720; ENABLED-NEXT:    [[CMP:%.*]] = icmp eq i64 [[INDVARS_IV]], 4096
721; ENABLED-NEXT:    br i1 [[CMP]], label [[OTHEREXIT:%.*]], label [[LATCH]]
722; ENABLED:       latch:
723; ENABLED-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i64 [[INDVARS_IV]]
724; ENABLED-NEXT:    [[TMP0:%.*]] = load i32, i32* [[ARRAYIDX]], align 4
725; ENABLED-NEXT:    [[ADD]] = add nsw i32 [[TMP0]], [[SUM_02]]
726; ENABLED-NEXT:    [[INDVARS_IV_NEXT]] = add i64 [[INDVARS_IV]], 1
727; ENABLED-NEXT:    [[EXITCOND:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], [[N:%.*]]
728; ENABLED-NEXT:    br i1 [[EXITCOND]], label [[LATCHEXIT:%.*]], label [[HEADER]]
729; ENABLED:       latchexit:
730; ENABLED-NEXT:    [[SUM_0_LCSSA:%.*]] = phi i32 [ [[ADD]], [[LATCH]] ]
731; ENABLED-NEXT:    ret i32 [[SUM_0_LCSSA]]
732; ENABLED:       otherexit:
733; ENABLED-NEXT:    ret i32 57
734;
735entry:
736  br label %header
737
738header:
739  %indvars.iv = phi i64 [ %indvars.iv.next, %latch ], [ 0, %entry ]
740  %sum.02 = phi i32 [ %add, %latch ], [ 0, %entry ]
741  br label %for.exiting_block
742
743for.exiting_block:
744  %cmp = icmp eq i64 %indvars.iv, 4096
745  br i1 %cmp, label %otherexit, label %latch
746
747latch:
748  %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
749  %0 = load i32, i32* %arrayidx, align 4
750  %add = add nsw i32 %0, %sum.02
751  %indvars.iv.next = add i64 %indvars.iv, 1
752  %exitcond = icmp eq i64 %indvars.iv.next, %n
753  br i1 %exitcond, label %latchexit, label %header
754
755latchexit:                                          ; preds = %latch
756  %sum.0.lcssa = phi i32 [ %add, %latch ]
757  ret i32 %sum.0.lcssa
758
759otherexit:
760  ret i32 57
761}
762
763
764
765declare i32 @llvm.experimental.deoptimize.i32(...)
766