xref: /llvm-project/llvm/test/Transforms/LoopUnroll/runtime-multiexit-heuristic.ll (revision eeb0884e6696ec618feb2181a432d10f66d4e840)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -unroll-runtime-other-exit-predictable=false -passes=loop-unroll,instcombine -unroll-runtime=true -verify-dom-info -verify-loop-info -S | FileCheck %s
3; RUN: opt < %s -unroll-runtime-other-exit-predictable=false -passes=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 -passes=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(ptr 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, ptr [[A:%.*]], i64 [[INDVARS_IV]]
36; CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
37; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[TMP3]], [[SUM_02]]
38; CHECK-NEXT:    [[INDVARS_IV_NEXT:%.*]] = or disjoint i64 [[INDVARS_IV]], 1
39; CHECK-NEXT:    br label [[FOR_EXITING_BLOCK_1:%.*]]
40; CHECK:       for.exiting_block.1:
41; CHECK-NEXT:    br i1 false, label [[OTHEREXIT_LOOPEXIT]], label [[LATCH_1:%.*]]
42; CHECK:       latch.1:
43; CHECK-NEXT:    [[ARRAYIDX_1:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[INDVARS_IV_NEXT]]
44; CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[ARRAYIDX_1]], align 4
45; CHECK-NEXT:    [[ADD_1:%.*]] = add nsw i32 [[TMP4]], [[ADD]]
46; CHECK-NEXT:    [[INDVARS_IV_NEXT_1:%.*]] = or disjoint i64 [[INDVARS_IV]], 2
47; CHECK-NEXT:    br label [[FOR_EXITING_BLOCK_2:%.*]]
48; CHECK:       for.exiting_block.2:
49; CHECK-NEXT:    br i1 false, label [[OTHEREXIT_LOOPEXIT]], label [[LATCH_2:%.*]]
50; CHECK:       latch.2:
51; CHECK-NEXT:    [[ARRAYIDX_2:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[INDVARS_IV_NEXT_1]]
52; CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[ARRAYIDX_2]], align 4
53; CHECK-NEXT:    [[ADD_2:%.*]] = add nsw i32 [[TMP5]], [[ADD_1]]
54; CHECK-NEXT:    [[INDVARS_IV_NEXT_2:%.*]] = or disjoint i64 [[INDVARS_IV]], 3
55; CHECK-NEXT:    br label [[FOR_EXITING_BLOCK_3:%.*]]
56; CHECK:       for.exiting_block.3:
57; CHECK-NEXT:    br i1 false, label [[OTHEREXIT_LOOPEXIT]], label [[LATCH_3:%.*]]
58; CHECK:       latch.3:
59; CHECK-NEXT:    [[ARRAYIDX_3:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[INDVARS_IV_NEXT_2]]
60; CHECK-NEXT:    [[TMP6:%.*]] = load i32, ptr [[ARRAYIDX_3]], align 4
61; CHECK-NEXT:    [[ADD_3:%.*]] = add nsw i32 [[TMP6]], [[ADD_2]]
62; CHECK-NEXT:    [[INDVARS_IV_NEXT_3:%.*]] = or disjoint i64 [[INDVARS_IV]], 4
63; CHECK-NEXT:    br label [[FOR_EXITING_BLOCK_4:%.*]]
64; CHECK:       for.exiting_block.4:
65; CHECK-NEXT:    br i1 false, label [[OTHEREXIT_LOOPEXIT]], label [[LATCH_4:%.*]]
66; CHECK:       latch.4:
67; CHECK-NEXT:    [[ARRAYIDX_4:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[INDVARS_IV_NEXT_3]]
68; CHECK-NEXT:    [[TMP7:%.*]] = load i32, ptr [[ARRAYIDX_4]], align 4
69; CHECK-NEXT:    [[ADD_4:%.*]] = add nsw i32 [[TMP7]], [[ADD_3]]
70; CHECK-NEXT:    [[INDVARS_IV_NEXT_4:%.*]] = or disjoint i64 [[INDVARS_IV]], 5
71; CHECK-NEXT:    br label [[FOR_EXITING_BLOCK_5:%.*]]
72; CHECK:       for.exiting_block.5:
73; CHECK-NEXT:    br i1 false, label [[OTHEREXIT_LOOPEXIT]], label [[LATCH_5:%.*]]
74; CHECK:       latch.5:
75; CHECK-NEXT:    [[ARRAYIDX_5:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[INDVARS_IV_NEXT_4]]
76; CHECK-NEXT:    [[TMP8:%.*]] = load i32, ptr [[ARRAYIDX_5]], align 4
77; CHECK-NEXT:    [[ADD_5:%.*]] = add nsw i32 [[TMP8]], [[ADD_4]]
78; CHECK-NEXT:    [[INDVARS_IV_NEXT_5:%.*]] = or disjoint i64 [[INDVARS_IV]], 6
79; CHECK-NEXT:    br label [[FOR_EXITING_BLOCK_6:%.*]]
80; CHECK:       for.exiting_block.6:
81; CHECK-NEXT:    br i1 false, label [[OTHEREXIT_LOOPEXIT]], label [[LATCH_6:%.*]]
82; CHECK:       latch.6:
83; CHECK-NEXT:    [[ARRAYIDX_6:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[INDVARS_IV_NEXT_5]]
84; CHECK-NEXT:    [[TMP9:%.*]] = load i32, ptr [[ARRAYIDX_6]], align 4
85; CHECK-NEXT:    [[ADD_6:%.*]] = add nsw i32 [[TMP9]], [[ADD_5]]
86; CHECK-NEXT:    [[INDVARS_IV_NEXT_6:%.*]] = or disjoint i64 [[INDVARS_IV]], 7
87; CHECK-NEXT:    br label [[FOR_EXITING_BLOCK_7:%.*]]
88; CHECK:       for.exiting_block.7:
89; CHECK-NEXT:    br i1 false, label [[OTHEREXIT_LOOPEXIT]], label [[LATCH_7]]
90; CHECK:       latch.7:
91; CHECK-NEXT:    [[ARRAYIDX_7:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[INDVARS_IV_NEXT_6]]
92; CHECK-NEXT:    [[TMP10:%.*]] = load i32, ptr [[ARRAYIDX_7]], align 4
93; CHECK-NEXT:    [[ADD_7]] = add nsw i32 [[TMP10]], [[ADD_6]]
94; CHECK-NEXT:    [[INDVARS_IV_NEXT_7]] = add i64 [[INDVARS_IV]], 8
95; CHECK-NEXT:    [[NITER_NEXT_7]] = add i64 [[NITER]], 8
96; CHECK-NEXT:    [[NITER_NCMP_7:%.*]] = icmp eq i64 [[NITER_NEXT_7]], [[UNROLL_ITER]]
97; CHECK-NEXT:    br i1 [[NITER_NCMP_7]], label [[LATCHEXIT_UNR_LCSSA_LOOPEXIT:%.*]], label [[HEADER]]
98; CHECK:       latchexit.unr-lcssa.loopexit:
99; CHECK-NEXT:    br label [[LATCHEXIT_UNR_LCSSA]]
100; CHECK:       latchexit.unr-lcssa:
101; CHECK-NEXT:    [[SUM_0_LCSSA_PH:%.*]] = phi i32 [ poison, [[ENTRY:%.*]] ], [ [[ADD_7]], [[LATCHEXIT_UNR_LCSSA_LOOPEXIT]] ]
102; CHECK-NEXT:    [[INDVARS_IV_UNR:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[INDVARS_IV_NEXT_7]], [[LATCHEXIT_UNR_LCSSA_LOOPEXIT]] ]
103; CHECK-NEXT:    [[SUM_02_UNR:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD_7]], [[LATCHEXIT_UNR_LCSSA_LOOPEXIT]] ]
104; CHECK-NEXT:    [[LCMP_MOD_NOT:%.*]] = icmp eq i64 [[XTRAITER]], 0
105; CHECK-NEXT:    br i1 [[LCMP_MOD_NOT]], label [[LATCHEXIT:%.*]], label [[HEADER_EPIL_PREHEADER:%.*]]
106; CHECK:       header.epil.preheader:
107; CHECK-NEXT:    br label [[HEADER_EPIL:%.*]]
108; CHECK:       header.epil:
109; CHECK-NEXT:    [[INDVARS_IV_EPIL:%.*]] = phi i64 [ [[INDVARS_IV_NEXT_EPIL:%.*]], [[LATCH_EPIL:%.*]] ], [ [[INDVARS_IV_UNR]], [[HEADER_EPIL_PREHEADER]] ]
110; CHECK-NEXT:    [[SUM_02_EPIL:%.*]] = phi i32 [ [[ADD_EPIL:%.*]], [[LATCH_EPIL]] ], [ [[SUM_02_UNR]], [[HEADER_EPIL_PREHEADER]] ]
111; CHECK-NEXT:    [[EPIL_ITER:%.*]] = phi i64 [ [[EPIL_ITER_NEXT:%.*]], [[LATCH_EPIL]] ], [ 0, [[HEADER_EPIL_PREHEADER]] ]
112; CHECK-NEXT:    br label [[FOR_EXITING_BLOCK_EPIL:%.*]]
113; CHECK:       for.exiting_block.epil:
114; CHECK-NEXT:    [[CMP_EPIL:%.*]] = icmp eq i64 [[TMP0]], 42
115; CHECK-NEXT:    br i1 [[CMP_EPIL]], label [[OTHEREXIT_LOOPEXIT3:%.*]], label [[LATCH_EPIL]]
116; CHECK:       latch.epil:
117; CHECK-NEXT:    [[ARRAYIDX_EPIL:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[INDVARS_IV_EPIL]]
118; CHECK-NEXT:    [[TMP11:%.*]] = load i32, ptr [[ARRAYIDX_EPIL]], align 4
119; CHECK-NEXT:    [[ADD_EPIL]] = add nsw i32 [[TMP11]], [[SUM_02_EPIL]]
120; CHECK-NEXT:    [[INDVARS_IV_NEXT_EPIL]] = add i64 [[INDVARS_IV_EPIL]], 1
121; CHECK-NEXT:    [[EPIL_ITER_NEXT]] = add i64 [[EPIL_ITER]], 1
122; CHECK-NEXT:    [[EPIL_ITER_CMP_NOT:%.*]] = icmp eq i64 [[EPIL_ITER_NEXT]], [[XTRAITER]]
123; CHECK-NEXT:    br i1 [[EPIL_ITER_CMP_NOT]], label [[LATCHEXIT_EPILOG_LCSSA:%.*]], label [[HEADER_EPIL]], !llvm.loop [[LOOP0:![0-9]+]]
124; CHECK:       latchexit.epilog-lcssa:
125; CHECK-NEXT:    br label [[LATCHEXIT]]
126; CHECK:       latchexit:
127; CHECK-NEXT:    [[SUM_0_LCSSA:%.*]] = phi i32 [ [[SUM_0_LCSSA_PH]], [[LATCHEXIT_UNR_LCSSA]] ], [ [[ADD_EPIL]], [[LATCHEXIT_EPILOG_LCSSA]] ]
128; CHECK-NEXT:    ret i32 [[SUM_0_LCSSA]]
129; CHECK:       otherexit.loopexit:
130; CHECK-NEXT:    br label [[OTHEREXIT:%.*]]
131; CHECK:       otherexit.loopexit3:
132; CHECK-NEXT:    br label [[OTHEREXIT]]
133; CHECK:       otherexit:
134; CHECK-NEXT:    [[SUM_02_LCSSA:%.*]] = phi i32 [ [[SUM_02]], [[OTHEREXIT_LOOPEXIT]] ], [ [[SUM_02_EPIL]], [[OTHEREXIT_LOOPEXIT3]] ]
135; CHECK-NEXT:    [[RVAL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"(i32 [[SUM_02_LCSSA]]) ]
136; CHECK-NEXT:    ret i32 [[RVAL]]
137;
138; NOUNROLL-LABEL: @test1(
139; NOUNROLL-NEXT:  entry:
140; NOUNROLL-NEXT:    br label [[HEADER:%.*]]
141; NOUNROLL:       header:
142; NOUNROLL-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LATCH:%.*]] ], [ 0, [[ENTRY:%.*]] ]
143; NOUNROLL-NEXT:    [[SUM_02:%.*]] = phi i32 [ [[ADD:%.*]], [[LATCH]] ], [ 0, [[ENTRY]] ]
144; NOUNROLL-NEXT:    br label [[FOR_EXITING_BLOCK:%.*]]
145; NOUNROLL:       for.exiting_block:
146; NOUNROLL-NEXT:    [[CMP:%.*]] = icmp eq i64 [[N:%.*]], 42
147; NOUNROLL-NEXT:    br i1 [[CMP]], label [[OTHEREXIT:%.*]], label [[LATCH]]
148; NOUNROLL:       latch:
149; NOUNROLL-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]]
150; NOUNROLL-NEXT:    [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
151; NOUNROLL-NEXT:    [[ADD]] = add nsw i32 [[TMP0]], [[SUM_02]]
152; NOUNROLL-NEXT:    [[INDVARS_IV_NEXT]] = add i64 [[INDVARS_IV]], 1
153; NOUNROLL-NEXT:    [[EXITCOND:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], [[N]]
154; NOUNROLL-NEXT:    br i1 [[EXITCOND]], label [[LATCHEXIT:%.*]], label [[HEADER]]
155; NOUNROLL:       latchexit:
156; NOUNROLL-NEXT:    [[SUM_0_LCSSA:%.*]] = phi i32 [ [[ADD]], [[LATCH]] ]
157; NOUNROLL-NEXT:    ret i32 [[SUM_0_LCSSA]]
158; NOUNROLL:       otherexit:
159; NOUNROLL-NEXT:    [[SUM_02_LCSSA:%.*]] = phi i32 [ [[SUM_02]], [[FOR_EXITING_BLOCK]] ]
160; NOUNROLL-NEXT:    [[RVAL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"(i32 [[SUM_02_LCSSA]]) ]
161; NOUNROLL-NEXT:    ret i32 [[RVAL]]
162;
163; ENABLED-LABEL: @test1(
164; ENABLED-NEXT:  entry:
165; ENABLED-NEXT:    [[TMP0:%.*]] = freeze i64 [[N:%.*]]
166; ENABLED-NEXT:    [[TMP1:%.*]] = add i64 [[TMP0]], -1
167; ENABLED-NEXT:    [[XTRAITER:%.*]] = and i64 [[TMP0]], 7
168; ENABLED-NEXT:    [[TMP2:%.*]] = icmp ult i64 [[TMP1]], 7
169; ENABLED-NEXT:    br i1 [[TMP2]], label [[LATCHEXIT_UNR_LCSSA:%.*]], label [[ENTRY_NEW:%.*]]
170; ENABLED:       entry.new:
171; ENABLED-NEXT:    [[UNROLL_ITER:%.*]] = sub i64 [[TMP0]], [[XTRAITER]]
172; ENABLED-NEXT:    br label [[HEADER:%.*]]
173; ENABLED:       header:
174; ENABLED-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY_NEW]] ], [ [[INDVARS_IV_NEXT_7:%.*]], [[LATCH_7:%.*]] ]
175; ENABLED-NEXT:    [[SUM_02:%.*]] = phi i32 [ 0, [[ENTRY_NEW]] ], [ [[ADD_7:%.*]], [[LATCH_7]] ]
176; ENABLED-NEXT:    [[NITER:%.*]] = phi i64 [ 0, [[ENTRY_NEW]] ], [ [[NITER_NEXT_7:%.*]], [[LATCH_7]] ]
177; ENABLED-NEXT:    br label [[FOR_EXITING_BLOCK:%.*]]
178; ENABLED:       for.exiting_block:
179; ENABLED-NEXT:    [[CMP:%.*]] = icmp eq i64 [[N]], 42
180; ENABLED-NEXT:    br i1 [[CMP]], label [[OTHEREXIT_LOOPEXIT:%.*]], label [[LATCH:%.*]]
181; ENABLED:       latch:
182; ENABLED-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]]
183; ENABLED-NEXT:    [[TMP3:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
184; ENABLED-NEXT:    [[ADD:%.*]] = add nsw i32 [[TMP3]], [[SUM_02]]
185; ENABLED-NEXT:    [[INDVARS_IV_NEXT:%.*]] = add nuw nsw i64 [[INDVARS_IV]], 1
186; ENABLED-NEXT:    br label [[FOR_EXITING_BLOCK_1:%.*]]
187; ENABLED:       for.exiting_block.1:
188; ENABLED-NEXT:    [[CMP_1:%.*]] = icmp eq i64 [[N]], 42
189; ENABLED-NEXT:    br i1 [[CMP_1]], label [[OTHEREXIT_LOOPEXIT]], label [[LATCH_1:%.*]]
190; ENABLED:       latch.1:
191; ENABLED-NEXT:    [[ARRAYIDX_1:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[INDVARS_IV_NEXT]]
192; ENABLED-NEXT:    [[TMP4:%.*]] = load i32, ptr [[ARRAYIDX_1]], align 4
193; ENABLED-NEXT:    [[ADD_1:%.*]] = add nsw i32 [[TMP4]], [[ADD]]
194; ENABLED-NEXT:    [[INDVARS_IV_NEXT_1:%.*]] = add nuw nsw i64 [[INDVARS_IV]], 2
195; ENABLED-NEXT:    br label [[FOR_EXITING_BLOCK_2:%.*]]
196; ENABLED:       for.exiting_block.2:
197; ENABLED-NEXT:    [[CMP_2:%.*]] = icmp eq i64 [[N]], 42
198; ENABLED-NEXT:    br i1 [[CMP_2]], label [[OTHEREXIT_LOOPEXIT]], label [[LATCH_2:%.*]]
199; ENABLED:       latch.2:
200; ENABLED-NEXT:    [[ARRAYIDX_2:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[INDVARS_IV_NEXT_1]]
201; ENABLED-NEXT:    [[TMP5:%.*]] = load i32, ptr [[ARRAYIDX_2]], align 4
202; ENABLED-NEXT:    [[ADD_2:%.*]] = add nsw i32 [[TMP5]], [[ADD_1]]
203; ENABLED-NEXT:    [[INDVARS_IV_NEXT_2:%.*]] = add nuw nsw i64 [[INDVARS_IV]], 3
204; ENABLED-NEXT:    br label [[FOR_EXITING_BLOCK_3:%.*]]
205; ENABLED:       for.exiting_block.3:
206; ENABLED-NEXT:    [[CMP_3:%.*]] = icmp eq i64 [[N]], 42
207; ENABLED-NEXT:    br i1 [[CMP_3]], label [[OTHEREXIT_LOOPEXIT]], label [[LATCH_3:%.*]]
208; ENABLED:       latch.3:
209; ENABLED-NEXT:    [[ARRAYIDX_3:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[INDVARS_IV_NEXT_2]]
210; ENABLED-NEXT:    [[TMP6:%.*]] = load i32, ptr [[ARRAYIDX_3]], align 4
211; ENABLED-NEXT:    [[ADD_3:%.*]] = add nsw i32 [[TMP6]], [[ADD_2]]
212; ENABLED-NEXT:    [[INDVARS_IV_NEXT_3:%.*]] = add nuw nsw i64 [[INDVARS_IV]], 4
213; ENABLED-NEXT:    br label [[FOR_EXITING_BLOCK_4:%.*]]
214; ENABLED:       for.exiting_block.4:
215; ENABLED-NEXT:    [[CMP_4:%.*]] = icmp eq i64 [[N]], 42
216; ENABLED-NEXT:    br i1 [[CMP_4]], label [[OTHEREXIT_LOOPEXIT]], label [[LATCH_4:%.*]]
217; ENABLED:       latch.4:
218; ENABLED-NEXT:    [[ARRAYIDX_4:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[INDVARS_IV_NEXT_3]]
219; ENABLED-NEXT:    [[TMP7:%.*]] = load i32, ptr [[ARRAYIDX_4]], align 4
220; ENABLED-NEXT:    [[ADD_4:%.*]] = add nsw i32 [[TMP7]], [[ADD_3]]
221; ENABLED-NEXT:    [[INDVARS_IV_NEXT_4:%.*]] = add nuw nsw i64 [[INDVARS_IV]], 5
222; ENABLED-NEXT:    br label [[FOR_EXITING_BLOCK_5:%.*]]
223; ENABLED:       for.exiting_block.5:
224; ENABLED-NEXT:    [[CMP_5:%.*]] = icmp eq i64 [[N]], 42
225; ENABLED-NEXT:    br i1 [[CMP_5]], label [[OTHEREXIT_LOOPEXIT]], label [[LATCH_5:%.*]]
226; ENABLED:       latch.5:
227; ENABLED-NEXT:    [[ARRAYIDX_5:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[INDVARS_IV_NEXT_4]]
228; ENABLED-NEXT:    [[TMP8:%.*]] = load i32, ptr [[ARRAYIDX_5]], align 4
229; ENABLED-NEXT:    [[ADD_5:%.*]] = add nsw i32 [[TMP8]], [[ADD_4]]
230; ENABLED-NEXT:    [[INDVARS_IV_NEXT_5:%.*]] = add nuw nsw i64 [[INDVARS_IV]], 6
231; ENABLED-NEXT:    br label [[FOR_EXITING_BLOCK_6:%.*]]
232; ENABLED:       for.exiting_block.6:
233; ENABLED-NEXT:    [[CMP_6:%.*]] = icmp eq i64 [[N]], 42
234; ENABLED-NEXT:    br i1 [[CMP_6]], label [[OTHEREXIT_LOOPEXIT]], label [[LATCH_6:%.*]]
235; ENABLED:       latch.6:
236; ENABLED-NEXT:    [[ARRAYIDX_6:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[INDVARS_IV_NEXT_5]]
237; ENABLED-NEXT:    [[TMP9:%.*]] = load i32, ptr [[ARRAYIDX_6]], align 4
238; ENABLED-NEXT:    [[ADD_6:%.*]] = add nsw i32 [[TMP9]], [[ADD_5]]
239; ENABLED-NEXT:    [[INDVARS_IV_NEXT_6:%.*]] = add nuw nsw i64 [[INDVARS_IV]], 7
240; ENABLED-NEXT:    br label [[FOR_EXITING_BLOCK_7:%.*]]
241; ENABLED:       for.exiting_block.7:
242; ENABLED-NEXT:    [[CMP_7:%.*]] = icmp eq i64 [[N]], 42
243; ENABLED-NEXT:    br i1 [[CMP_7]], label [[OTHEREXIT_LOOPEXIT]], label [[LATCH_7]]
244; ENABLED:       latch.7:
245; ENABLED-NEXT:    [[ARRAYIDX_7:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[INDVARS_IV_NEXT_6]]
246; ENABLED-NEXT:    [[TMP10:%.*]] = load i32, ptr [[ARRAYIDX_7]], align 4
247; ENABLED-NEXT:    [[ADD_7]] = add nsw i32 [[TMP10]], [[ADD_6]]
248; ENABLED-NEXT:    [[INDVARS_IV_NEXT_7]] = add i64 [[INDVARS_IV]], 8
249; ENABLED-NEXT:    [[NITER_NEXT_7]] = add i64 [[NITER]], 8
250; ENABLED-NEXT:    [[NITER_NCMP_7:%.*]] = icmp eq i64 [[NITER_NEXT_7]], [[UNROLL_ITER]]
251; ENABLED-NEXT:    br i1 [[NITER_NCMP_7]], label [[LATCHEXIT_UNR_LCSSA_LOOPEXIT:%.*]], label [[HEADER]]
252; ENABLED:       latchexit.unr-lcssa.loopexit:
253; ENABLED-NEXT:    [[SUM_0_LCSSA_PH_PH:%.*]] = phi i32 [ [[ADD_7]], [[LATCH_7]] ]
254; ENABLED-NEXT:    [[INDVARS_IV_UNR_PH:%.*]] = phi i64 [ [[INDVARS_IV_NEXT_7]], [[LATCH_7]] ]
255; ENABLED-NEXT:    [[SUM_02_UNR_PH:%.*]] = phi i32 [ [[ADD_7]], [[LATCH_7]] ]
256; ENABLED-NEXT:    br label [[LATCHEXIT_UNR_LCSSA]]
257; ENABLED:       latchexit.unr-lcssa:
258; ENABLED-NEXT:    [[SUM_0_LCSSA_PH:%.*]] = phi i32 [ poison, [[ENTRY:%.*]] ], [ [[SUM_0_LCSSA_PH_PH]], [[LATCHEXIT_UNR_LCSSA_LOOPEXIT]] ]
259; ENABLED-NEXT:    [[INDVARS_IV_UNR:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[INDVARS_IV_UNR_PH]], [[LATCHEXIT_UNR_LCSSA_LOOPEXIT]] ]
260; ENABLED-NEXT:    [[SUM_02_UNR:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[SUM_02_UNR_PH]], [[LATCHEXIT_UNR_LCSSA_LOOPEXIT]] ]
261; ENABLED-NEXT:    [[LCMP_MOD:%.*]] = icmp ne i64 [[XTRAITER]], 0
262; ENABLED-NEXT:    br i1 [[LCMP_MOD]], label [[HEADER_EPIL_PREHEADER:%.*]], label [[LATCHEXIT:%.*]]
263; ENABLED:       header.epil.preheader:
264; ENABLED-NEXT:    br label [[HEADER_EPIL:%.*]]
265; ENABLED:       header.epil:
266; ENABLED-NEXT:    [[INDVARS_IV_EPIL:%.*]] = phi i64 [ [[INDVARS_IV_NEXT_EPIL:%.*]], [[LATCH_EPIL:%.*]] ], [ [[INDVARS_IV_UNR]], [[HEADER_EPIL_PREHEADER]] ]
267; ENABLED-NEXT:    [[SUM_02_EPIL:%.*]] = phi i32 [ [[ADD_EPIL:%.*]], [[LATCH_EPIL]] ], [ [[SUM_02_UNR]], [[HEADER_EPIL_PREHEADER]] ]
268; ENABLED-NEXT:    [[EPIL_ITER:%.*]] = phi i64 [ 0, [[HEADER_EPIL_PREHEADER]] ], [ [[EPIL_ITER_NEXT:%.*]], [[LATCH_EPIL]] ]
269; ENABLED-NEXT:    br label [[FOR_EXITING_BLOCK_EPIL:%.*]]
270; ENABLED:       for.exiting_block.epil:
271; ENABLED-NEXT:    [[CMP_EPIL:%.*]] = icmp eq i64 [[N]], 42
272; ENABLED-NEXT:    br i1 [[CMP_EPIL]], label [[OTHEREXIT_LOOPEXIT3:%.*]], label [[LATCH_EPIL]]
273; ENABLED:       latch.epil:
274; ENABLED-NEXT:    [[ARRAYIDX_EPIL:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[INDVARS_IV_EPIL]]
275; ENABLED-NEXT:    [[TMP11:%.*]] = load i32, ptr [[ARRAYIDX_EPIL]], align 4
276; ENABLED-NEXT:    [[ADD_EPIL]] = add nsw i32 [[TMP11]], [[SUM_02_EPIL]]
277; ENABLED-NEXT:    [[INDVARS_IV_NEXT_EPIL]] = add i64 [[INDVARS_IV_EPIL]], 1
278; ENABLED-NEXT:    [[EXITCOND_EPIL:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT_EPIL]], [[N]]
279; ENABLED-NEXT:    [[EPIL_ITER_NEXT]] = add i64 [[EPIL_ITER]], 1
280; ENABLED-NEXT:    [[EPIL_ITER_CMP:%.*]] = icmp ne i64 [[EPIL_ITER_NEXT]], [[XTRAITER]]
281; ENABLED-NEXT:    br i1 [[EPIL_ITER_CMP]], label [[HEADER_EPIL]], label [[LATCHEXIT_EPILOG_LCSSA:%.*]], !llvm.loop [[LOOP0:![0-9]+]]
282; ENABLED:       latchexit.epilog-lcssa:
283; ENABLED-NEXT:    [[SUM_0_LCSSA_PH2:%.*]] = phi i32 [ [[ADD_EPIL]], [[LATCH_EPIL]] ]
284; ENABLED-NEXT:    br label [[LATCHEXIT]]
285; ENABLED:       latchexit:
286; ENABLED-NEXT:    [[SUM_0_LCSSA:%.*]] = phi i32 [ [[SUM_0_LCSSA_PH]], [[LATCHEXIT_UNR_LCSSA]] ], [ [[SUM_0_LCSSA_PH2]], [[LATCHEXIT_EPILOG_LCSSA]] ]
287; ENABLED-NEXT:    ret i32 [[SUM_0_LCSSA]]
288; ENABLED:       otherexit.loopexit:
289; 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]] ]
290; ENABLED-NEXT:    br label [[OTHEREXIT:%.*]]
291; ENABLED:       otherexit.loopexit3:
292; ENABLED-NEXT:    [[SUM_02_LCSSA_PH4:%.*]] = phi i32 [ [[SUM_02_EPIL]], [[FOR_EXITING_BLOCK_EPIL]] ]
293; ENABLED-NEXT:    br label [[OTHEREXIT]]
294; ENABLED:       otherexit:
295; ENABLED-NEXT:    [[SUM_02_LCSSA:%.*]] = phi i32 [ [[SUM_02_LCSSA_PH]], [[OTHEREXIT_LOOPEXIT]] ], [ [[SUM_02_LCSSA_PH4]], [[OTHEREXIT_LOOPEXIT3]] ]
296; ENABLED-NEXT:    [[RVAL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"(i32 [[SUM_02_LCSSA]]) ]
297; ENABLED-NEXT:    ret i32 [[RVAL]]
298;
299entry:
300  br label %header
301
302header:
303  %indvars.iv = phi i64 [ %indvars.iv.next, %latch ], [ 0, %entry ]
304  %sum.02 = phi i32 [ %add, %latch ], [ 0, %entry ]
305  br label %for.exiting_block
306
307for.exiting_block:
308  %cmp = icmp eq i64 %n, 42
309  br i1 %cmp, label %otherexit, label %latch
310
311latch:
312  %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv
313  %0 = load i32, ptr %arrayidx, align 4
314  %add = add nsw i32 %0, %sum.02
315  %indvars.iv.next = add i64 %indvars.iv, 1
316  %exitcond = icmp eq i64 %indvars.iv.next, %n
317  br i1 %exitcond, label %latchexit, label %header
318
319latchexit:                                          ; preds = %latch
320  %sum.0.lcssa = phi i32 [ %add, %latch ]
321  ret i32 %sum.0.lcssa
322
323otherexit:
324  %rval = call i32(...) @llvm.experimental.deoptimize.i32() [ "deopt"(i32 %sum.02) ]
325  ret i32 %rval
326}
327
328; the exit block is not a deopt block.
329define i32 @test2(ptr nocapture %a, i64 %n) {
330;
331; CHECK-LABEL: @test2(
332; CHECK-NEXT:  entry:
333; CHECK-NEXT:    br label [[HEADER:%.*]]
334; CHECK:       header:
335; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LATCH:%.*]] ], [ 0, [[ENTRY:%.*]] ]
336; CHECK-NEXT:    [[SUM_02:%.*]] = phi i32 [ [[ADD:%.*]], [[LATCH]] ], [ 0, [[ENTRY]] ]
337; CHECK-NEXT:    br label [[FOR_EXITING_BLOCK:%.*]]
338; CHECK:       for.exiting_block:
339; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i64 [[N:%.*]], 42
340; CHECK-NEXT:    br i1 [[CMP]], label [[OTHEREXIT:%.*]], label [[LATCH]]
341; CHECK:       latch:
342; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]]
343; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
344; CHECK-NEXT:    [[ADD]] = add nsw i32 [[TMP0]], [[SUM_02]]
345; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add i64 [[INDVARS_IV]], 1
346; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], [[N]]
347; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LATCHEXIT:%.*]], label [[HEADER]]
348; CHECK:       latchexit:
349; CHECK-NEXT:    ret i32 [[ADD]]
350; CHECK:       otherexit:
351; CHECK-NEXT:    ret i32 [[SUM_02]]
352;
353; NOUNROLL-LABEL: @test2(
354; NOUNROLL-NEXT:  entry:
355; NOUNROLL-NEXT:    br label [[HEADER:%.*]]
356; NOUNROLL:       header:
357; NOUNROLL-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LATCH:%.*]] ], [ 0, [[ENTRY:%.*]] ]
358; NOUNROLL-NEXT:    [[SUM_02:%.*]] = phi i32 [ [[ADD:%.*]], [[LATCH]] ], [ 0, [[ENTRY]] ]
359; NOUNROLL-NEXT:    br label [[FOR_EXITING_BLOCK:%.*]]
360; NOUNROLL:       for.exiting_block:
361; NOUNROLL-NEXT:    [[CMP:%.*]] = icmp eq i64 [[N:%.*]], 42
362; NOUNROLL-NEXT:    br i1 [[CMP]], label [[OTHEREXIT:%.*]], label [[LATCH]]
363; NOUNROLL:       latch:
364; NOUNROLL-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]]
365; NOUNROLL-NEXT:    [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
366; NOUNROLL-NEXT:    [[ADD]] = add nsw i32 [[TMP0]], [[SUM_02]]
367; NOUNROLL-NEXT:    [[INDVARS_IV_NEXT]] = add i64 [[INDVARS_IV]], 1
368; NOUNROLL-NEXT:    [[EXITCOND:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], [[N]]
369; NOUNROLL-NEXT:    br i1 [[EXITCOND]], label [[LATCHEXIT:%.*]], label [[HEADER]]
370; NOUNROLL:       latchexit:
371; NOUNROLL-NEXT:    [[SUM_0_LCSSA:%.*]] = phi i32 [ [[ADD]], [[LATCH]] ]
372; NOUNROLL-NEXT:    ret i32 [[SUM_0_LCSSA]]
373; NOUNROLL:       otherexit:
374; NOUNROLL-NEXT:    [[RVAL:%.*]] = phi i32 [ [[SUM_02]], [[FOR_EXITING_BLOCK]] ]
375; NOUNROLL-NEXT:    ret i32 [[RVAL]]
376;
377; ENABLED-LABEL: @test2(
378; ENABLED-NEXT:  entry:
379; ENABLED-NEXT:    [[TMP0:%.*]] = freeze i64 [[N:%.*]]
380; ENABLED-NEXT:    [[TMP1:%.*]] = add i64 [[TMP0]], -1
381; ENABLED-NEXT:    [[XTRAITER:%.*]] = and i64 [[TMP0]], 7
382; ENABLED-NEXT:    [[TMP2:%.*]] = icmp ult i64 [[TMP1]], 7
383; ENABLED-NEXT:    br i1 [[TMP2]], label [[LATCHEXIT_UNR_LCSSA:%.*]], label [[ENTRY_NEW:%.*]]
384; ENABLED:       entry.new:
385; ENABLED-NEXT:    [[UNROLL_ITER:%.*]] = sub i64 [[TMP0]], [[XTRAITER]]
386; ENABLED-NEXT:    br label [[HEADER:%.*]]
387; ENABLED:       header:
388; ENABLED-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY_NEW]] ], [ [[INDVARS_IV_NEXT_7:%.*]], [[LATCH_7:%.*]] ]
389; ENABLED-NEXT:    [[SUM_02:%.*]] = phi i32 [ 0, [[ENTRY_NEW]] ], [ [[ADD_7:%.*]], [[LATCH_7]] ]
390; ENABLED-NEXT:    [[NITER:%.*]] = phi i64 [ 0, [[ENTRY_NEW]] ], [ [[NITER_NEXT_7:%.*]], [[LATCH_7]] ]
391; ENABLED-NEXT:    br label [[FOR_EXITING_BLOCK:%.*]]
392; ENABLED:       for.exiting_block:
393; ENABLED-NEXT:    [[CMP:%.*]] = icmp eq i64 [[N]], 42
394; ENABLED-NEXT:    br i1 [[CMP]], label [[OTHEREXIT_LOOPEXIT:%.*]], label [[LATCH:%.*]]
395; ENABLED:       latch:
396; ENABLED-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]]
397; ENABLED-NEXT:    [[TMP3:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
398; ENABLED-NEXT:    [[ADD:%.*]] = add nsw i32 [[TMP3]], [[SUM_02]]
399; ENABLED-NEXT:    [[INDVARS_IV_NEXT:%.*]] = add nuw nsw i64 [[INDVARS_IV]], 1
400; ENABLED-NEXT:    br label [[FOR_EXITING_BLOCK_1:%.*]]
401; ENABLED:       for.exiting_block.1:
402; ENABLED-NEXT:    [[CMP_1:%.*]] = icmp eq i64 [[N]], 42
403; ENABLED-NEXT:    br i1 [[CMP_1]], label [[OTHEREXIT_LOOPEXIT]], label [[LATCH_1:%.*]]
404; ENABLED:       latch.1:
405; ENABLED-NEXT:    [[ARRAYIDX_1:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[INDVARS_IV_NEXT]]
406; ENABLED-NEXT:    [[TMP4:%.*]] = load i32, ptr [[ARRAYIDX_1]], align 4
407; ENABLED-NEXT:    [[ADD_1:%.*]] = add nsw i32 [[TMP4]], [[ADD]]
408; ENABLED-NEXT:    [[INDVARS_IV_NEXT_1:%.*]] = add nuw nsw i64 [[INDVARS_IV]], 2
409; ENABLED-NEXT:    br label [[FOR_EXITING_BLOCK_2:%.*]]
410; ENABLED:       for.exiting_block.2:
411; ENABLED-NEXT:    [[CMP_2:%.*]] = icmp eq i64 [[N]], 42
412; ENABLED-NEXT:    br i1 [[CMP_2]], label [[OTHEREXIT_LOOPEXIT]], label [[LATCH_2:%.*]]
413; ENABLED:       latch.2:
414; ENABLED-NEXT:    [[ARRAYIDX_2:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[INDVARS_IV_NEXT_1]]
415; ENABLED-NEXT:    [[TMP5:%.*]] = load i32, ptr [[ARRAYIDX_2]], align 4
416; ENABLED-NEXT:    [[ADD_2:%.*]] = add nsw i32 [[TMP5]], [[ADD_1]]
417; ENABLED-NEXT:    [[INDVARS_IV_NEXT_2:%.*]] = add nuw nsw i64 [[INDVARS_IV]], 3
418; ENABLED-NEXT:    br label [[FOR_EXITING_BLOCK_3:%.*]]
419; ENABLED:       for.exiting_block.3:
420; ENABLED-NEXT:    [[CMP_3:%.*]] = icmp eq i64 [[N]], 42
421; ENABLED-NEXT:    br i1 [[CMP_3]], label [[OTHEREXIT_LOOPEXIT]], label [[LATCH_3:%.*]]
422; ENABLED:       latch.3:
423; ENABLED-NEXT:    [[ARRAYIDX_3:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[INDVARS_IV_NEXT_2]]
424; ENABLED-NEXT:    [[TMP6:%.*]] = load i32, ptr [[ARRAYIDX_3]], align 4
425; ENABLED-NEXT:    [[ADD_3:%.*]] = add nsw i32 [[TMP6]], [[ADD_2]]
426; ENABLED-NEXT:    [[INDVARS_IV_NEXT_3:%.*]] = add nuw nsw i64 [[INDVARS_IV]], 4
427; ENABLED-NEXT:    br label [[FOR_EXITING_BLOCK_4:%.*]]
428; ENABLED:       for.exiting_block.4:
429; ENABLED-NEXT:    [[CMP_4:%.*]] = icmp eq i64 [[N]], 42
430; ENABLED-NEXT:    br i1 [[CMP_4]], label [[OTHEREXIT_LOOPEXIT]], label [[LATCH_4:%.*]]
431; ENABLED:       latch.4:
432; ENABLED-NEXT:    [[ARRAYIDX_4:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[INDVARS_IV_NEXT_3]]
433; ENABLED-NEXT:    [[TMP7:%.*]] = load i32, ptr [[ARRAYIDX_4]], align 4
434; ENABLED-NEXT:    [[ADD_4:%.*]] = add nsw i32 [[TMP7]], [[ADD_3]]
435; ENABLED-NEXT:    [[INDVARS_IV_NEXT_4:%.*]] = add nuw nsw i64 [[INDVARS_IV]], 5
436; ENABLED-NEXT:    br label [[FOR_EXITING_BLOCK_5:%.*]]
437; ENABLED:       for.exiting_block.5:
438; ENABLED-NEXT:    [[CMP_5:%.*]] = icmp eq i64 [[N]], 42
439; ENABLED-NEXT:    br i1 [[CMP_5]], label [[OTHEREXIT_LOOPEXIT]], label [[LATCH_5:%.*]]
440; ENABLED:       latch.5:
441; ENABLED-NEXT:    [[ARRAYIDX_5:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[INDVARS_IV_NEXT_4]]
442; ENABLED-NEXT:    [[TMP8:%.*]] = load i32, ptr [[ARRAYIDX_5]], align 4
443; ENABLED-NEXT:    [[ADD_5:%.*]] = add nsw i32 [[TMP8]], [[ADD_4]]
444; ENABLED-NEXT:    [[INDVARS_IV_NEXT_5:%.*]] = add nuw nsw i64 [[INDVARS_IV]], 6
445; ENABLED-NEXT:    br label [[FOR_EXITING_BLOCK_6:%.*]]
446; ENABLED:       for.exiting_block.6:
447; ENABLED-NEXT:    [[CMP_6:%.*]] = icmp eq i64 [[N]], 42
448; ENABLED-NEXT:    br i1 [[CMP_6]], label [[OTHEREXIT_LOOPEXIT]], label [[LATCH_6:%.*]]
449; ENABLED:       latch.6:
450; ENABLED-NEXT:    [[ARRAYIDX_6:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[INDVARS_IV_NEXT_5]]
451; ENABLED-NEXT:    [[TMP9:%.*]] = load i32, ptr [[ARRAYIDX_6]], align 4
452; ENABLED-NEXT:    [[ADD_6:%.*]] = add nsw i32 [[TMP9]], [[ADD_5]]
453; ENABLED-NEXT:    [[INDVARS_IV_NEXT_6:%.*]] = add nuw nsw i64 [[INDVARS_IV]], 7
454; ENABLED-NEXT:    br label [[FOR_EXITING_BLOCK_7:%.*]]
455; ENABLED:       for.exiting_block.7:
456; ENABLED-NEXT:    [[CMP_7:%.*]] = icmp eq i64 [[N]], 42
457; ENABLED-NEXT:    br i1 [[CMP_7]], label [[OTHEREXIT_LOOPEXIT]], label [[LATCH_7]]
458; ENABLED:       latch.7:
459; ENABLED-NEXT:    [[ARRAYIDX_7:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[INDVARS_IV_NEXT_6]]
460; ENABLED-NEXT:    [[TMP10:%.*]] = load i32, ptr [[ARRAYIDX_7]], align 4
461; ENABLED-NEXT:    [[ADD_7]] = add nsw i32 [[TMP10]], [[ADD_6]]
462; ENABLED-NEXT:    [[INDVARS_IV_NEXT_7]] = add i64 [[INDVARS_IV]], 8
463; ENABLED-NEXT:    [[NITER_NEXT_7]] = add i64 [[NITER]], 8
464; ENABLED-NEXT:    [[NITER_NCMP_7:%.*]] = icmp eq i64 [[NITER_NEXT_7]], [[UNROLL_ITER]]
465; ENABLED-NEXT:    br i1 [[NITER_NCMP_7]], label [[LATCHEXIT_UNR_LCSSA_LOOPEXIT:%.*]], label [[HEADER]]
466; ENABLED:       latchexit.unr-lcssa.loopexit:
467; ENABLED-NEXT:    [[SUM_0_LCSSA_PH_PH:%.*]] = phi i32 [ [[ADD_7]], [[LATCH_7]] ]
468; ENABLED-NEXT:    [[INDVARS_IV_UNR_PH:%.*]] = phi i64 [ [[INDVARS_IV_NEXT_7]], [[LATCH_7]] ]
469; ENABLED-NEXT:    [[SUM_02_UNR_PH:%.*]] = phi i32 [ [[ADD_7]], [[LATCH_7]] ]
470; ENABLED-NEXT:    br label [[LATCHEXIT_UNR_LCSSA]]
471; ENABLED:       latchexit.unr-lcssa:
472; ENABLED-NEXT:    [[SUM_0_LCSSA_PH:%.*]] = phi i32 [ poison, [[ENTRY:%.*]] ], [ [[SUM_0_LCSSA_PH_PH]], [[LATCHEXIT_UNR_LCSSA_LOOPEXIT]] ]
473; ENABLED-NEXT:    [[INDVARS_IV_UNR:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[INDVARS_IV_UNR_PH]], [[LATCHEXIT_UNR_LCSSA_LOOPEXIT]] ]
474; ENABLED-NEXT:    [[SUM_02_UNR:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[SUM_02_UNR_PH]], [[LATCHEXIT_UNR_LCSSA_LOOPEXIT]] ]
475; ENABLED-NEXT:    [[LCMP_MOD:%.*]] = icmp ne i64 [[XTRAITER]], 0
476; ENABLED-NEXT:    br i1 [[LCMP_MOD]], label [[HEADER_EPIL_PREHEADER:%.*]], label [[LATCHEXIT:%.*]]
477; ENABLED:       header.epil.preheader:
478; ENABLED-NEXT:    br label [[HEADER_EPIL:%.*]]
479; ENABLED:       header.epil:
480; ENABLED-NEXT:    [[INDVARS_IV_EPIL:%.*]] = phi i64 [ [[INDVARS_IV_NEXT_EPIL:%.*]], [[LATCH_EPIL:%.*]] ], [ [[INDVARS_IV_UNR]], [[HEADER_EPIL_PREHEADER]] ]
481; ENABLED-NEXT:    [[SUM_02_EPIL:%.*]] = phi i32 [ [[ADD_EPIL:%.*]], [[LATCH_EPIL]] ], [ [[SUM_02_UNR]], [[HEADER_EPIL_PREHEADER]] ]
482; ENABLED-NEXT:    [[EPIL_ITER:%.*]] = phi i64 [ 0, [[HEADER_EPIL_PREHEADER]] ], [ [[EPIL_ITER_NEXT:%.*]], [[LATCH_EPIL]] ]
483; ENABLED-NEXT:    br label [[FOR_EXITING_BLOCK_EPIL:%.*]]
484; ENABLED:       for.exiting_block.epil:
485; ENABLED-NEXT:    [[CMP_EPIL:%.*]] = icmp eq i64 [[N]], 42
486; ENABLED-NEXT:    br i1 [[CMP_EPIL]], label [[OTHEREXIT_LOOPEXIT2:%.*]], label [[LATCH_EPIL]]
487; ENABLED:       latch.epil:
488; ENABLED-NEXT:    [[ARRAYIDX_EPIL:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[INDVARS_IV_EPIL]]
489; ENABLED-NEXT:    [[TMP11:%.*]] = load i32, ptr [[ARRAYIDX_EPIL]], align 4
490; ENABLED-NEXT:    [[ADD_EPIL]] = add nsw i32 [[TMP11]], [[SUM_02_EPIL]]
491; ENABLED-NEXT:    [[INDVARS_IV_NEXT_EPIL]] = add i64 [[INDVARS_IV_EPIL]], 1
492; ENABLED-NEXT:    [[EXITCOND_EPIL:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT_EPIL]], [[N]]
493; ENABLED-NEXT:    [[EPIL_ITER_NEXT]] = add i64 [[EPIL_ITER]], 1
494; ENABLED-NEXT:    [[EPIL_ITER_CMP:%.*]] = icmp ne i64 [[EPIL_ITER_NEXT]], [[XTRAITER]]
495; ENABLED-NEXT:    br i1 [[EPIL_ITER_CMP]], label [[HEADER_EPIL]], label [[LATCHEXIT_EPILOG_LCSSA:%.*]], !llvm.loop [[LOOP2:![0-9]+]]
496; ENABLED:       latchexit.epilog-lcssa:
497; ENABLED-NEXT:    [[SUM_0_LCSSA_PH1:%.*]] = phi i32 [ [[ADD_EPIL]], [[LATCH_EPIL]] ]
498; ENABLED-NEXT:    br label [[LATCHEXIT]]
499; ENABLED:       latchexit:
500; ENABLED-NEXT:    [[SUM_0_LCSSA:%.*]] = phi i32 [ [[SUM_0_LCSSA_PH]], [[LATCHEXIT_UNR_LCSSA]] ], [ [[SUM_0_LCSSA_PH1]], [[LATCHEXIT_EPILOG_LCSSA]] ]
501; ENABLED-NEXT:    ret i32 [[SUM_0_LCSSA]]
502; ENABLED:       otherexit.loopexit:
503; 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]] ]
504; ENABLED-NEXT:    br label [[OTHEREXIT:%.*]]
505; ENABLED:       otherexit.loopexit2:
506; ENABLED-NEXT:    [[RVAL_PH3:%.*]] = phi i32 [ [[SUM_02_EPIL]], [[FOR_EXITING_BLOCK_EPIL]] ]
507; ENABLED-NEXT:    br label [[OTHEREXIT]]
508; ENABLED:       otherexit:
509; ENABLED-NEXT:    [[RVAL:%.*]] = phi i32 [ [[RVAL_PH]], [[OTHEREXIT_LOOPEXIT]] ], [ [[RVAL_PH3]], [[OTHEREXIT_LOOPEXIT2]] ]
510; ENABLED-NEXT:    ret i32 [[RVAL]]
511;
512entry:
513  br label %header
514
515header:
516  %indvars.iv = phi i64 [ %indvars.iv.next, %latch ], [ 0, %entry ]
517  %sum.02 = phi i32 [ %add, %latch ], [ 0, %entry ]
518  br label %for.exiting_block
519
520for.exiting_block:
521  %cmp = icmp eq i64 %n, 42
522  br i1 %cmp, label %otherexit, label %latch
523
524latch:
525  %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv
526  %0 = load i32, ptr %arrayidx, align 4
527  %add = add nsw i32 %0, %sum.02
528  %indvars.iv.next = add i64 %indvars.iv, 1
529  %exitcond = icmp eq i64 %indvars.iv.next, %n
530  br i1 %exitcond, label %latchexit, label %header
531
532latchexit:                                          ; preds = %latch
533  %sum.0.lcssa = phi i32 [ %add, %latch ]
534  ret i32 %sum.0.lcssa
535
536otherexit:
537  %rval = phi i32 [%sum.02, %for.exiting_block ]
538  ret i32 %rval
539}
540
541; A multiple exit loop with an estimated trip count which is small, and thus
542; the loop is not worth unrolling.  We probably should peel said loop, but
543; currently don't.
544define i32 @test3(ptr nocapture %a, i64 %n) !prof !{!"function_entry_count", i64 2048} {
545; CHECK-LABEL: @test3(
546; CHECK-NEXT:  entry:
547; CHECK-NEXT:    br label [[HEADER:%.*]]
548; CHECK:       header:
549; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LATCH:%.*]] ], [ 0, [[ENTRY:%.*]] ]
550; CHECK-NEXT:    [[SUM_02:%.*]] = phi i32 [ [[ADD:%.*]], [[LATCH]] ], [ 0, [[ENTRY]] ]
551; CHECK-NEXT:    br label [[FOR_EXITING_BLOCK:%.*]]
552; CHECK:       for.exiting_block:
553; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i64 [[N:%.*]], 42
554; CHECK-NEXT:    br i1 [[CMP]], label [[OTHEREXIT:%.*]], label [[LATCH]]
555; CHECK:       latch:
556; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]]
557; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
558; CHECK-NEXT:    [[ADD]] = add nsw i32 [[TMP0]], [[SUM_02]]
559; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add i64 [[INDVARS_IV]], 1
560; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], [[N]]
561; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LATCHEXIT:%.*]], label [[HEADER]], !prof [[PROF3:![0-9]+]]
562; CHECK:       latchexit:
563; CHECK-NEXT:    ret i32 [[ADD]]
564; CHECK:       otherexit:
565; CHECK-NEXT:    ret i32 57
566;
567; NOUNROLL-LABEL: @test3(
568; NOUNROLL-NEXT:  entry:
569; NOUNROLL-NEXT:    br label [[HEADER:%.*]]
570; NOUNROLL:       header:
571; NOUNROLL-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LATCH:%.*]] ], [ 0, [[ENTRY:%.*]] ]
572; NOUNROLL-NEXT:    [[SUM_02:%.*]] = phi i32 [ [[ADD:%.*]], [[LATCH]] ], [ 0, [[ENTRY]] ]
573; NOUNROLL-NEXT:    br label [[FOR_EXITING_BLOCK:%.*]]
574; NOUNROLL:       for.exiting_block:
575; NOUNROLL-NEXT:    [[CMP:%.*]] = icmp eq i64 [[N:%.*]], 42
576; NOUNROLL-NEXT:    br i1 [[CMP]], label [[OTHEREXIT:%.*]], label [[LATCH]]
577; NOUNROLL:       latch:
578; NOUNROLL-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]]
579; NOUNROLL-NEXT:    [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
580; NOUNROLL-NEXT:    [[ADD]] = add nsw i32 [[TMP0]], [[SUM_02]]
581; NOUNROLL-NEXT:    [[INDVARS_IV_NEXT]] = add i64 [[INDVARS_IV]], 1
582; NOUNROLL-NEXT:    [[EXITCOND:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], [[N]]
583; NOUNROLL-NEXT:    br i1 [[EXITCOND]], label [[LATCHEXIT:%.*]], label [[HEADER]], !prof [[PROF1:![0-9]+]]
584; NOUNROLL:       latchexit:
585; NOUNROLL-NEXT:    [[SUM_0_LCSSA:%.*]] = phi i32 [ [[ADD]], [[LATCH]] ]
586; NOUNROLL-NEXT:    ret i32 [[SUM_0_LCSSA]]
587; NOUNROLL:       otherexit:
588; NOUNROLL-NEXT:    ret i32 57
589;
590; ENABLED-LABEL: @test3(
591; ENABLED-NEXT:  entry:
592; ENABLED-NEXT:    br label [[HEADER:%.*]]
593; ENABLED:       header:
594; ENABLED-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LATCH:%.*]] ], [ 0, [[ENTRY:%.*]] ]
595; ENABLED-NEXT:    [[SUM_02:%.*]] = phi i32 [ [[ADD:%.*]], [[LATCH]] ], [ 0, [[ENTRY]] ]
596; ENABLED-NEXT:    br label [[FOR_EXITING_BLOCK:%.*]]
597; ENABLED:       for.exiting_block:
598; ENABLED-NEXT:    [[CMP:%.*]] = icmp eq i64 [[N:%.*]], 42
599; ENABLED-NEXT:    br i1 [[CMP]], label [[OTHEREXIT:%.*]], label [[LATCH]]
600; ENABLED:       latch:
601; ENABLED-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]]
602; ENABLED-NEXT:    [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
603; ENABLED-NEXT:    [[ADD]] = add nsw i32 [[TMP0]], [[SUM_02]]
604; ENABLED-NEXT:    [[INDVARS_IV_NEXT]] = add i64 [[INDVARS_IV]], 1
605; ENABLED-NEXT:    [[EXITCOND:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], [[N]]
606; ENABLED-NEXT:    br i1 [[EXITCOND]], label [[LATCHEXIT:%.*]], label [[HEADER]], !prof [[PROF4:![0-9]+]]
607; ENABLED:       latchexit:
608; ENABLED-NEXT:    [[SUM_0_LCSSA:%.*]] = phi i32 [ [[ADD]], [[LATCH]] ]
609; ENABLED-NEXT:    ret i32 [[SUM_0_LCSSA]]
610; ENABLED:       otherexit:
611; ENABLED-NEXT:    ret i32 57
612;
613entry:
614  br label %header
615
616header:
617  %indvars.iv = phi i64 [ %indvars.iv.next, %latch ], [ 0, %entry ]
618  %sum.02 = phi i32 [ %add, %latch ], [ 0, %entry ]
619  br label %for.exiting_block
620
621for.exiting_block:
622  %cmp = icmp eq i64 %n, 42
623  br i1 %cmp, label %otherexit, label %latch
624
625latch:
626  %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv
627  %0 = load i32, ptr %arrayidx, align 4
628  %add = add nsw i32 %0, %sum.02
629  %indvars.iv.next = add i64 %indvars.iv, 1
630  %exitcond = icmp eq i64 %indvars.iv.next, %n
631  br i1 %exitcond, label %latchexit, label %header, !prof !{!"branch_weights", i64 1, i64 2}
632
633latchexit:                                          ; preds = %latch
634  %sum.0.lcssa = phi i32 [ %add, %latch ]
635  ret i32 %sum.0.lcssa
636
637otherexit:
638  ret i32 57
639}
640
641; A case noticed while writing test3 where changing the early exit condition
642; seems to inhibit unrolling for some unclear reason.
643define i32 @test4(ptr nocapture %a, i64 %n) !prof !{!"function_entry_count", i64 2048} {
644;
645; CHECK-LABEL: @test4(
646; CHECK-NEXT:  entry:
647; CHECK-NEXT:    br label [[HEADER:%.*]]
648; CHECK:       header:
649; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LATCH:%.*]] ], [ 0, [[ENTRY:%.*]] ]
650; CHECK-NEXT:    [[SUM_02:%.*]] = phi i32 [ [[ADD:%.*]], [[LATCH]] ], [ 0, [[ENTRY]] ]
651; CHECK-NEXT:    br label [[FOR_EXITING_BLOCK:%.*]]
652; CHECK:       for.exiting_block:
653; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i64 [[INDVARS_IV]], 4096
654; CHECK-NEXT:    br i1 [[CMP]], label [[OTHEREXIT:%.*]], label [[LATCH]]
655; CHECK:       latch:
656; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]]
657; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
658; CHECK-NEXT:    [[ADD]] = add nsw i32 [[TMP0]], [[SUM_02]]
659; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add i64 [[INDVARS_IV]], 1
660; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], [[N:%.*]]
661; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LATCHEXIT:%.*]], label [[HEADER]]
662; CHECK:       latchexit:
663; CHECK-NEXT:    ret i32 [[ADD]]
664; CHECK:       otherexit:
665; CHECK-NEXT:    ret i32 57
666;
667; NOUNROLL-LABEL: @test4(
668; NOUNROLL-NEXT:  entry:
669; NOUNROLL-NEXT:    br label [[HEADER:%.*]]
670; NOUNROLL:       header:
671; NOUNROLL-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LATCH:%.*]] ], [ 0, [[ENTRY:%.*]] ]
672; NOUNROLL-NEXT:    [[SUM_02:%.*]] = phi i32 [ [[ADD:%.*]], [[LATCH]] ], [ 0, [[ENTRY]] ]
673; NOUNROLL-NEXT:    br label [[FOR_EXITING_BLOCK:%.*]]
674; NOUNROLL:       for.exiting_block:
675; NOUNROLL-NEXT:    [[CMP:%.*]] = icmp eq i64 [[INDVARS_IV]], 4096
676; NOUNROLL-NEXT:    br i1 [[CMP]], label [[OTHEREXIT:%.*]], label [[LATCH]]
677; NOUNROLL:       latch:
678; NOUNROLL-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]]
679; NOUNROLL-NEXT:    [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
680; NOUNROLL-NEXT:    [[ADD]] = add nsw i32 [[TMP0]], [[SUM_02]]
681; NOUNROLL-NEXT:    [[INDVARS_IV_NEXT]] = add i64 [[INDVARS_IV]], 1
682; NOUNROLL-NEXT:    [[EXITCOND:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], [[N:%.*]]
683; NOUNROLL-NEXT:    br i1 [[EXITCOND]], label [[LATCHEXIT:%.*]], label [[HEADER]]
684; NOUNROLL:       latchexit:
685; NOUNROLL-NEXT:    [[SUM_0_LCSSA:%.*]] = phi i32 [ [[ADD]], [[LATCH]] ]
686; NOUNROLL-NEXT:    ret i32 [[SUM_0_LCSSA]]
687; NOUNROLL:       otherexit:
688; NOUNROLL-NEXT:    ret i32 57
689;
690; ENABLED-LABEL: @test4(
691; ENABLED-NEXT:  entry:
692; ENABLED-NEXT:    br label [[HEADER:%.*]]
693; ENABLED:       header:
694; ENABLED-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LATCH:%.*]] ], [ 0, [[ENTRY:%.*]] ]
695; ENABLED-NEXT:    [[SUM_02:%.*]] = phi i32 [ [[ADD:%.*]], [[LATCH]] ], [ 0, [[ENTRY]] ]
696; ENABLED-NEXT:    br label [[FOR_EXITING_BLOCK:%.*]]
697; ENABLED:       for.exiting_block:
698; ENABLED-NEXT:    [[CMP:%.*]] = icmp eq i64 [[INDVARS_IV]], 4096
699; ENABLED-NEXT:    br i1 [[CMP]], label [[OTHEREXIT:%.*]], label [[LATCH]]
700; ENABLED:       latch:
701; ENABLED-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]]
702; ENABLED-NEXT:    [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
703; ENABLED-NEXT:    [[ADD]] = add nsw i32 [[TMP0]], [[SUM_02]]
704; ENABLED-NEXT:    [[INDVARS_IV_NEXT]] = add i64 [[INDVARS_IV]], 1
705; ENABLED-NEXT:    [[EXITCOND:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], [[N:%.*]]
706; ENABLED-NEXT:    br i1 [[EXITCOND]], label [[LATCHEXIT:%.*]], label [[HEADER]]
707; ENABLED:       latchexit:
708; ENABLED-NEXT:    [[SUM_0_LCSSA:%.*]] = phi i32 [ [[ADD]], [[LATCH]] ]
709; ENABLED-NEXT:    ret i32 [[SUM_0_LCSSA]]
710; ENABLED:       otherexit:
711; ENABLED-NEXT:    ret i32 57
712;
713entry:
714  br label %header
715
716header:
717  %indvars.iv = phi i64 [ %indvars.iv.next, %latch ], [ 0, %entry ]
718  %sum.02 = phi i32 [ %add, %latch ], [ 0, %entry ]
719  br label %for.exiting_block
720
721for.exiting_block:
722  %cmp = icmp eq i64 %indvars.iv, 4096
723  br i1 %cmp, label %otherexit, label %latch
724
725latch:
726  %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv
727  %0 = load i32, ptr %arrayidx, align 4
728  %add = add nsw i32 %0, %sum.02
729  %indvars.iv.next = add i64 %indvars.iv, 1
730  %exitcond = icmp eq i64 %indvars.iv.next, %n
731  br i1 %exitcond, label %latchexit, label %header
732
733latchexit:                                          ; preds = %latch
734  %sum.0.lcssa = phi i32 [ %add, %latch ]
735  ret i32 %sum.0.lcssa
736
737otherexit:
738  ret i32 57
739}
740
741; the exit block is not a deopt block but it leads to deopt one.
742define i32 @test5(ptr nocapture %a, i64 %n) {
743;
744; CHECK-LABEL: @test5(
745; CHECK-NEXT:  entry:
746; CHECK-NEXT:    [[TMP0:%.*]] = freeze i64 [[N:%.*]]
747; CHECK-NEXT:    [[TMP1:%.*]] = add i64 [[TMP0]], -1
748; CHECK-NEXT:    [[XTRAITER:%.*]] = and i64 [[TMP0]], 7
749; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i64 [[TMP1]], 7
750; CHECK-NEXT:    br i1 [[TMP2]], label [[LATCHEXIT_UNR_LCSSA:%.*]], label [[ENTRY_NEW:%.*]]
751; CHECK:       entry.new:
752; CHECK-NEXT:    [[UNROLL_ITER:%.*]] = and i64 [[TMP0]], -8
753; CHECK-NEXT:    br label [[HEADER:%.*]]
754; CHECK:       header:
755; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY_NEW]] ], [ [[INDVARS_IV_NEXT_7:%.*]], [[LATCH_7:%.*]] ]
756; CHECK-NEXT:    [[SUM_02:%.*]] = phi i32 [ 0, [[ENTRY_NEW]] ], [ [[ADD_7:%.*]], [[LATCH_7]] ]
757; CHECK-NEXT:    [[NITER:%.*]] = phi i64 [ 0, [[ENTRY_NEW]] ], [ [[NITER_NEXT_7:%.*]], [[LATCH_7]] ]
758; CHECK-NEXT:    br label [[FOR_EXITING_BLOCK:%.*]]
759; CHECK:       for.exiting_block:
760; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i64 [[TMP0]], 42
761; CHECK-NEXT:    br i1 [[CMP]], label [[OTHEREXIT_LOOPEXIT:%.*]], label [[LATCH:%.*]]
762; CHECK:       latch:
763; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]]
764; CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
765; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[TMP3]], [[SUM_02]]
766; CHECK-NEXT:    [[INDVARS_IV_NEXT:%.*]] = or disjoint i64 [[INDVARS_IV]], 1
767; CHECK-NEXT:    br label [[FOR_EXITING_BLOCK_1:%.*]]
768; CHECK:       for.exiting_block.1:
769; CHECK-NEXT:    br i1 false, label [[OTHEREXIT_LOOPEXIT]], label [[LATCH_1:%.*]]
770; CHECK:       latch.1:
771; CHECK-NEXT:    [[ARRAYIDX_1:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[INDVARS_IV_NEXT]]
772; CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[ARRAYIDX_1]], align 4
773; CHECK-NEXT:    [[ADD_1:%.*]] = add nsw i32 [[TMP4]], [[ADD]]
774; CHECK-NEXT:    [[INDVARS_IV_NEXT_1:%.*]] = or disjoint i64 [[INDVARS_IV]], 2
775; CHECK-NEXT:    br label [[FOR_EXITING_BLOCK_2:%.*]]
776; CHECK:       for.exiting_block.2:
777; CHECK-NEXT:    br i1 false, label [[OTHEREXIT_LOOPEXIT]], label [[LATCH_2:%.*]]
778; CHECK:       latch.2:
779; CHECK-NEXT:    [[ARRAYIDX_2:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[INDVARS_IV_NEXT_1]]
780; CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[ARRAYIDX_2]], align 4
781; CHECK-NEXT:    [[ADD_2:%.*]] = add nsw i32 [[TMP5]], [[ADD_1]]
782; CHECK-NEXT:    [[INDVARS_IV_NEXT_2:%.*]] = or disjoint i64 [[INDVARS_IV]], 3
783; CHECK-NEXT:    br label [[FOR_EXITING_BLOCK_3:%.*]]
784; CHECK:       for.exiting_block.3:
785; CHECK-NEXT:    br i1 false, label [[OTHEREXIT_LOOPEXIT]], label [[LATCH_3:%.*]]
786; CHECK:       latch.3:
787; CHECK-NEXT:    [[ARRAYIDX_3:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[INDVARS_IV_NEXT_2]]
788; CHECK-NEXT:    [[TMP6:%.*]] = load i32, ptr [[ARRAYIDX_3]], align 4
789; CHECK-NEXT:    [[ADD_3:%.*]] = add nsw i32 [[TMP6]], [[ADD_2]]
790; CHECK-NEXT:    [[INDVARS_IV_NEXT_3:%.*]] = or disjoint i64 [[INDVARS_IV]], 4
791; CHECK-NEXT:    br label [[FOR_EXITING_BLOCK_4:%.*]]
792; CHECK:       for.exiting_block.4:
793; CHECK-NEXT:    br i1 false, label [[OTHEREXIT_LOOPEXIT]], label [[LATCH_4:%.*]]
794; CHECK:       latch.4:
795; CHECK-NEXT:    [[ARRAYIDX_4:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[INDVARS_IV_NEXT_3]]
796; CHECK-NEXT:    [[TMP7:%.*]] = load i32, ptr [[ARRAYIDX_4]], align 4
797; CHECK-NEXT:    [[ADD_4:%.*]] = add nsw i32 [[TMP7]], [[ADD_3]]
798; CHECK-NEXT:    [[INDVARS_IV_NEXT_4:%.*]] = or disjoint i64 [[INDVARS_IV]], 5
799; CHECK-NEXT:    br label [[FOR_EXITING_BLOCK_5:%.*]]
800; CHECK:       for.exiting_block.5:
801; CHECK-NEXT:    br i1 false, label [[OTHEREXIT_LOOPEXIT]], label [[LATCH_5:%.*]]
802; CHECK:       latch.5:
803; CHECK-NEXT:    [[ARRAYIDX_5:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[INDVARS_IV_NEXT_4]]
804; CHECK-NEXT:    [[TMP8:%.*]] = load i32, ptr [[ARRAYIDX_5]], align 4
805; CHECK-NEXT:    [[ADD_5:%.*]] = add nsw i32 [[TMP8]], [[ADD_4]]
806; CHECK-NEXT:    [[INDVARS_IV_NEXT_5:%.*]] = or disjoint i64 [[INDVARS_IV]], 6
807; CHECK-NEXT:    br label [[FOR_EXITING_BLOCK_6:%.*]]
808; CHECK:       for.exiting_block.6:
809; CHECK-NEXT:    br i1 false, label [[OTHEREXIT_LOOPEXIT]], label [[LATCH_6:%.*]]
810; CHECK:       latch.6:
811; CHECK-NEXT:    [[ARRAYIDX_6:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[INDVARS_IV_NEXT_5]]
812; CHECK-NEXT:    [[TMP9:%.*]] = load i32, ptr [[ARRAYIDX_6]], align 4
813; CHECK-NEXT:    [[ADD_6:%.*]] = add nsw i32 [[TMP9]], [[ADD_5]]
814; CHECK-NEXT:    [[INDVARS_IV_NEXT_6:%.*]] = or disjoint i64 [[INDVARS_IV]], 7
815; CHECK-NEXT:    br label [[FOR_EXITING_BLOCK_7:%.*]]
816; CHECK:       for.exiting_block.7:
817; CHECK-NEXT:    br i1 false, label [[OTHEREXIT_LOOPEXIT]], label [[LATCH_7]]
818; CHECK:       latch.7:
819; CHECK-NEXT:    [[ARRAYIDX_7:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[INDVARS_IV_NEXT_6]]
820; CHECK-NEXT:    [[TMP10:%.*]] = load i32, ptr [[ARRAYIDX_7]], align 4
821; CHECK-NEXT:    [[ADD_7]] = add nsw i32 [[TMP10]], [[ADD_6]]
822; CHECK-NEXT:    [[INDVARS_IV_NEXT_7]] = add i64 [[INDVARS_IV]], 8
823; CHECK-NEXT:    [[NITER_NEXT_7]] = add i64 [[NITER]], 8
824; CHECK-NEXT:    [[NITER_NCMP_7:%.*]] = icmp eq i64 [[NITER_NEXT_7]], [[UNROLL_ITER]]
825; CHECK-NEXT:    br i1 [[NITER_NCMP_7]], label [[LATCHEXIT_UNR_LCSSA_LOOPEXIT:%.*]], label [[HEADER]]
826; CHECK:       latchexit.unr-lcssa.loopexit:
827; CHECK-NEXT:    br label [[LATCHEXIT_UNR_LCSSA]]
828; CHECK:       latchexit.unr-lcssa:
829; CHECK-NEXT:    [[SUM_0_LCSSA_PH:%.*]] = phi i32 [ poison, [[ENTRY:%.*]] ], [ [[ADD_7]], [[LATCHEXIT_UNR_LCSSA_LOOPEXIT]] ]
830; CHECK-NEXT:    [[INDVARS_IV_UNR:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[INDVARS_IV_NEXT_7]], [[LATCHEXIT_UNR_LCSSA_LOOPEXIT]] ]
831; CHECK-NEXT:    [[SUM_02_UNR:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ADD_7]], [[LATCHEXIT_UNR_LCSSA_LOOPEXIT]] ]
832; CHECK-NEXT:    [[LCMP_MOD_NOT:%.*]] = icmp eq i64 [[XTRAITER]], 0
833; CHECK-NEXT:    br i1 [[LCMP_MOD_NOT]], label [[LATCHEXIT:%.*]], label [[HEADER_EPIL_PREHEADER:%.*]]
834; CHECK:       header.epil.preheader:
835; CHECK-NEXT:    br label [[HEADER_EPIL:%.*]]
836; CHECK:       header.epil:
837; CHECK-NEXT:    [[INDVARS_IV_EPIL:%.*]] = phi i64 [ [[INDVARS_IV_NEXT_EPIL:%.*]], [[LATCH_EPIL:%.*]] ], [ [[INDVARS_IV_UNR]], [[HEADER_EPIL_PREHEADER]] ]
838; CHECK-NEXT:    [[SUM_02_EPIL:%.*]] = phi i32 [ [[ADD_EPIL:%.*]], [[LATCH_EPIL]] ], [ [[SUM_02_UNR]], [[HEADER_EPIL_PREHEADER]] ]
839; CHECK-NEXT:    [[EPIL_ITER:%.*]] = phi i64 [ [[EPIL_ITER_NEXT:%.*]], [[LATCH_EPIL]] ], [ 0, [[HEADER_EPIL_PREHEADER]] ]
840; CHECK-NEXT:    br label [[FOR_EXITING_BLOCK_EPIL:%.*]]
841; CHECK:       for.exiting_block.epil:
842; CHECK-NEXT:    [[CMP_EPIL:%.*]] = icmp eq i64 [[TMP0]], 42
843; CHECK-NEXT:    br i1 [[CMP_EPIL]], label [[OTHEREXIT_LOOPEXIT3:%.*]], label [[LATCH_EPIL]]
844; CHECK:       latch.epil:
845; CHECK-NEXT:    [[ARRAYIDX_EPIL:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[INDVARS_IV_EPIL]]
846; CHECK-NEXT:    [[TMP11:%.*]] = load i32, ptr [[ARRAYIDX_EPIL]], align 4
847; CHECK-NEXT:    [[ADD_EPIL]] = add nsw i32 [[TMP11]], [[SUM_02_EPIL]]
848; CHECK-NEXT:    [[INDVARS_IV_NEXT_EPIL]] = add i64 [[INDVARS_IV_EPIL]], 1
849; CHECK-NEXT:    [[EPIL_ITER_NEXT]] = add i64 [[EPIL_ITER]], 1
850; CHECK-NEXT:    [[EPIL_ITER_CMP_NOT:%.*]] = icmp eq i64 [[EPIL_ITER_NEXT]], [[XTRAITER]]
851; CHECK-NEXT:    br i1 [[EPIL_ITER_CMP_NOT]], label [[LATCHEXIT_EPILOG_LCSSA:%.*]], label [[HEADER_EPIL]], !llvm.loop [[LOOP4:![0-9]+]]
852; CHECK:       latchexit.epilog-lcssa:
853; CHECK-NEXT:    br label [[LATCHEXIT]]
854; CHECK:       latchexit:
855; CHECK-NEXT:    [[SUM_0_LCSSA:%.*]] = phi i32 [ [[SUM_0_LCSSA_PH]], [[LATCHEXIT_UNR_LCSSA]] ], [ [[ADD_EPIL]], [[LATCHEXIT_EPILOG_LCSSA]] ]
856; CHECK-NEXT:    ret i32 [[SUM_0_LCSSA]]
857; CHECK:       otherexit.loopexit:
858; CHECK-NEXT:    br label [[OTHEREXIT:%.*]]
859; CHECK:       otherexit.loopexit3:
860; CHECK-NEXT:    br label [[OTHEREXIT]]
861; CHECK:       otherexit:
862; CHECK-NEXT:    [[SUM_02_LCSSA:%.*]] = phi i32 [ [[SUM_02]], [[OTHEREXIT_LOOPEXIT]] ], [ [[SUM_02_EPIL]], [[OTHEREXIT_LOOPEXIT3]] ]
863; CHECK-NEXT:    br label [[OTHEREXIT2:%.*]]
864; CHECK:       otherexit2:
865; CHECK-NEXT:    [[RVAL2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"(i32 [[SUM_02_LCSSA]]) ]
866; CHECK-NEXT:    ret i32 [[RVAL2]]
867;
868; NOUNROLL-LABEL: @test5(
869; NOUNROLL-NEXT:  entry:
870; NOUNROLL-NEXT:    br label [[HEADER:%.*]]
871; NOUNROLL:       header:
872; NOUNROLL-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LATCH:%.*]] ], [ 0, [[ENTRY:%.*]] ]
873; NOUNROLL-NEXT:    [[SUM_02:%.*]] = phi i32 [ [[ADD:%.*]], [[LATCH]] ], [ 0, [[ENTRY]] ]
874; NOUNROLL-NEXT:    br label [[FOR_EXITING_BLOCK:%.*]]
875; NOUNROLL:       for.exiting_block:
876; NOUNROLL-NEXT:    [[CMP:%.*]] = icmp eq i64 [[N:%.*]], 42
877; NOUNROLL-NEXT:    br i1 [[CMP]], label [[OTHEREXIT:%.*]], label [[LATCH]]
878; NOUNROLL:       latch:
879; NOUNROLL-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]]
880; NOUNROLL-NEXT:    [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
881; NOUNROLL-NEXT:    [[ADD]] = add nsw i32 [[TMP0]], [[SUM_02]]
882; NOUNROLL-NEXT:    [[INDVARS_IV_NEXT]] = add i64 [[INDVARS_IV]], 1
883; NOUNROLL-NEXT:    [[EXITCOND:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], [[N]]
884; NOUNROLL-NEXT:    br i1 [[EXITCOND]], label [[LATCHEXIT:%.*]], label [[HEADER]]
885; NOUNROLL:       latchexit:
886; NOUNROLL-NEXT:    [[SUM_0_LCSSA:%.*]] = phi i32 [ [[ADD]], [[LATCH]] ]
887; NOUNROLL-NEXT:    ret i32 [[SUM_0_LCSSA]]
888; NOUNROLL:       otherexit:
889; NOUNROLL-NEXT:    [[SUM_02_LCSSA:%.*]] = phi i32 [ [[SUM_02]], [[FOR_EXITING_BLOCK]] ]
890; NOUNROLL-NEXT:    [[RVAL:%.*]] = phi i32 [ [[SUM_02]], [[FOR_EXITING_BLOCK]] ]
891; NOUNROLL-NEXT:    br label [[OTHEREXIT2:%.*]]
892; NOUNROLL:       otherexit2:
893; NOUNROLL-NEXT:    [[RVAL2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"(i32 [[SUM_02_LCSSA]]) ]
894; NOUNROLL-NEXT:    ret i32 [[RVAL2]]
895;
896; ENABLED-LABEL: @test5(
897; ENABLED-NEXT:  entry:
898; ENABLED-NEXT:    [[TMP0:%.*]] = freeze i64 [[N:%.*]]
899; ENABLED-NEXT:    [[TMP1:%.*]] = add i64 [[TMP0]], -1
900; ENABLED-NEXT:    [[XTRAITER:%.*]] = and i64 [[TMP0]], 7
901; ENABLED-NEXT:    [[TMP2:%.*]] = icmp ult i64 [[TMP1]], 7
902; ENABLED-NEXT:    br i1 [[TMP2]], label [[LATCHEXIT_UNR_LCSSA:%.*]], label [[ENTRY_NEW:%.*]]
903; ENABLED:       entry.new:
904; ENABLED-NEXT:    [[UNROLL_ITER:%.*]] = sub i64 [[TMP0]], [[XTRAITER]]
905; ENABLED-NEXT:    br label [[HEADER:%.*]]
906; ENABLED:       header:
907; ENABLED-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY_NEW]] ], [ [[INDVARS_IV_NEXT_7:%.*]], [[LATCH_7:%.*]] ]
908; ENABLED-NEXT:    [[SUM_02:%.*]] = phi i32 [ 0, [[ENTRY_NEW]] ], [ [[ADD_7:%.*]], [[LATCH_7]] ]
909; ENABLED-NEXT:    [[NITER:%.*]] = phi i64 [ 0, [[ENTRY_NEW]] ], [ [[NITER_NEXT_7:%.*]], [[LATCH_7]] ]
910; ENABLED-NEXT:    br label [[FOR_EXITING_BLOCK:%.*]]
911; ENABLED:       for.exiting_block:
912; ENABLED-NEXT:    [[CMP:%.*]] = icmp eq i64 [[N]], 42
913; ENABLED-NEXT:    br i1 [[CMP]], label [[OTHEREXIT_LOOPEXIT:%.*]], label [[LATCH:%.*]]
914; ENABLED:       latch:
915; ENABLED-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]]
916; ENABLED-NEXT:    [[TMP3:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
917; ENABLED-NEXT:    [[ADD:%.*]] = add nsw i32 [[TMP3]], [[SUM_02]]
918; ENABLED-NEXT:    [[INDVARS_IV_NEXT:%.*]] = add nuw nsw i64 [[INDVARS_IV]], 1
919; ENABLED-NEXT:    br label [[FOR_EXITING_BLOCK_1:%.*]]
920; ENABLED:       for.exiting_block.1:
921; ENABLED-NEXT:    [[CMP_1:%.*]] = icmp eq i64 [[N]], 42
922; ENABLED-NEXT:    br i1 [[CMP_1]], label [[OTHEREXIT_LOOPEXIT]], label [[LATCH_1:%.*]]
923; ENABLED:       latch.1:
924; ENABLED-NEXT:    [[ARRAYIDX_1:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[INDVARS_IV_NEXT]]
925; ENABLED-NEXT:    [[TMP4:%.*]] = load i32, ptr [[ARRAYIDX_1]], align 4
926; ENABLED-NEXT:    [[ADD_1:%.*]] = add nsw i32 [[TMP4]], [[ADD]]
927; ENABLED-NEXT:    [[INDVARS_IV_NEXT_1:%.*]] = add nuw nsw i64 [[INDVARS_IV]], 2
928; ENABLED-NEXT:    br label [[FOR_EXITING_BLOCK_2:%.*]]
929; ENABLED:       for.exiting_block.2:
930; ENABLED-NEXT:    [[CMP_2:%.*]] = icmp eq i64 [[N]], 42
931; ENABLED-NEXT:    br i1 [[CMP_2]], label [[OTHEREXIT_LOOPEXIT]], label [[LATCH_2:%.*]]
932; ENABLED:       latch.2:
933; ENABLED-NEXT:    [[ARRAYIDX_2:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[INDVARS_IV_NEXT_1]]
934; ENABLED-NEXT:    [[TMP5:%.*]] = load i32, ptr [[ARRAYIDX_2]], align 4
935; ENABLED-NEXT:    [[ADD_2:%.*]] = add nsw i32 [[TMP5]], [[ADD_1]]
936; ENABLED-NEXT:    [[INDVARS_IV_NEXT_2:%.*]] = add nuw nsw i64 [[INDVARS_IV]], 3
937; ENABLED-NEXT:    br label [[FOR_EXITING_BLOCK_3:%.*]]
938; ENABLED:       for.exiting_block.3:
939; ENABLED-NEXT:    [[CMP_3:%.*]] = icmp eq i64 [[N]], 42
940; ENABLED-NEXT:    br i1 [[CMP_3]], label [[OTHEREXIT_LOOPEXIT]], label [[LATCH_3:%.*]]
941; ENABLED:       latch.3:
942; ENABLED-NEXT:    [[ARRAYIDX_3:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[INDVARS_IV_NEXT_2]]
943; ENABLED-NEXT:    [[TMP6:%.*]] = load i32, ptr [[ARRAYIDX_3]], align 4
944; ENABLED-NEXT:    [[ADD_3:%.*]] = add nsw i32 [[TMP6]], [[ADD_2]]
945; ENABLED-NEXT:    [[INDVARS_IV_NEXT_3:%.*]] = add nuw nsw i64 [[INDVARS_IV]], 4
946; ENABLED-NEXT:    br label [[FOR_EXITING_BLOCK_4:%.*]]
947; ENABLED:       for.exiting_block.4:
948; ENABLED-NEXT:    [[CMP_4:%.*]] = icmp eq i64 [[N]], 42
949; ENABLED-NEXT:    br i1 [[CMP_4]], label [[OTHEREXIT_LOOPEXIT]], label [[LATCH_4:%.*]]
950; ENABLED:       latch.4:
951; ENABLED-NEXT:    [[ARRAYIDX_4:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[INDVARS_IV_NEXT_3]]
952; ENABLED-NEXT:    [[TMP7:%.*]] = load i32, ptr [[ARRAYIDX_4]], align 4
953; ENABLED-NEXT:    [[ADD_4:%.*]] = add nsw i32 [[TMP7]], [[ADD_3]]
954; ENABLED-NEXT:    [[INDVARS_IV_NEXT_4:%.*]] = add nuw nsw i64 [[INDVARS_IV]], 5
955; ENABLED-NEXT:    br label [[FOR_EXITING_BLOCK_5:%.*]]
956; ENABLED:       for.exiting_block.5:
957; ENABLED-NEXT:    [[CMP_5:%.*]] = icmp eq i64 [[N]], 42
958; ENABLED-NEXT:    br i1 [[CMP_5]], label [[OTHEREXIT_LOOPEXIT]], label [[LATCH_5:%.*]]
959; ENABLED:       latch.5:
960; ENABLED-NEXT:    [[ARRAYIDX_5:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[INDVARS_IV_NEXT_4]]
961; ENABLED-NEXT:    [[TMP8:%.*]] = load i32, ptr [[ARRAYIDX_5]], align 4
962; ENABLED-NEXT:    [[ADD_5:%.*]] = add nsw i32 [[TMP8]], [[ADD_4]]
963; ENABLED-NEXT:    [[INDVARS_IV_NEXT_5:%.*]] = add nuw nsw i64 [[INDVARS_IV]], 6
964; ENABLED-NEXT:    br label [[FOR_EXITING_BLOCK_6:%.*]]
965; ENABLED:       for.exiting_block.6:
966; ENABLED-NEXT:    [[CMP_6:%.*]] = icmp eq i64 [[N]], 42
967; ENABLED-NEXT:    br i1 [[CMP_6]], label [[OTHEREXIT_LOOPEXIT]], label [[LATCH_6:%.*]]
968; ENABLED:       latch.6:
969; ENABLED-NEXT:    [[ARRAYIDX_6:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[INDVARS_IV_NEXT_5]]
970; ENABLED-NEXT:    [[TMP9:%.*]] = load i32, ptr [[ARRAYIDX_6]], align 4
971; ENABLED-NEXT:    [[ADD_6:%.*]] = add nsw i32 [[TMP9]], [[ADD_5]]
972; ENABLED-NEXT:    [[INDVARS_IV_NEXT_6:%.*]] = add nuw nsw i64 [[INDVARS_IV]], 7
973; ENABLED-NEXT:    br label [[FOR_EXITING_BLOCK_7:%.*]]
974; ENABLED:       for.exiting_block.7:
975; ENABLED-NEXT:    [[CMP_7:%.*]] = icmp eq i64 [[N]], 42
976; ENABLED-NEXT:    br i1 [[CMP_7]], label [[OTHEREXIT_LOOPEXIT]], label [[LATCH_7]]
977; ENABLED:       latch.7:
978; ENABLED-NEXT:    [[ARRAYIDX_7:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[INDVARS_IV_NEXT_6]]
979; ENABLED-NEXT:    [[TMP10:%.*]] = load i32, ptr [[ARRAYIDX_7]], align 4
980; ENABLED-NEXT:    [[ADD_7]] = add nsw i32 [[TMP10]], [[ADD_6]]
981; ENABLED-NEXT:    [[INDVARS_IV_NEXT_7]] = add i64 [[INDVARS_IV]], 8
982; ENABLED-NEXT:    [[NITER_NEXT_7]] = add i64 [[NITER]], 8
983; ENABLED-NEXT:    [[NITER_NCMP_7:%.*]] = icmp eq i64 [[NITER_NEXT_7]], [[UNROLL_ITER]]
984; ENABLED-NEXT:    br i1 [[NITER_NCMP_7]], label [[LATCHEXIT_UNR_LCSSA_LOOPEXIT:%.*]], label [[HEADER]]
985; ENABLED:       latchexit.unr-lcssa.loopexit:
986; ENABLED-NEXT:    [[SUM_0_LCSSA_PH_PH:%.*]] = phi i32 [ [[ADD_7]], [[LATCH_7]] ]
987; ENABLED-NEXT:    [[INDVARS_IV_UNR_PH:%.*]] = phi i64 [ [[INDVARS_IV_NEXT_7]], [[LATCH_7]] ]
988; ENABLED-NEXT:    [[SUM_02_UNR_PH:%.*]] = phi i32 [ [[ADD_7]], [[LATCH_7]] ]
989; ENABLED-NEXT:    br label [[LATCHEXIT_UNR_LCSSA]]
990; ENABLED:       latchexit.unr-lcssa:
991; ENABLED-NEXT:    [[SUM_0_LCSSA_PH:%.*]] = phi i32 [ poison, [[ENTRY:%.*]] ], [ [[SUM_0_LCSSA_PH_PH]], [[LATCHEXIT_UNR_LCSSA_LOOPEXIT]] ]
992; ENABLED-NEXT:    [[INDVARS_IV_UNR:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[INDVARS_IV_UNR_PH]], [[LATCHEXIT_UNR_LCSSA_LOOPEXIT]] ]
993; ENABLED-NEXT:    [[SUM_02_UNR:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[SUM_02_UNR_PH]], [[LATCHEXIT_UNR_LCSSA_LOOPEXIT]] ]
994; ENABLED-NEXT:    [[LCMP_MOD:%.*]] = icmp ne i64 [[XTRAITER]], 0
995; ENABLED-NEXT:    br i1 [[LCMP_MOD]], label [[HEADER_EPIL_PREHEADER:%.*]], label [[LATCHEXIT:%.*]]
996; ENABLED:       header.epil.preheader:
997; ENABLED-NEXT:    br label [[HEADER_EPIL:%.*]]
998; ENABLED:       header.epil:
999; ENABLED-NEXT:    [[INDVARS_IV_EPIL:%.*]] = phi i64 [ [[INDVARS_IV_NEXT_EPIL:%.*]], [[LATCH_EPIL:%.*]] ], [ [[INDVARS_IV_UNR]], [[HEADER_EPIL_PREHEADER]] ]
1000; ENABLED-NEXT:    [[SUM_02_EPIL:%.*]] = phi i32 [ [[ADD_EPIL:%.*]], [[LATCH_EPIL]] ], [ [[SUM_02_UNR]], [[HEADER_EPIL_PREHEADER]] ]
1001; ENABLED-NEXT:    [[EPIL_ITER:%.*]] = phi i64 [ 0, [[HEADER_EPIL_PREHEADER]] ], [ [[EPIL_ITER_NEXT:%.*]], [[LATCH_EPIL]] ]
1002; ENABLED-NEXT:    br label [[FOR_EXITING_BLOCK_EPIL:%.*]]
1003; ENABLED:       for.exiting_block.epil:
1004; ENABLED-NEXT:    [[CMP_EPIL:%.*]] = icmp eq i64 [[N]], 42
1005; ENABLED-NEXT:    br i1 [[CMP_EPIL]], label [[OTHEREXIT_LOOPEXIT3:%.*]], label [[LATCH_EPIL]]
1006; ENABLED:       latch.epil:
1007; ENABLED-NEXT:    [[ARRAYIDX_EPIL:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[INDVARS_IV_EPIL]]
1008; ENABLED-NEXT:    [[TMP11:%.*]] = load i32, ptr [[ARRAYIDX_EPIL]], align 4
1009; ENABLED-NEXT:    [[ADD_EPIL]] = add nsw i32 [[TMP11]], [[SUM_02_EPIL]]
1010; ENABLED-NEXT:    [[INDVARS_IV_NEXT_EPIL]] = add i64 [[INDVARS_IV_EPIL]], 1
1011; ENABLED-NEXT:    [[EXITCOND_EPIL:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT_EPIL]], [[N]]
1012; ENABLED-NEXT:    [[EPIL_ITER_NEXT]] = add i64 [[EPIL_ITER]], 1
1013; ENABLED-NEXT:    [[EPIL_ITER_CMP:%.*]] = icmp ne i64 [[EPIL_ITER_NEXT]], [[XTRAITER]]
1014; ENABLED-NEXT:    br i1 [[EPIL_ITER_CMP]], label [[HEADER_EPIL]], label [[LATCHEXIT_EPILOG_LCSSA:%.*]], !llvm.loop [[LOOP5:![0-9]+]]
1015; ENABLED:       latchexit.epilog-lcssa:
1016; ENABLED-NEXT:    [[SUM_0_LCSSA_PH2:%.*]] = phi i32 [ [[ADD_EPIL]], [[LATCH_EPIL]] ]
1017; ENABLED-NEXT:    br label [[LATCHEXIT]]
1018; ENABLED:       latchexit:
1019; ENABLED-NEXT:    [[SUM_0_LCSSA:%.*]] = phi i32 [ [[SUM_0_LCSSA_PH]], [[LATCHEXIT_UNR_LCSSA]] ], [ [[SUM_0_LCSSA_PH2]], [[LATCHEXIT_EPILOG_LCSSA]] ]
1020; ENABLED-NEXT:    ret i32 [[SUM_0_LCSSA]]
1021; ENABLED:       otherexit.loopexit:
1022; 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]] ]
1023; 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]] ]
1024; ENABLED-NEXT:    br label [[OTHEREXIT:%.*]]
1025; ENABLED:       otherexit.loopexit3:
1026; ENABLED-NEXT:    [[SUM_02_LCSSA_PH4:%.*]] = phi i32 [ [[SUM_02_EPIL]], [[FOR_EXITING_BLOCK_EPIL]] ]
1027; ENABLED-NEXT:    [[RVAL_PH5:%.*]] = phi i32 [ [[SUM_02_EPIL]], [[FOR_EXITING_BLOCK_EPIL]] ]
1028; ENABLED-NEXT:    br label [[OTHEREXIT]]
1029; ENABLED:       otherexit:
1030; ENABLED-NEXT:    [[SUM_02_LCSSA:%.*]] = phi i32 [ [[SUM_02_LCSSA_PH]], [[OTHEREXIT_LOOPEXIT]] ], [ [[SUM_02_LCSSA_PH4]], [[OTHEREXIT_LOOPEXIT3]] ]
1031; ENABLED-NEXT:    [[RVAL:%.*]] = phi i32 [ [[RVAL_PH]], [[OTHEREXIT_LOOPEXIT]] ], [ [[RVAL_PH5]], [[OTHEREXIT_LOOPEXIT3]] ]
1032; ENABLED-NEXT:    br label [[OTHEREXIT2:%.*]]
1033; ENABLED:       otherexit2:
1034; ENABLED-NEXT:    [[RVAL2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"(i32 [[SUM_02_LCSSA]]) ]
1035; ENABLED-NEXT:    ret i32 [[RVAL2]]
1036;
1037entry:
1038  br label %header
1039
1040header:
1041  %indvars.iv = phi i64 [ %indvars.iv.next, %latch ], [ 0, %entry ]
1042  %sum.02 = phi i32 [ %add, %latch ], [ 0, %entry ]
1043  br label %for.exiting_block
1044
1045for.exiting_block:
1046  %cmp = icmp eq i64 %n, 42
1047  br i1 %cmp, label %otherexit, label %latch
1048
1049latch:
1050  %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv
1051  %0 = load i32, ptr %arrayidx, align 4
1052  %add = add nsw i32 %0, %sum.02
1053  %indvars.iv.next = add i64 %indvars.iv, 1
1054  %exitcond = icmp eq i64 %indvars.iv.next, %n
1055  br i1 %exitcond, label %latchexit, label %header
1056
1057latchexit:                                          ; preds = %latch
1058  %sum.0.lcssa = phi i32 [ %add, %latch ]
1059  ret i32 %sum.0.lcssa
1060
1061otherexit:
1062  %rval = phi i32 [%sum.02, %for.exiting_block ]
1063  br label %otherexit2
1064
1065otherexit2:
1066  %rval2 = call i32(...) @llvm.experimental.deoptimize.i32() [ "deopt"(i32 %sum.02) ]
1067  ret i32 %rval2
1068}
1069
1070declare i32 @llvm.experimental.deoptimize.i32(...)
1071