xref: /llvm-project/llvm/test/Transforms/LoopUnrollAndJam/unroll-and-jam.ll (revision eeb0884e6696ec618feb2181a432d10f66d4e840)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -passes=loop-unroll-and-jam -allow-unroll-and-jam -unroll-and-jam-count=4 -unroll-remainder < %s -S | FileCheck %s
3; RUN: opt -aa-pipeline=tbaa,basic-aa -passes='loop-unroll-and-jam' -allow-unroll-and-jam -unroll-and-jam-count=4 -unroll-remainder < %s -S | FileCheck %s
4
5target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
6
7; Tests for(i) { sum = 0; for(j) sum += B[j]; A[i] = sum; }
8define void @test1(i32 %I, i32 %E, ptr noalias nocapture %A, ptr noalias nocapture readonly %B) #0 {
9; CHECK-LABEL: @test1(
10; CHECK-NEXT:  entry:
11; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[E:%.*]], 0
12; CHECK-NEXT:    [[CMPJ:%.*]] = icmp ne i32 [[I:%.*]], 0
13; CHECK-NEXT:    [[OR_COND:%.*]] = and i1 [[CMP]], [[CMPJ]]
14; CHECK-NEXT:    br i1 [[OR_COND]], label [[FOR_OUTER_PREHEADER:%.*]], label [[FOR_END:%.*]]
15; CHECK:       for.outer.preheader:
16; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[I]], -1
17; CHECK-NEXT:    [[XTRAITER:%.*]] = and i32 [[I]], 3
18; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 [[TMP0]], 3
19; CHECK-NEXT:    br i1 [[TMP1]], label [[FOR_END_LOOPEXIT_UNR_LCSSA:%.*]], label [[FOR_OUTER_PREHEADER_NEW:%.*]]
20; CHECK:       for.outer.preheader.new:
21; CHECK-NEXT:    [[UNROLL_ITER:%.*]] = sub i32 [[I]], [[XTRAITER]]
22; CHECK-NEXT:    br label [[FOR_OUTER:%.*]]
23; CHECK:       for.outer:
24; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[ADD8_3:%.*]], [[FOR_LATCH:%.*]] ], [ 0, [[FOR_OUTER_PREHEADER_NEW]] ]
25; CHECK-NEXT:    [[NITER:%.*]] = phi i32 [ 0, [[FOR_OUTER_PREHEADER_NEW]] ], [ [[NITER_NEXT_3:%.*]], [[FOR_LATCH]] ]
26; CHECK-NEXT:    [[ADD8:%.*]] = add nuw nsw i32 [[I]], 1
27; CHECK-NEXT:    [[ADD8_1:%.*]] = add nuw nsw i32 [[I]], 2
28; CHECK-NEXT:    [[ADD8_2:%.*]] = add nuw nsw i32 [[I]], 3
29; CHECK-NEXT:    [[ADD8_3]] = add nuw i32 [[I]], 4
30; CHECK-NEXT:    [[NITER_NEXT_3]] = add i32 [[NITER]], 4
31; CHECK-NEXT:    br label [[FOR_INNER:%.*]]
32; CHECK:       for.inner:
33; CHECK-NEXT:    [[J:%.*]] = phi i32 [ 0, [[FOR_OUTER]] ], [ [[INC:%.*]], [[FOR_INNER]] ]
34; CHECK-NEXT:    [[SUM:%.*]] = phi i32 [ 0, [[FOR_OUTER]] ], [ [[ADD:%.*]], [[FOR_INNER]] ]
35; CHECK-NEXT:    [[J_1:%.*]] = phi i32 [ 0, [[FOR_OUTER]] ], [ [[INC_1:%.*]], [[FOR_INNER]] ]
36; CHECK-NEXT:    [[SUM_1:%.*]] = phi i32 [ 0, [[FOR_OUTER]] ], [ [[ADD_1:%.*]], [[FOR_INNER]] ]
37; CHECK-NEXT:    [[J_2:%.*]] = phi i32 [ 0, [[FOR_OUTER]] ], [ [[INC_2:%.*]], [[FOR_INNER]] ]
38; CHECK-NEXT:    [[SUM_2:%.*]] = phi i32 [ 0, [[FOR_OUTER]] ], [ [[ADD_2:%.*]], [[FOR_INNER]] ]
39; CHECK-NEXT:    [[J_3:%.*]] = phi i32 [ 0, [[FOR_OUTER]] ], [ [[INC_3:%.*]], [[FOR_INNER]] ]
40; CHECK-NEXT:    [[SUM_3:%.*]] = phi i32 [ 0, [[FOR_OUTER]] ], [ [[ADD_3:%.*]], [[FOR_INNER]] ]
41; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[B:%.*]], i32 [[J]]
42; CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA0:![0-9]+]]
43; CHECK-NEXT:    [[ADD]] = add i32 [[TMP2]], [[SUM]]
44; CHECK-NEXT:    [[INC]] = add nuw i32 [[J]], 1
45; CHECK-NEXT:    [[ARRAYIDX_1:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[J_1]]
46; CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[ARRAYIDX_1]], align 4, !tbaa [[TBAA0]]
47; CHECK-NEXT:    [[ADD_1]] = add i32 [[TMP3]], [[SUM_1]]
48; CHECK-NEXT:    [[INC_1]] = add nuw i32 [[J_1]], 1
49; CHECK-NEXT:    [[ARRAYIDX_2:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[J_2]]
50; CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[ARRAYIDX_2]], align 4, !tbaa [[TBAA0]]
51; CHECK-NEXT:    [[ADD_2]] = add i32 [[TMP4]], [[SUM_2]]
52; CHECK-NEXT:    [[INC_2]] = add nuw i32 [[J_2]], 1
53; CHECK-NEXT:    [[ARRAYIDX_3:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[J_3]]
54; CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[ARRAYIDX_3]], align 4, !tbaa [[TBAA0]]
55; CHECK-NEXT:    [[ADD_3]] = add i32 [[TMP5]], [[SUM_3]]
56; CHECK-NEXT:    [[INC_3]] = add nuw i32 [[J_3]], 1
57; CHECK-NEXT:    [[EXITCOND_3:%.*]] = icmp eq i32 [[INC_3]], [[E]]
58; CHECK-NEXT:    br i1 [[EXITCOND_3]], label [[FOR_LATCH]], label [[FOR_INNER]]
59; CHECK:       for.latch:
60; CHECK-NEXT:    [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[FOR_INNER]] ]
61; CHECK-NEXT:    [[ADD_LCSSA_1:%.*]] = phi i32 [ [[ADD_1]], [[FOR_INNER]] ]
62; CHECK-NEXT:    [[ADD_LCSSA_2:%.*]] = phi i32 [ [[ADD_2]], [[FOR_INNER]] ]
63; CHECK-NEXT:    [[ADD_LCSSA_3:%.*]] = phi i32 [ [[ADD_3]], [[FOR_INNER]] ]
64; CHECK-NEXT:    [[ARRAYIDX6:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[I]]
65; CHECK-NEXT:    store i32 [[ADD_LCSSA]], ptr [[ARRAYIDX6]], align 4, !tbaa [[TBAA0]]
66; CHECK-NEXT:    [[ARRAYIDX6_1:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[ADD8]]
67; CHECK-NEXT:    store i32 [[ADD_LCSSA_1]], ptr [[ARRAYIDX6_1]], align 4, !tbaa [[TBAA0]]
68; CHECK-NEXT:    [[ARRAYIDX6_2:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[ADD8_1]]
69; CHECK-NEXT:    store i32 [[ADD_LCSSA_2]], ptr [[ARRAYIDX6_2]], align 4, !tbaa [[TBAA0]]
70; CHECK-NEXT:    [[ARRAYIDX6_3:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[ADD8_2]]
71; CHECK-NEXT:    store i32 [[ADD_LCSSA_3]], ptr [[ARRAYIDX6_3]], align 4, !tbaa [[TBAA0]]
72; CHECK-NEXT:    [[NITER_NCMP_3:%.*]] = icmp eq i32 [[NITER_NEXT_3]], [[UNROLL_ITER]]
73; CHECK-NEXT:    br i1 [[NITER_NCMP_3]], label [[FOR_END_LOOPEXIT_UNR_LCSSA_LOOPEXIT:%.*]], label [[FOR_OUTER]], !llvm.loop [[LOOP4:![0-9]+]]
74; CHECK:       for.end.loopexit.unr-lcssa.loopexit:
75; CHECK-NEXT:    [[I_UNR_PH:%.*]] = phi i32 [ [[ADD8_3]], [[FOR_LATCH]] ]
76; CHECK-NEXT:    br label [[FOR_END_LOOPEXIT_UNR_LCSSA]]
77; CHECK:       for.end.loopexit.unr-lcssa:
78; CHECK-NEXT:    [[I_UNR:%.*]] = phi i32 [ 0, [[FOR_OUTER_PREHEADER]] ], [ [[I_UNR_PH]], [[FOR_END_LOOPEXIT_UNR_LCSSA_LOOPEXIT]] ]
79; CHECK-NEXT:    [[LCMP_MOD:%.*]] = icmp ne i32 [[XTRAITER]], 0
80; CHECK-NEXT:    br i1 [[LCMP_MOD]], label [[FOR_OUTER_EPIL_PREHEADER:%.*]], label [[FOR_END_LOOPEXIT:%.*]]
81; CHECK:       for.outer.epil.preheader:
82; CHECK-NEXT:    br label [[FOR_OUTER_EPIL:%.*]]
83; CHECK:       for.outer.epil:
84; CHECK-NEXT:    br label [[FOR_INNER_EPIL:%.*]]
85; CHECK:       for.inner.epil:
86; CHECK-NEXT:    [[J_EPIL:%.*]] = phi i32 [ 0, [[FOR_OUTER_EPIL]] ], [ [[INC_EPIL:%.*]], [[FOR_INNER_EPIL]] ]
87; CHECK-NEXT:    [[SUM_EPIL:%.*]] = phi i32 [ 0, [[FOR_OUTER_EPIL]] ], [ [[ADD_EPIL:%.*]], [[FOR_INNER_EPIL]] ]
88; CHECK-NEXT:    [[ARRAYIDX_EPIL:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[J_EPIL]]
89; CHECK-NEXT:    [[TMP6:%.*]] = load i32, ptr [[ARRAYIDX_EPIL]], align 4, !tbaa [[TBAA0]]
90; CHECK-NEXT:    [[ADD_EPIL]] = add i32 [[TMP6]], [[SUM_EPIL]]
91; CHECK-NEXT:    [[INC_EPIL]] = add nuw i32 [[J_EPIL]], 1
92; CHECK-NEXT:    [[EXITCOND_EPIL:%.*]] = icmp eq i32 [[INC_EPIL]], [[E]]
93; CHECK-NEXT:    br i1 [[EXITCOND_EPIL]], label [[FOR_LATCH_EPIL:%.*]], label [[FOR_INNER_EPIL]]
94; CHECK:       for.latch.epil:
95; CHECK-NEXT:    [[ADD_LCSSA_EPIL:%.*]] = phi i32 [ [[ADD_EPIL]], [[FOR_INNER_EPIL]] ]
96; CHECK-NEXT:    [[ARRAYIDX6_EPIL:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_UNR]]
97; CHECK-NEXT:    store i32 [[ADD_LCSSA_EPIL]], ptr [[ARRAYIDX6_EPIL]], align 4, !tbaa [[TBAA0]]
98; CHECK-NEXT:    [[ADD8_EPIL:%.*]] = add nuw i32 [[I_UNR]], 1
99; CHECK-NEXT:    [[EPIL_ITER_CMP:%.*]] = icmp ne i32 1, [[XTRAITER]]
100; CHECK-NEXT:    br i1 [[EPIL_ITER_CMP]], label [[FOR_OUTER_EPIL_1:%.*]], label [[FOR_END_LOOPEXIT_EPILOG_LCSSA:%.*]]
101; CHECK:       for.outer.epil.1:
102; CHECK-NEXT:    br label [[FOR_INNER_EPIL_1:%.*]]
103; CHECK:       for.inner.epil.1:
104; CHECK-NEXT:    [[J_EPIL_1:%.*]] = phi i32 [ 0, [[FOR_OUTER_EPIL_1]] ], [ [[INC_EPIL_1:%.*]], [[FOR_INNER_EPIL_1]] ]
105; CHECK-NEXT:    [[SUM_EPIL_1:%.*]] = phi i32 [ 0, [[FOR_OUTER_EPIL_1]] ], [ [[ADD_EPIL_1:%.*]], [[FOR_INNER_EPIL_1]] ]
106; CHECK-NEXT:    [[ARRAYIDX_EPIL_1:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[J_EPIL_1]]
107; CHECK-NEXT:    [[TMP7:%.*]] = load i32, ptr [[ARRAYIDX_EPIL_1]], align 4, !tbaa [[TBAA0]]
108; CHECK-NEXT:    [[ADD_EPIL_1]] = add i32 [[TMP7]], [[SUM_EPIL_1]]
109; CHECK-NEXT:    [[INC_EPIL_1]] = add nuw i32 [[J_EPIL_1]], 1
110; CHECK-NEXT:    [[EXITCOND_EPIL_1:%.*]] = icmp eq i32 [[INC_EPIL_1]], [[E]]
111; CHECK-NEXT:    br i1 [[EXITCOND_EPIL_1]], label [[FOR_LATCH_EPIL_1:%.*]], label [[FOR_INNER_EPIL_1]]
112; CHECK:       for.latch.epil.1:
113; CHECK-NEXT:    [[ADD_LCSSA_EPIL_1:%.*]] = phi i32 [ [[ADD_EPIL_1]], [[FOR_INNER_EPIL_1]] ]
114; CHECK-NEXT:    [[ARRAYIDX6_EPIL_1:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[ADD8_EPIL]]
115; CHECK-NEXT:    store i32 [[ADD_LCSSA_EPIL_1]], ptr [[ARRAYIDX6_EPIL_1]], align 4, !tbaa [[TBAA0]]
116; CHECK-NEXT:    [[ADD8_EPIL_1:%.*]] = add nuw i32 [[I_UNR]], 2
117; CHECK-NEXT:    [[EPIL_ITER_CMP_1:%.*]] = icmp ne i32 2, [[XTRAITER]]
118; CHECK-NEXT:    br i1 [[EPIL_ITER_CMP_1]], label [[FOR_OUTER_EPIL_2:%.*]], label [[FOR_END_LOOPEXIT_EPILOG_LCSSA]]
119; CHECK:       for.outer.epil.2:
120; CHECK-NEXT:    br label [[FOR_INNER_EPIL_2:%.*]]
121; CHECK:       for.inner.epil.2:
122; CHECK-NEXT:    [[J_EPIL_2:%.*]] = phi i32 [ 0, [[FOR_OUTER_EPIL_2]] ], [ [[INC_EPIL_2:%.*]], [[FOR_INNER_EPIL_2]] ]
123; CHECK-NEXT:    [[SUM_EPIL_2:%.*]] = phi i32 [ 0, [[FOR_OUTER_EPIL_2]] ], [ [[ADD_EPIL_2:%.*]], [[FOR_INNER_EPIL_2]] ]
124; CHECK-NEXT:    [[ARRAYIDX_EPIL_2:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[J_EPIL_2]]
125; CHECK-NEXT:    [[TMP8:%.*]] = load i32, ptr [[ARRAYIDX_EPIL_2]], align 4, !tbaa [[TBAA0]]
126; CHECK-NEXT:    [[ADD_EPIL_2]] = add i32 [[TMP8]], [[SUM_EPIL_2]]
127; CHECK-NEXT:    [[INC_EPIL_2]] = add nuw i32 [[J_EPIL_2]], 1
128; CHECK-NEXT:    [[EXITCOND_EPIL_2:%.*]] = icmp eq i32 [[INC_EPIL_2]], [[E]]
129; CHECK-NEXT:    br i1 [[EXITCOND_EPIL_2]], label [[FOR_LATCH_EPIL_2:%.*]], label [[FOR_INNER_EPIL_2]]
130; CHECK:       for.latch.epil.2:
131; CHECK-NEXT:    [[ADD_LCSSA_EPIL_2:%.*]] = phi i32 [ [[ADD_EPIL_2]], [[FOR_INNER_EPIL_2]] ]
132; CHECK-NEXT:    [[ARRAYIDX6_EPIL_2:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[ADD8_EPIL_1]]
133; CHECK-NEXT:    store i32 [[ADD_LCSSA_EPIL_2]], ptr [[ARRAYIDX6_EPIL_2]], align 4, !tbaa [[TBAA0]]
134; CHECK-NEXT:    br label [[FOR_END_LOOPEXIT_EPILOG_LCSSA]]
135; CHECK:       for.end.loopexit.epilog-lcssa:
136; CHECK-NEXT:    br label [[FOR_END_LOOPEXIT]]
137; CHECK:       for.end.loopexit:
138; CHECK-NEXT:    br label [[FOR_END]]
139; CHECK:       for.end:
140; CHECK-NEXT:    ret void
141;
142entry:
143  %cmp = icmp ne i32 %E, 0
144  %cmpJ = icmp ne i32 %I, 0
145  %or.cond = and i1 %cmp, %cmpJ
146  br i1 %or.cond, label %for.outer.preheader, label %for.end
147
148for.outer.preheader:
149  br label %for.outer
150
151for.outer:
152  %i = phi i32 [ %add8, %for.latch ], [ 0, %for.outer.preheader ]
153  br label %for.inner
154
155for.inner:
156  %j = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ]
157  %sum = phi i32 [ 0, %for.outer ], [ %add, %for.inner ]
158  %arrayidx = getelementptr inbounds i32, ptr %B, i32 %j
159  %0 = load i32, ptr %arrayidx, align 4, !tbaa !5
160  %add = add i32 %0, %sum
161  %inc = add nuw i32 %j, 1
162  %exitcond = icmp eq i32 %inc, %E
163  br i1 %exitcond, label %for.latch, label %for.inner
164
165for.latch:
166  %add.lcssa = phi i32 [ %add, %for.inner ]
167  %arrayidx6 = getelementptr inbounds i32, ptr %A, i32 %i
168  store i32 %add.lcssa, ptr %arrayidx6, align 4, !tbaa !5
169  %add8 = add nuw i32 %i, 1
170  %exitcond25 = icmp eq i32 %add8, %I
171  br i1 %exitcond25, label %for.end.loopexit, label %for.outer
172
173for.end.loopexit:
174  br label %for.end
175
176for.end:
177  ret void
178}
179
180
181; Tests for(i) { sum = A[i]; for(j) sum += B[j]; A[i] = sum; }
182; A[i] load/store dependency should not block unroll-and-jam
183define void @test2(i32 %I, i32 %E, ptr noalias nocapture %A, ptr noalias nocapture readonly %B) #0 {
184; CHECK-LABEL: @test2(
185; CHECK-NEXT:  entry:
186; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[E:%.*]], 0
187; CHECK-NEXT:    [[CMP125:%.*]] = icmp ne i32 [[I:%.*]], 0
188; CHECK-NEXT:    [[OR_COND:%.*]] = and i1 [[CMP]], [[CMP125]]
189; CHECK-NEXT:    br i1 [[OR_COND]], label [[FOR_OUTER_PREHEADER:%.*]], label [[FOR_END10:%.*]]
190; CHECK:       for.outer.preheader:
191; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[I]], -1
192; CHECK-NEXT:    [[XTRAITER:%.*]] = and i32 [[I]], 3
193; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 [[TMP0]], 3
194; CHECK-NEXT:    br i1 [[TMP1]], label [[FOR_END10_LOOPEXIT_UNR_LCSSA:%.*]], label [[FOR_OUTER_PREHEADER_NEW:%.*]]
195; CHECK:       for.outer.preheader.new:
196; CHECK-NEXT:    [[UNROLL_ITER:%.*]] = sub i32 [[I]], [[XTRAITER]]
197; CHECK-NEXT:    br label [[FOR_OUTER:%.*]]
198; CHECK:       for.outer:
199; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[ADD9_3:%.*]], [[FOR_LATCH:%.*]] ], [ 0, [[FOR_OUTER_PREHEADER_NEW]] ]
200; CHECK-NEXT:    [[NITER:%.*]] = phi i32 [ 0, [[FOR_OUTER_PREHEADER_NEW]] ], [ [[NITER_NEXT_3:%.*]], [[FOR_LATCH]] ]
201; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[I]]
202; CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA0]]
203; CHECK-NEXT:    [[ADD9:%.*]] = add nuw nsw i32 [[I]], 1
204; CHECK-NEXT:    [[ARRAYIDX_1:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[ADD9]]
205; CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[ARRAYIDX_1]], align 4, !tbaa [[TBAA0]]
206; CHECK-NEXT:    [[ADD9_1:%.*]] = add nuw nsw i32 [[I]], 2
207; CHECK-NEXT:    [[ARRAYIDX_2:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[ADD9_1]]
208; CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[ARRAYIDX_2]], align 4, !tbaa [[TBAA0]]
209; CHECK-NEXT:    [[ADD9_2:%.*]] = add nuw nsw i32 [[I]], 3
210; CHECK-NEXT:    [[ARRAYIDX_3:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[ADD9_2]]
211; CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[ARRAYIDX_3]], align 4, !tbaa [[TBAA0]]
212; CHECK-NEXT:    [[ADD9_3]] = add nuw i32 [[I]], 4
213; CHECK-NEXT:    [[NITER_NEXT_3]] = add i32 [[NITER]], 4
214; CHECK-NEXT:    br label [[FOR_INNER:%.*]]
215; CHECK:       for.inner:
216; CHECK-NEXT:    [[J:%.*]] = phi i32 [ 0, [[FOR_OUTER]] ], [ [[INC:%.*]], [[FOR_INNER]] ]
217; CHECK-NEXT:    [[SUM:%.*]] = phi i32 [ [[TMP2]], [[FOR_OUTER]] ], [ [[ADD:%.*]], [[FOR_INNER]] ]
218; CHECK-NEXT:    [[J_1:%.*]] = phi i32 [ 0, [[FOR_OUTER]] ], [ [[INC_1:%.*]], [[FOR_INNER]] ]
219; CHECK-NEXT:    [[SUM_1:%.*]] = phi i32 [ [[TMP3]], [[FOR_OUTER]] ], [ [[ADD_1:%.*]], [[FOR_INNER]] ]
220; CHECK-NEXT:    [[J_2:%.*]] = phi i32 [ 0, [[FOR_OUTER]] ], [ [[INC_2:%.*]], [[FOR_INNER]] ]
221; CHECK-NEXT:    [[SUM_2:%.*]] = phi i32 [ [[TMP4]], [[FOR_OUTER]] ], [ [[ADD_2:%.*]], [[FOR_INNER]] ]
222; CHECK-NEXT:    [[J_3:%.*]] = phi i32 [ 0, [[FOR_OUTER]] ], [ [[INC_3:%.*]], [[FOR_INNER]] ]
223; CHECK-NEXT:    [[SUM_3:%.*]] = phi i32 [ [[TMP5]], [[FOR_OUTER]] ], [ [[ADD_3:%.*]], [[FOR_INNER]] ]
224; CHECK-NEXT:    [[ARRAYIDX6:%.*]] = getelementptr inbounds i32, ptr [[B:%.*]], i32 [[J]]
225; CHECK-NEXT:    [[TMP6:%.*]] = load i32, ptr [[ARRAYIDX6]], align 4, !tbaa [[TBAA0]]
226; CHECK-NEXT:    [[ADD]] = add i32 [[TMP6]], [[SUM]]
227; CHECK-NEXT:    [[INC]] = add nuw i32 [[J]], 1
228; CHECK-NEXT:    [[ARRAYIDX6_1:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[J_1]]
229; CHECK-NEXT:    [[TMP7:%.*]] = load i32, ptr [[ARRAYIDX6_1]], align 4, !tbaa [[TBAA0]]
230; CHECK-NEXT:    [[ADD_1]] = add i32 [[TMP7]], [[SUM_1]]
231; CHECK-NEXT:    [[INC_1]] = add nuw i32 [[J_1]], 1
232; CHECK-NEXT:    [[ARRAYIDX6_2:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[J_2]]
233; CHECK-NEXT:    [[TMP8:%.*]] = load i32, ptr [[ARRAYIDX6_2]], align 4, !tbaa [[TBAA0]]
234; CHECK-NEXT:    [[ADD_2]] = add i32 [[TMP8]], [[SUM_2]]
235; CHECK-NEXT:    [[INC_2]] = add nuw i32 [[J_2]], 1
236; CHECK-NEXT:    [[ARRAYIDX6_3:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[J_3]]
237; CHECK-NEXT:    [[TMP9:%.*]] = load i32, ptr [[ARRAYIDX6_3]], align 4, !tbaa [[TBAA0]]
238; CHECK-NEXT:    [[ADD_3]] = add i32 [[TMP9]], [[SUM_3]]
239; CHECK-NEXT:    [[INC_3]] = add nuw i32 [[J_3]], 1
240; CHECK-NEXT:    [[EXITCOND_3:%.*]] = icmp eq i32 [[INC_3]], [[E]]
241; CHECK-NEXT:    br i1 [[EXITCOND_3]], label [[FOR_LATCH]], label [[FOR_INNER]]
242; CHECK:       for.latch:
243; CHECK-NEXT:    [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[FOR_INNER]] ]
244; CHECK-NEXT:    [[ADD_LCSSA_1:%.*]] = phi i32 [ [[ADD_1]], [[FOR_INNER]] ]
245; CHECK-NEXT:    [[ADD_LCSSA_2:%.*]] = phi i32 [ [[ADD_2]], [[FOR_INNER]] ]
246; CHECK-NEXT:    [[ADD_LCSSA_3:%.*]] = phi i32 [ [[ADD_3]], [[FOR_INNER]] ]
247; CHECK-NEXT:    store i32 [[ADD_LCSSA]], ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA0]]
248; CHECK-NEXT:    store i32 [[ADD_LCSSA_1]], ptr [[ARRAYIDX_1]], align 4, !tbaa [[TBAA0]]
249; CHECK-NEXT:    store i32 [[ADD_LCSSA_2]], ptr [[ARRAYIDX_2]], align 4, !tbaa [[TBAA0]]
250; CHECK-NEXT:    store i32 [[ADD_LCSSA_3]], ptr [[ARRAYIDX_3]], align 4, !tbaa [[TBAA0]]
251; CHECK-NEXT:    [[NITER_NCMP_3:%.*]] = icmp eq i32 [[NITER_NEXT_3]], [[UNROLL_ITER]]
252; CHECK-NEXT:    br i1 [[NITER_NCMP_3]], label [[FOR_END10_LOOPEXIT_UNR_LCSSA_LOOPEXIT:%.*]], label [[FOR_OUTER]], !llvm.loop [[LOOP6:![0-9]+]]
253; CHECK:       for.end10.loopexit.unr-lcssa.loopexit:
254; CHECK-NEXT:    [[I_UNR_PH:%.*]] = phi i32 [ [[ADD9_3]], [[FOR_LATCH]] ]
255; CHECK-NEXT:    br label [[FOR_END10_LOOPEXIT_UNR_LCSSA]]
256; CHECK:       for.end10.loopexit.unr-lcssa:
257; CHECK-NEXT:    [[I_UNR:%.*]] = phi i32 [ 0, [[FOR_OUTER_PREHEADER]] ], [ [[I_UNR_PH]], [[FOR_END10_LOOPEXIT_UNR_LCSSA_LOOPEXIT]] ]
258; CHECK-NEXT:    [[LCMP_MOD:%.*]] = icmp ne i32 [[XTRAITER]], 0
259; CHECK-NEXT:    br i1 [[LCMP_MOD]], label [[FOR_OUTER_EPIL_PREHEADER:%.*]], label [[FOR_END10_LOOPEXIT:%.*]]
260; CHECK:       for.outer.epil.preheader:
261; CHECK-NEXT:    br label [[FOR_OUTER_EPIL:%.*]]
262; CHECK:       for.outer.epil:
263; CHECK-NEXT:    [[ARRAYIDX_EPIL:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_UNR]]
264; CHECK-NEXT:    [[TMP10:%.*]] = load i32, ptr [[ARRAYIDX_EPIL]], align 4, !tbaa [[TBAA0]]
265; CHECK-NEXT:    br label [[FOR_INNER_EPIL:%.*]]
266; CHECK:       for.inner.epil:
267; CHECK-NEXT:    [[J_EPIL:%.*]] = phi i32 [ 0, [[FOR_OUTER_EPIL]] ], [ [[INC_EPIL:%.*]], [[FOR_INNER_EPIL]] ]
268; CHECK-NEXT:    [[SUM_EPIL:%.*]] = phi i32 [ [[TMP10]], [[FOR_OUTER_EPIL]] ], [ [[ADD_EPIL:%.*]], [[FOR_INNER_EPIL]] ]
269; CHECK-NEXT:    [[ARRAYIDX6_EPIL:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[J_EPIL]]
270; CHECK-NEXT:    [[TMP11:%.*]] = load i32, ptr [[ARRAYIDX6_EPIL]], align 4, !tbaa [[TBAA0]]
271; CHECK-NEXT:    [[ADD_EPIL]] = add i32 [[TMP11]], [[SUM_EPIL]]
272; CHECK-NEXT:    [[INC_EPIL]] = add nuw i32 [[J_EPIL]], 1
273; CHECK-NEXT:    [[EXITCOND_EPIL:%.*]] = icmp eq i32 [[INC_EPIL]], [[E]]
274; CHECK-NEXT:    br i1 [[EXITCOND_EPIL]], label [[FOR_LATCH_EPIL:%.*]], label [[FOR_INNER_EPIL]]
275; CHECK:       for.latch.epil:
276; CHECK-NEXT:    [[ADD_LCSSA_EPIL:%.*]] = phi i32 [ [[ADD_EPIL]], [[FOR_INNER_EPIL]] ]
277; CHECK-NEXT:    store i32 [[ADD_LCSSA_EPIL]], ptr [[ARRAYIDX_EPIL]], align 4, !tbaa [[TBAA0]]
278; CHECK-NEXT:    [[ADD9_EPIL:%.*]] = add nuw i32 [[I_UNR]], 1
279; CHECK-NEXT:    [[EPIL_ITER_CMP:%.*]] = icmp ne i32 1, [[XTRAITER]]
280; CHECK-NEXT:    br i1 [[EPIL_ITER_CMP]], label [[FOR_OUTER_EPIL_1:%.*]], label [[FOR_END10_LOOPEXIT_EPILOG_LCSSA:%.*]]
281; CHECK:       for.outer.epil.1:
282; CHECK-NEXT:    [[ARRAYIDX_EPIL_1:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[ADD9_EPIL]]
283; CHECK-NEXT:    [[TMP12:%.*]] = load i32, ptr [[ARRAYIDX_EPIL_1]], align 4, !tbaa [[TBAA0]]
284; CHECK-NEXT:    br label [[FOR_INNER_EPIL_1:%.*]]
285; CHECK:       for.inner.epil.1:
286; CHECK-NEXT:    [[J_EPIL_1:%.*]] = phi i32 [ 0, [[FOR_OUTER_EPIL_1]] ], [ [[INC_EPIL_1:%.*]], [[FOR_INNER_EPIL_1]] ]
287; CHECK-NEXT:    [[SUM_EPIL_1:%.*]] = phi i32 [ [[TMP12]], [[FOR_OUTER_EPIL_1]] ], [ [[ADD_EPIL_1:%.*]], [[FOR_INNER_EPIL_1]] ]
288; CHECK-NEXT:    [[ARRAYIDX6_EPIL_1:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[J_EPIL_1]]
289; CHECK-NEXT:    [[TMP13:%.*]] = load i32, ptr [[ARRAYIDX6_EPIL_1]], align 4, !tbaa [[TBAA0]]
290; CHECK-NEXT:    [[ADD_EPIL_1]] = add i32 [[TMP13]], [[SUM_EPIL_1]]
291; CHECK-NEXT:    [[INC_EPIL_1]] = add nuw i32 [[J_EPIL_1]], 1
292; CHECK-NEXT:    [[EXITCOND_EPIL_1:%.*]] = icmp eq i32 [[INC_EPIL_1]], [[E]]
293; CHECK-NEXT:    br i1 [[EXITCOND_EPIL_1]], label [[FOR_LATCH_EPIL_1:%.*]], label [[FOR_INNER_EPIL_1]]
294; CHECK:       for.latch.epil.1:
295; CHECK-NEXT:    [[ADD_LCSSA_EPIL_1:%.*]] = phi i32 [ [[ADD_EPIL_1]], [[FOR_INNER_EPIL_1]] ]
296; CHECK-NEXT:    store i32 [[ADD_LCSSA_EPIL_1]], ptr [[ARRAYIDX_EPIL_1]], align 4, !tbaa [[TBAA0]]
297; CHECK-NEXT:    [[ADD9_EPIL_1:%.*]] = add nuw i32 [[I_UNR]], 2
298; CHECK-NEXT:    [[EPIL_ITER_CMP_1:%.*]] = icmp ne i32 2, [[XTRAITER]]
299; CHECK-NEXT:    br i1 [[EPIL_ITER_CMP_1]], label [[FOR_OUTER_EPIL_2:%.*]], label [[FOR_END10_LOOPEXIT_EPILOG_LCSSA]]
300; CHECK:       for.outer.epil.2:
301; CHECK-NEXT:    [[ARRAYIDX_EPIL_2:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[ADD9_EPIL_1]]
302; CHECK-NEXT:    [[TMP14:%.*]] = load i32, ptr [[ARRAYIDX_EPIL_2]], align 4, !tbaa [[TBAA0]]
303; CHECK-NEXT:    br label [[FOR_INNER_EPIL_2:%.*]]
304; CHECK:       for.inner.epil.2:
305; CHECK-NEXT:    [[J_EPIL_2:%.*]] = phi i32 [ 0, [[FOR_OUTER_EPIL_2]] ], [ [[INC_EPIL_2:%.*]], [[FOR_INNER_EPIL_2]] ]
306; CHECK-NEXT:    [[SUM_EPIL_2:%.*]] = phi i32 [ [[TMP14]], [[FOR_OUTER_EPIL_2]] ], [ [[ADD_EPIL_2:%.*]], [[FOR_INNER_EPIL_2]] ]
307; CHECK-NEXT:    [[ARRAYIDX6_EPIL_2:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[J_EPIL_2]]
308; CHECK-NEXT:    [[TMP15:%.*]] = load i32, ptr [[ARRAYIDX6_EPIL_2]], align 4, !tbaa [[TBAA0]]
309; CHECK-NEXT:    [[ADD_EPIL_2]] = add i32 [[TMP15]], [[SUM_EPIL_2]]
310; CHECK-NEXT:    [[INC_EPIL_2]] = add nuw i32 [[J_EPIL_2]], 1
311; CHECK-NEXT:    [[EXITCOND_EPIL_2:%.*]] = icmp eq i32 [[INC_EPIL_2]], [[E]]
312; CHECK-NEXT:    br i1 [[EXITCOND_EPIL_2]], label [[FOR_LATCH_EPIL_2:%.*]], label [[FOR_INNER_EPIL_2]]
313; CHECK:       for.latch.epil.2:
314; CHECK-NEXT:    [[ADD_LCSSA_EPIL_2:%.*]] = phi i32 [ [[ADD_EPIL_2]], [[FOR_INNER_EPIL_2]] ]
315; CHECK-NEXT:    store i32 [[ADD_LCSSA_EPIL_2]], ptr [[ARRAYIDX_EPIL_2]], align 4, !tbaa [[TBAA0]]
316; CHECK-NEXT:    br label [[FOR_END10_LOOPEXIT_EPILOG_LCSSA]]
317; CHECK:       for.end10.loopexit.epilog-lcssa:
318; CHECK-NEXT:    br label [[FOR_END10_LOOPEXIT]]
319; CHECK:       for.end10.loopexit:
320; CHECK-NEXT:    br label [[FOR_END10]]
321; CHECK:       for.end10:
322; CHECK-NEXT:    ret void
323;
324entry:
325  %cmp = icmp ne i32 %E, 0
326  %cmp125 = icmp ne i32 %I, 0
327  %or.cond = and i1 %cmp, %cmp125
328  br i1 %or.cond, label %for.outer.preheader, label %for.end10
329
330for.outer.preheader:
331  br label %for.outer
332
333for.outer:
334  %i = phi i32 [ %add9, %for.latch ], [ 0, %for.outer.preheader ]
335  %arrayidx = getelementptr inbounds i32, ptr %A, i32 %i
336  %0 = load i32, ptr %arrayidx, align 4, !tbaa !5
337  br label %for.inner
338
339for.inner:
340  %j = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ]
341  %sum = phi i32 [ %0, %for.outer ], [ %add, %for.inner ]
342  %arrayidx6 = getelementptr inbounds i32, ptr %B, i32 %j
343  %1 = load i32, ptr %arrayidx6, align 4, !tbaa !5
344  %add = add i32 %1, %sum
345  %inc = add nuw i32 %j, 1
346  %exitcond = icmp eq i32 %inc, %E
347  br i1 %exitcond, label %for.latch, label %for.inner
348
349for.latch:
350  %add.lcssa = phi i32 [ %add, %for.inner ]
351  store i32 %add.lcssa, ptr %arrayidx, align 4, !tbaa !5
352  %add9 = add nuw i32 %i, 1
353  %exitcond28 = icmp eq i32 %add9, %I
354  br i1 %exitcond28, label %for.end10.loopexit, label %for.outer
355
356for.end10.loopexit:
357  br label %for.end10
358
359for.end10:
360  ret void
361}
362
363
364; Tests Complete unroll-and-jam of the outer loop
365define void @test3(i32 %I, i32 %E, ptr noalias nocapture %A, ptr noalias nocapture readonly %B) #0 {
366; CHECK-LABEL: @test3(
367; CHECK-NEXT:  entry:
368; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[E:%.*]], 0
369; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_END:%.*]], label [[FOR_PREHEADER:%.*]]
370; CHECK:       for.preheader:
371; CHECK-NEXT:    br label [[FOR_OUTER:%.*]]
372; CHECK:       for.outer:
373; CHECK-NEXT:    br label [[FOR_INNER:%.*]]
374; CHECK:       for.inner:
375; CHECK-NEXT:    [[J:%.*]] = phi i32 [ 0, [[FOR_OUTER]] ], [ [[INC:%.*]], [[FOR_INNER]] ]
376; CHECK-NEXT:    [[SUM:%.*]] = phi i32 [ 0, [[FOR_OUTER]] ], [ [[ADD:%.*]], [[FOR_INNER]] ]
377; CHECK-NEXT:    [[J_1:%.*]] = phi i32 [ 0, [[FOR_OUTER]] ], [ [[INC_1:%.*]], [[FOR_INNER]] ]
378; CHECK-NEXT:    [[SUM_1:%.*]] = phi i32 [ 0, [[FOR_OUTER]] ], [ [[ADD_1:%.*]], [[FOR_INNER]] ]
379; CHECK-NEXT:    [[J_2:%.*]] = phi i32 [ 0, [[FOR_OUTER]] ], [ [[INC_2:%.*]], [[FOR_INNER]] ]
380; CHECK-NEXT:    [[SUM_2:%.*]] = phi i32 [ 0, [[FOR_OUTER]] ], [ [[ADD_2:%.*]], [[FOR_INNER]] ]
381; CHECK-NEXT:    [[J_3:%.*]] = phi i32 [ 0, [[FOR_OUTER]] ], [ [[INC_3:%.*]], [[FOR_INNER]] ]
382; CHECK-NEXT:    [[SUM_3:%.*]] = phi i32 [ 0, [[FOR_OUTER]] ], [ [[ADD_3:%.*]], [[FOR_INNER]] ]
383; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[B:%.*]], i32 [[J]]
384; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA0]]
385; CHECK-NEXT:    [[SUB:%.*]] = add i32 [[SUM]], 10
386; CHECK-NEXT:    [[ADD]] = sub i32 [[SUB]], [[TMP0]]
387; CHECK-NEXT:    [[INC]] = add nuw i32 [[J]], 1
388; CHECK-NEXT:    [[ARRAYIDX_1:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[J_1]]
389; CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX_1]], align 4, !tbaa [[TBAA0]]
390; CHECK-NEXT:    [[SUB_1:%.*]] = add i32 [[SUM_1]], 10
391; CHECK-NEXT:    [[ADD_1]] = sub i32 [[SUB_1]], [[TMP1]]
392; CHECK-NEXT:    [[INC_1]] = add nuw i32 [[J_1]], 1
393; CHECK-NEXT:    [[ARRAYIDX_2:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[J_2]]
394; CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX_2]], align 4, !tbaa [[TBAA0]]
395; CHECK-NEXT:    [[SUB_2:%.*]] = add i32 [[SUM_2]], 10
396; CHECK-NEXT:    [[ADD_2]] = sub i32 [[SUB_2]], [[TMP2]]
397; CHECK-NEXT:    [[INC_2]] = add nuw i32 [[J_2]], 1
398; CHECK-NEXT:    [[ARRAYIDX_3:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[J_3]]
399; CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[ARRAYIDX_3]], align 4, !tbaa [[TBAA0]]
400; CHECK-NEXT:    [[SUB_3:%.*]] = add i32 [[SUM_3]], 10
401; CHECK-NEXT:    [[ADD_3]] = sub i32 [[SUB_3]], [[TMP3]]
402; CHECK-NEXT:    [[INC_3]] = add nuw i32 [[J_3]], 1
403; CHECK-NEXT:    [[EXITCOND_3:%.*]] = icmp eq i32 [[INC_3]], [[E]]
404; CHECK-NEXT:    br i1 [[EXITCOND_3]], label [[FOR_LATCH:%.*]], label [[FOR_INNER]]
405; CHECK:       for.latch:
406; CHECK-NEXT:    [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[FOR_INNER]] ]
407; CHECK-NEXT:    [[ADD_LCSSA_1:%.*]] = phi i32 [ [[ADD_1]], [[FOR_INNER]] ]
408; CHECK-NEXT:    [[ADD_LCSSA_2:%.*]] = phi i32 [ [[ADD_2]], [[FOR_INNER]] ]
409; CHECK-NEXT:    [[ADD_LCSSA_3:%.*]] = phi i32 [ [[ADD_3]], [[FOR_INNER]] ]
410; CHECK-NEXT:    store i32 [[ADD_LCSSA]], ptr [[A:%.*]], align 4, !tbaa [[TBAA0]]
411; CHECK-NEXT:    [[ARRAYIDX6_1:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 1
412; CHECK-NEXT:    store i32 [[ADD_LCSSA_1]], ptr [[ARRAYIDX6_1]], align 4, !tbaa [[TBAA0]]
413; CHECK-NEXT:    [[ARRAYIDX6_2:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 2
414; CHECK-NEXT:    store i32 [[ADD_LCSSA_2]], ptr [[ARRAYIDX6_2]], align 4, !tbaa [[TBAA0]]
415; CHECK-NEXT:    [[ARRAYIDX6_3:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 3
416; CHECK-NEXT:    store i32 [[ADD_LCSSA_3]], ptr [[ARRAYIDX6_3]], align 4, !tbaa [[TBAA0]]
417; CHECK-NEXT:    br label [[FOR_END_LOOPEXIT:%.*]]
418; CHECK:       for.end.loopexit:
419; CHECK-NEXT:    br label [[FOR_END]]
420; CHECK:       for.end:
421; CHECK-NEXT:    ret void
422;
423entry:
424  %cmp = icmp eq i32 %E, 0
425  br i1 %cmp, label %for.end, label %for.preheader
426
427for.preheader:
428  br label %for.outer
429
430for.outer:
431  %i = phi i32 [ %add8, %for.latch ], [ 0, %for.preheader ]
432  br label %for.inner
433
434for.inner:
435  %j = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ]
436  %sum = phi i32 [ 0, %for.outer ], [ %add, %for.inner ]
437  %arrayidx = getelementptr inbounds i32, ptr %B, i32 %j
438  %0 = load i32, ptr %arrayidx, align 4, !tbaa !5
439  %sub = add i32 %sum, 10
440  %add = sub i32 %sub, %0
441  %inc = add nuw i32 %j, 1
442  %exitcond = icmp eq i32 %inc, %E
443  br i1 %exitcond, label %for.latch, label %for.inner
444
445for.latch:
446  %arrayidx6 = getelementptr inbounds i32, ptr %A, i32 %i
447  store i32 %add, ptr %arrayidx6, align 4, !tbaa !5
448  %add8 = add nuw nsw i32 %i, 1
449  %exitcond23 = icmp eq i32 %add8, 4
450  br i1 %exitcond23, label %for.end, label %for.outer
451
452for.end:
453  ret void
454}
455
456
457; Tests Complete unroll-and-jam with a trip count of 1
458define void @test4(i32 %I, i32 %E, ptr noalias nocapture %A, ptr noalias nocapture readonly %B) #0 {
459; CHECK-LABEL: @test4(
460; CHECK-NEXT:  entry:
461; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[E:%.*]], 0
462; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_END:%.*]], label [[FOR_PREHEADER:%.*]]
463; CHECK:       for.preheader:
464; CHECK-NEXT:    br label [[FOR_OUTER:%.*]]
465; CHECK:       for.outer:
466; CHECK-NEXT:    br label [[FOR_INNER:%.*]]
467; CHECK:       for.inner:
468; CHECK-NEXT:    [[J:%.*]] = phi i32 [ 0, [[FOR_OUTER]] ], [ [[INC:%.*]], [[FOR_INNER]] ]
469; CHECK-NEXT:    [[SUM:%.*]] = phi i32 [ 0, [[FOR_OUTER]] ], [ [[ADD:%.*]], [[FOR_INNER]] ]
470; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[B:%.*]], i32 [[J]]
471; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA0]]
472; CHECK-NEXT:    [[SUB:%.*]] = add i32 [[SUM]], 10
473; CHECK-NEXT:    [[ADD]] = sub i32 [[SUB]], [[TMP0]]
474; CHECK-NEXT:    [[INC]] = add nuw i32 [[J]], 1
475; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[INC]], [[E]]
476; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_LATCH:%.*]], label [[FOR_INNER]]
477; CHECK:       for.latch:
478; CHECK-NEXT:    [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[FOR_INNER]] ]
479; CHECK-NEXT:    store i32 [[ADD_LCSSA]], ptr [[A:%.*]], align 4, !tbaa [[TBAA0]]
480; CHECK-NEXT:    br label [[FOR_END_LOOPEXIT:%.*]]
481; CHECK:       for.end.loopexit:
482; CHECK-NEXT:    br label [[FOR_END]]
483; CHECK:       for.end:
484; CHECK-NEXT:    ret void
485;
486entry:
487  %cmp = icmp eq i32 %E, 0
488  br i1 %cmp, label %for.end, label %for.preheader
489
490for.preheader:
491  br label %for.outer
492
493for.outer:
494  %i = phi i32 [ %add8, %for.latch ], [ 0, %for.preheader ]
495  br label %for.inner
496
497for.inner:
498  %j = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ]
499  %sum = phi i32 [ 0, %for.outer ], [ %add, %for.inner ]
500  %arrayidx = getelementptr inbounds i32, ptr %B, i32 %j
501  %0 = load i32, ptr %arrayidx, align 4, !tbaa !5
502  %sub = add i32 %sum, 10
503  %add = sub i32 %sub, %0
504  %inc = add nuw i32 %j, 1
505  %exitcond = icmp eq i32 %inc, %E
506  br i1 %exitcond, label %for.latch, label %for.inner
507
508for.latch:
509  %arrayidx6 = getelementptr inbounds i32, ptr %A, i32 %i
510  store i32 %add, ptr %arrayidx6, align 4, !tbaa !5
511  %add8 = add nuw nsw i32 %i, 1
512  %exitcond23 = icmp eq i32 %add8, 1
513  br i1 %exitcond23, label %for.end, label %for.outer
514
515for.end:
516  ret void
517}
518
519
520; Multiple SubLoopBlocks
521@a = hidden global [1 x i32] zeroinitializer, align 4
522define i32 @test5() #0 {
523; CHECK-LABEL: @test5(
524; CHECK-NEXT:  entry:
525; CHECK-NEXT:    br label [[FOR_OUTER:%.*]]
526; CHECK:       for.outer:
527; CHECK-NEXT:    br label [[FOR_INNER:%.*]]
528; CHECK:       for.inner:
529; CHECK-NEXT:    [[INC8_SINK15:%.*]] = phi i32 [ 0, [[FOR_OUTER]] ], [ [[INC8:%.*]], [[FOR_INC_1:%.*]] ]
530; CHECK-NEXT:    [[INC8_SINK15_1:%.*]] = phi i32 [ 0, [[FOR_OUTER]] ], [ [[INC8_1:%.*]], [[FOR_INC_1]] ]
531; CHECK-NEXT:    br label [[FOR_INNER2:%.*]]
532; CHECK:       for.inner2:
533; CHECK-NEXT:    [[L1:%.*]] = load i32, ptr @a, align 4
534; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[L1]], 0
535; CHECK-NEXT:    br i1 [[TOBOOL]], label [[FOR_COND4:%.*]], label [[FOR_INC:%.*]]
536; CHECK:       for.cond4:
537; CHECK-NEXT:    [[L0:%.*]] = load i32, ptr getelementptr inbounds ([1 x i32], ptr @a, i32 1, i32 0), align 4
538; CHECK-NEXT:    [[TOBOOL_1:%.*]] = icmp eq i32 [[L0]], 0
539; CHECK-NEXT:    br i1 [[TOBOOL_1]], label [[FOR_COND4A:%.*]], label [[FOR_INC]]
540; CHECK:       for.cond4a:
541; CHECK-NEXT:    br label [[FOR_INC]]
542; CHECK:       for.inc:
543; CHECK-NEXT:    [[INC8]] = add nuw nsw i32 [[INC8_SINK15]], 1
544; CHECK-NEXT:    [[L1_1:%.*]] = load i32, ptr @a, align 4
545; CHECK-NEXT:    [[TOBOOL_11:%.*]] = icmp eq i32 [[L1_1]], 0
546; CHECK-NEXT:    br i1 [[TOBOOL_11]], label [[FOR_COND4_1:%.*]], label [[FOR_INC_1]]
547; CHECK:       for.latch:
548; CHECK-NEXT:    [[DOTLCSSA_1:%.*]] = phi i32 [ [[L2_1:%.*]], [[FOR_INC_1]] ]
549; CHECK-NEXT:    br label [[FOR_END:%.*]]
550; CHECK:       for.end:
551; CHECK-NEXT:    [[DOTLCSSA_LCSSA:%.*]] = phi i32 [ [[DOTLCSSA_1]], [[FOR_LATCH:%.*]] ]
552; CHECK-NEXT:    ret i32 0
553; CHECK:       for.cond4.1:
554; CHECK-NEXT:    [[L0_1:%.*]] = load i32, ptr getelementptr inbounds ([1 x i32], ptr @a, i32 1, i32 0), align 4
555; CHECK-NEXT:    [[TOBOOL_1_1:%.*]] = icmp eq i32 [[L0_1]], 0
556; CHECK-NEXT:    br i1 [[TOBOOL_1_1]], label [[FOR_COND4A_1:%.*]], label [[FOR_INC_1]]
557; CHECK:       for.cond4a.1:
558; CHECK-NEXT:    br label [[FOR_INC_1]]
559; CHECK:       for.inc.1:
560; CHECK-NEXT:    [[L2_1]] = phi i32 [ 0, [[FOR_INC]] ], [ 1, [[FOR_COND4_1]] ], [ 2, [[FOR_COND4A_1]] ]
561; CHECK-NEXT:    [[INC8_1]] = add nuw nsw i32 [[INC8_SINK15_1]], 1
562; CHECK-NEXT:    [[EXITCOND_1:%.*]] = icmp eq i32 [[INC8_1]], 3
563; CHECK-NEXT:    br i1 [[EXITCOND_1]], label [[FOR_LATCH]], label [[FOR_INNER]]
564;
565entry:
566  br label %for.outer
567
568for.outer:
569  %.sink16 = phi i32 [ 0, %entry ], [ %add, %for.latch ]
570  br label %for.inner
571
572for.inner:
573  %inc8.sink15 = phi i32 [ 0, %for.outer ], [ %inc8, %for.inc ]
574  br label %for.inner2
575
576for.inner2:
577  %l1 = load i32, ptr @a, align 4
578  %tobool = icmp eq i32 %l1, 0
579  br i1 %tobool, label %for.cond4, label %for.inc
580
581for.cond4:
582  %l0 = load i32, ptr getelementptr inbounds ([1 x i32], ptr @a, i32 1, i32 0), align 4
583  %tobool.1 = icmp eq i32 %l0, 0
584  br i1 %tobool.1, label %for.cond4a, label %for.inc
585
586for.cond4a:
587  br label %for.inc
588
589for.inc:
590  %l2 = phi i32 [ 0, %for.inner2 ], [ 1, %for.cond4 ], [ 2, %for.cond4a ]
591  %inc8 = add nuw nsw i32 %inc8.sink15, 1
592  %exitcond = icmp eq i32 %inc8, 3
593  br i1 %exitcond, label %for.latch, label %for.inner
594
595for.latch:
596  %.lcssa = phi i32 [ %l2, %for.inc ]
597  %conv11 = and i32 %.sink16, 255
598  %add = add nuw nsw i32 %conv11, 4
599  %cmp = icmp eq i32 %add, 8
600  br i1 %cmp, label %for.end, label %for.outer
601
602for.end:
603  %.lcssa.lcssa = phi i32 [ %.lcssa, %for.latch ]
604  ret i32 0
605}
606
607
608; Test odd uses of phi nodes
609@f = hidden global i32 0, align 4
610define i32 @test6() #0 {
611; CHECK-LABEL: @test6(
612; CHECK-NEXT:  entry:
613; CHECK-NEXT:    [[F_PROMOTED10:%.*]] = load i32, ptr @f, align 4, !tbaa [[TBAA0]]
614; CHECK-NEXT:    br i1 false, label [[FOR_END_UNR_LCSSA:%.*]], label [[ENTRY_NEW:%.*]]
615; CHECK:       entry.new:
616; CHECK-NEXT:    br label [[FOR_OUTER:%.*]]
617; CHECK:       for.outer:
618; CHECK-NEXT:    [[INC5_SINK9:%.*]] = phi i32 [ 2, [[ENTRY_NEW]] ], [ [[INC5_3:%.*]], [[FOR_LATCH:%.*]] ]
619; CHECK-NEXT:    [[NITER:%.*]] = phi i32 [ 0, [[ENTRY_NEW]] ], [ [[NITER_NEXT_3:%.*]], [[FOR_LATCH]] ]
620; CHECK-NEXT:    [[INC5_3]] = add nuw nsw i32 [[INC5_SINK9]], 4
621; CHECK-NEXT:    [[NITER_NEXT_3]] = add nuw nsw i32 [[NITER]], 4
622; CHECK-NEXT:    br label [[FOR_INNER:%.*]]
623; CHECK:       for.inner:
624; CHECK-NEXT:    [[INC_SINK8:%.*]] = phi i32 [ 0, [[FOR_OUTER]] ], [ [[INC:%.*]], [[FOR_INNER]] ]
625; CHECK-NEXT:    [[INC_SINK8_1:%.*]] = phi i32 [ 0, [[FOR_OUTER]] ], [ [[INC_1:%.*]], [[FOR_INNER]] ]
626; CHECK-NEXT:    [[INC_SINK8_2:%.*]] = phi i32 [ 0, [[FOR_OUTER]] ], [ [[INC_2:%.*]], [[FOR_INNER]] ]
627; CHECK-NEXT:    [[INC_SINK8_3:%.*]] = phi i32 [ 0, [[FOR_OUTER]] ], [ [[INC_3:%.*]], [[FOR_INNER]] ]
628; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[INC_SINK8]], 1
629; CHECK-NEXT:    [[INC_1]] = add nuw nsw i32 [[INC_SINK8_1]], 1
630; CHECK-NEXT:    [[INC_2]] = add nuw nsw i32 [[INC_SINK8_2]], 1
631; CHECK-NEXT:    [[INC_3]] = add nuw nsw i32 [[INC_SINK8_3]], 1
632; CHECK-NEXT:    [[EXITCOND_3:%.*]] = icmp ne i32 [[INC_3]], 7
633; CHECK-NEXT:    br i1 [[EXITCOND_3]], label [[FOR_INNER]], label [[FOR_LATCH]]
634; CHECK:       for.latch:
635; CHECK-NEXT:    br i1 false, label [[FOR_OUTER]], label [[FOR_END_UNR_LCSSA_LOOPEXIT:%.*]], !llvm.loop [[LOOP7:![0-9]+]]
636; CHECK:       for.end.unr-lcssa.loopexit:
637; CHECK-NEXT:    [[DOTLCSSA_LCSSA_PH_PH:%.*]] = phi i32 [ 2, [[FOR_LATCH]] ]
638; CHECK-NEXT:    [[INC_LCSSA_LCSSA_PH_PH:%.*]] = phi i32 [ 7, [[FOR_LATCH]] ]
639; CHECK-NEXT:    [[P0_UNR_PH:%.*]] = phi i32 [ 2, [[FOR_LATCH]] ]
640; CHECK-NEXT:    br label [[FOR_END_UNR_LCSSA]]
641; CHECK:       for.end.unr-lcssa:
642; CHECK-NEXT:    [[DOTLCSSA_LCSSA_PH:%.*]] = phi i32 [ poison, [[ENTRY:%.*]] ], [ [[DOTLCSSA_LCSSA_PH_PH]], [[FOR_END_UNR_LCSSA_LOOPEXIT]] ]
643; CHECK-NEXT:    [[INC_LCSSA_LCSSA_PH:%.*]] = phi i32 [ poison, [[ENTRY]] ], [ [[INC_LCSSA_LCSSA_PH_PH]], [[FOR_END_UNR_LCSSA_LOOPEXIT]] ]
644; CHECK-NEXT:    [[P0_UNR:%.*]] = phi i32 [ [[F_PROMOTED10]], [[ENTRY]] ], [ [[P0_UNR_PH]], [[FOR_END_UNR_LCSSA_LOOPEXIT]] ]
645; CHECK-NEXT:    br i1 true, label [[FOR_OUTER_EPIL_PREHEADER:%.*]], label [[FOR_END:%.*]]
646; CHECK:       for.outer.epil.preheader:
647; CHECK-NEXT:    br label [[FOR_OUTER_EPIL:%.*]]
648; CHECK:       for.outer.epil:
649; CHECK-NEXT:    br label [[FOR_INNER_EPIL:%.*]]
650; CHECK:       for.inner.epil:
651; CHECK-NEXT:    [[P1_EPIL:%.*]] = phi i32 [ [[P0_UNR]], [[FOR_OUTER_EPIL]] ], [ 2, [[FOR_INNER_EPIL]] ]
652; CHECK-NEXT:    [[INC_SINK8_EPIL:%.*]] = phi i32 [ 0, [[FOR_OUTER_EPIL]] ], [ [[INC_EPIL:%.*]], [[FOR_INNER_EPIL]] ]
653; CHECK-NEXT:    [[INC_EPIL]] = add nuw nsw i32 [[INC_SINK8_EPIL]], 1
654; CHECK-NEXT:    [[EXITCOND_EPIL:%.*]] = icmp ne i32 [[INC_EPIL]], 7
655; CHECK-NEXT:    br i1 [[EXITCOND_EPIL]], label [[FOR_INNER_EPIL]], label [[FOR_LATCH_EPIL:%.*]]
656; CHECK:       for.latch.epil:
657; CHECK-NEXT:    [[DOTLCSSA_EPIL:%.*]] = phi i32 [ [[P1_EPIL]], [[FOR_INNER_EPIL]] ]
658; CHECK-NEXT:    br label [[FOR_END]]
659; CHECK:       for.end:
660; CHECK-NEXT:    [[DOTLCSSA_LCSSA:%.*]] = phi i32 [ [[DOTLCSSA_LCSSA_PH]], [[FOR_END_UNR_LCSSA]] ], [ [[DOTLCSSA_EPIL]], [[FOR_LATCH_EPIL]] ]
661; CHECK-NEXT:    [[INC_LCSSA_LCSSA:%.*]] = phi i32 [ [[INC_LCSSA_LCSSA_PH]], [[FOR_END_UNR_LCSSA]] ], [ 7, [[FOR_LATCH_EPIL]] ]
662; CHECK-NEXT:    ret i32 0
663;
664entry:
665  %f.promoted10 = load i32, ptr @f, align 4, !tbaa !5
666  br label %for.outer
667
668for.outer:
669  %p0 = phi i32 [ %f.promoted10, %entry ], [ 2, %for.latch ]
670  %inc5.sink9 = phi i32 [ 2, %entry ], [ %inc5, %for.latch ]
671  br label %for.inner
672
673for.inner:
674  %p1 = phi i32 [ %p0, %for.outer ], [ 2, %for.inner ]
675  %inc.sink8 = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ]
676  %inc = add nuw nsw i32 %inc.sink8, 1
677  %exitcond = icmp ne i32 %inc, 7
678  br i1 %exitcond, label %for.inner, label %for.latch
679
680for.latch:
681  %.lcssa = phi i32 [ %p1, %for.inner ]
682  %inc5 = add nuw nsw i32 %inc5.sink9, 1
683  %exitcond11 = icmp ne i32 %inc5, 7
684  br i1 %exitcond11, label %for.outer, label %for.end
685
686for.end:
687  %.lcssa.lcssa = phi i32 [ %.lcssa, %for.latch ]
688  %inc.lcssa.lcssa = phi i32 [ 7, %for.latch ]
689  ret i32 0
690}
691
692
693; Has a positive dependency between two stores. Still valid.
694; The negative dependecy is in unroll-and-jam-disabled.ll
695define void @test7(i32 %I, i32 %E, ptr noalias nocapture %A, ptr noalias nocapture readonly %B) #0 {
696; CHECK-LABEL: @test7(
697; CHECK-NEXT:  entry:
698; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[E:%.*]], 0
699; CHECK-NEXT:    [[CMP128:%.*]] = icmp ne i32 [[I:%.*]], 0
700; CHECK-NEXT:    [[OR_COND:%.*]] = and i1 [[CMP128]], [[CMP]]
701; CHECK-NEXT:    br i1 [[OR_COND]], label [[FOR_PREHEADER:%.*]], label [[FOR_END:%.*]]
702; CHECK:       for.preheader:
703; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[I]], -1
704; CHECK-NEXT:    [[XTRAITER:%.*]] = and i32 [[I]], 3
705; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 [[TMP0]], 3
706; CHECK-NEXT:    br i1 [[TMP1]], label [[FOR_END_LOOPEXIT_UNR_LCSSA:%.*]], label [[FOR_PREHEADER_NEW:%.*]]
707; CHECK:       for.preheader.new:
708; CHECK-NEXT:    [[UNROLL_ITER:%.*]] = sub i32 [[I]], [[XTRAITER]]
709; CHECK-NEXT:    br label [[FOR_OUTER:%.*]]
710; CHECK:       for.outer:
711; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[ADD_3:%.*]], [[FOR_LATCH:%.*]] ], [ 0, [[FOR_PREHEADER_NEW]] ]
712; CHECK-NEXT:    [[NITER:%.*]] = phi i32 [ 0, [[FOR_PREHEADER_NEW]] ], [ [[NITER_NEXT_3:%.*]], [[FOR_LATCH]] ]
713; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[I]]
714; CHECK-NEXT:    store i32 0, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA0]]
715; CHECK-NEXT:    [[ADD:%.*]] = add nuw nsw i32 [[I]], 1
716; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[ADD]]
717; CHECK-NEXT:    store i32 2, ptr [[ARRAYIDX2]], align 4, !tbaa [[TBAA0]]
718; CHECK-NEXT:    [[ARRAYIDX_1:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[ADD]]
719; CHECK-NEXT:    store i32 0, ptr [[ARRAYIDX_1]], align 4, !tbaa [[TBAA0]]
720; CHECK-NEXT:    [[ADD_1:%.*]] = add nuw nsw i32 [[I]], 2
721; CHECK-NEXT:    [[ARRAYIDX2_1:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[ADD_1]]
722; CHECK-NEXT:    store i32 2, ptr [[ARRAYIDX2_1]], align 4, !tbaa [[TBAA0]]
723; CHECK-NEXT:    [[ARRAYIDX_2:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[ADD_1]]
724; CHECK-NEXT:    store i32 0, ptr [[ARRAYIDX_2]], align 4, !tbaa [[TBAA0]]
725; CHECK-NEXT:    [[ADD_2:%.*]] = add nuw nsw i32 [[I]], 3
726; CHECK-NEXT:    [[ARRAYIDX2_2:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[ADD_2]]
727; CHECK-NEXT:    store i32 2, ptr [[ARRAYIDX2_2]], align 4, !tbaa [[TBAA0]]
728; CHECK-NEXT:    [[ARRAYIDX_3:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[ADD_2]]
729; CHECK-NEXT:    store i32 0, ptr [[ARRAYIDX_3]], align 4, !tbaa [[TBAA0]]
730; CHECK-NEXT:    [[ADD_3]] = add nuw i32 [[I]], 4
731; CHECK-NEXT:    [[ARRAYIDX2_3:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[ADD_3]]
732; CHECK-NEXT:    store i32 2, ptr [[ARRAYIDX2_3]], align 4, !tbaa [[TBAA0]]
733; CHECK-NEXT:    [[NITER_NEXT_3]] = add i32 [[NITER]], 4
734; CHECK-NEXT:    br label [[FOR_INNER:%.*]]
735; CHECK:       for.latch:
736; CHECK-NEXT:    [[ADD9_LCSSA:%.*]] = phi i32 [ [[ADD9:%.*]], [[FOR_INNER]] ]
737; CHECK-NEXT:    [[ADD9_LCSSA_1:%.*]] = phi i32 [ [[ADD9_1:%.*]], [[FOR_INNER]] ]
738; CHECK-NEXT:    [[ADD9_LCSSA_2:%.*]] = phi i32 [ [[ADD9_2:%.*]], [[FOR_INNER]] ]
739; CHECK-NEXT:    [[ADD9_LCSSA_3:%.*]] = phi i32 [ [[ADD9_3:%.*]], [[FOR_INNER]] ]
740; CHECK-NEXT:    store i32 [[ADD9_LCSSA]], ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA0]]
741; CHECK-NEXT:    store i32 [[ADD9_LCSSA_1]], ptr [[ARRAYIDX_1]], align 4, !tbaa [[TBAA0]]
742; CHECK-NEXT:    store i32 [[ADD9_LCSSA_2]], ptr [[ARRAYIDX_2]], align 4, !tbaa [[TBAA0]]
743; CHECK-NEXT:    store i32 [[ADD9_LCSSA_3]], ptr [[ARRAYIDX_3]], align 4, !tbaa [[TBAA0]]
744; CHECK-NEXT:    [[NITER_NCMP_3:%.*]] = icmp eq i32 [[NITER_NEXT_3]], [[UNROLL_ITER]]
745; CHECK-NEXT:    br i1 [[NITER_NCMP_3]], label [[FOR_END_LOOPEXIT_UNR_LCSSA_LOOPEXIT:%.*]], label [[FOR_OUTER]], !llvm.loop [[LOOP8:![0-9]+]]
746; CHECK:       for.inner:
747; CHECK-NEXT:    [[SUM:%.*]] = phi i32 [ 0, [[FOR_OUTER]] ], [ [[ADD9]], [[FOR_INNER]] ]
748; CHECK-NEXT:    [[J:%.*]] = phi i32 [ 0, [[FOR_OUTER]] ], [ [[ADD10:%.*]], [[FOR_INNER]] ]
749; CHECK-NEXT:    [[SUM_1:%.*]] = phi i32 [ 0, [[FOR_OUTER]] ], [ [[ADD9_1]], [[FOR_INNER]] ]
750; CHECK-NEXT:    [[J_1:%.*]] = phi i32 [ 0, [[FOR_OUTER]] ], [ [[ADD10_1:%.*]], [[FOR_INNER]] ]
751; CHECK-NEXT:    [[SUM_2:%.*]] = phi i32 [ 0, [[FOR_OUTER]] ], [ [[ADD9_2]], [[FOR_INNER]] ]
752; CHECK-NEXT:    [[J_2:%.*]] = phi i32 [ 0, [[FOR_OUTER]] ], [ [[ADD10_2:%.*]], [[FOR_INNER]] ]
753; CHECK-NEXT:    [[SUM_3:%.*]] = phi i32 [ 0, [[FOR_OUTER]] ], [ [[ADD9_3]], [[FOR_INNER]] ]
754; CHECK-NEXT:    [[J_3:%.*]] = phi i32 [ 0, [[FOR_OUTER]] ], [ [[ADD10_3:%.*]], [[FOR_INNER]] ]
755; CHECK-NEXT:    [[ARRAYIDX7:%.*]] = getelementptr inbounds i32, ptr [[B:%.*]], i32 [[J]]
756; CHECK-NEXT:    [[L1:%.*]] = load i32, ptr [[ARRAYIDX7]], align 4, !tbaa [[TBAA0]]
757; CHECK-NEXT:    [[ADD9]] = add i32 [[L1]], [[SUM]]
758; CHECK-NEXT:    [[ADD10]] = add nuw i32 [[J]], 1
759; CHECK-NEXT:    [[ARRAYIDX7_1:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[J_1]]
760; CHECK-NEXT:    [[L1_1:%.*]] = load i32, ptr [[ARRAYIDX7_1]], align 4, !tbaa [[TBAA0]]
761; CHECK-NEXT:    [[ADD9_1]] = add i32 [[L1_1]], [[SUM_1]]
762; CHECK-NEXT:    [[ADD10_1]] = add nuw i32 [[J_1]], 1
763; CHECK-NEXT:    [[ARRAYIDX7_2:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[J_2]]
764; CHECK-NEXT:    [[L1_2:%.*]] = load i32, ptr [[ARRAYIDX7_2]], align 4, !tbaa [[TBAA0]]
765; CHECK-NEXT:    [[ADD9_2]] = add i32 [[L1_2]], [[SUM_2]]
766; CHECK-NEXT:    [[ADD10_2]] = add nuw i32 [[J_2]], 1
767; CHECK-NEXT:    [[ARRAYIDX7_3:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[J_3]]
768; CHECK-NEXT:    [[L1_3:%.*]] = load i32, ptr [[ARRAYIDX7_3]], align 4, !tbaa [[TBAA0]]
769; CHECK-NEXT:    [[ADD9_3]] = add i32 [[L1_3]], [[SUM_3]]
770; CHECK-NEXT:    [[ADD10_3]] = add nuw i32 [[J_3]], 1
771; CHECK-NEXT:    [[EXITCOND_3:%.*]] = icmp eq i32 [[ADD10_3]], [[E]]
772; CHECK-NEXT:    br i1 [[EXITCOND_3]], label [[FOR_LATCH]], label [[FOR_INNER]]
773; CHECK:       for.end.loopexit.unr-lcssa.loopexit:
774; CHECK-NEXT:    [[I_UNR_PH:%.*]] = phi i32 [ [[ADD_3]], [[FOR_LATCH]] ]
775; CHECK-NEXT:    br label [[FOR_END_LOOPEXIT_UNR_LCSSA]]
776; CHECK:       for.end.loopexit.unr-lcssa:
777; CHECK-NEXT:    [[I_UNR:%.*]] = phi i32 [ 0, [[FOR_PREHEADER]] ], [ [[I_UNR_PH]], [[FOR_END_LOOPEXIT_UNR_LCSSA_LOOPEXIT]] ]
778; CHECK-NEXT:    [[LCMP_MOD:%.*]] = icmp ne i32 [[XTRAITER]], 0
779; CHECK-NEXT:    br i1 [[LCMP_MOD]], label [[FOR_OUTER_EPIL_PREHEADER:%.*]], label [[FOR_END_LOOPEXIT:%.*]]
780; CHECK:       for.outer.epil.preheader:
781; CHECK-NEXT:    br label [[FOR_OUTER_EPIL:%.*]]
782; CHECK:       for.outer.epil:
783; CHECK-NEXT:    [[ARRAYIDX_EPIL:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_UNR]]
784; CHECK-NEXT:    store i32 0, ptr [[ARRAYIDX_EPIL]], align 4, !tbaa [[TBAA0]]
785; CHECK-NEXT:    [[ADD_EPIL:%.*]] = add nuw i32 [[I_UNR]], 1
786; CHECK-NEXT:    [[ARRAYIDX2_EPIL:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[ADD_EPIL]]
787; CHECK-NEXT:    store i32 2, ptr [[ARRAYIDX2_EPIL]], align 4, !tbaa [[TBAA0]]
788; CHECK-NEXT:    br label [[FOR_INNER_EPIL:%.*]]
789; CHECK:       for.inner.epil:
790; CHECK-NEXT:    [[SUM_EPIL:%.*]] = phi i32 [ 0, [[FOR_OUTER_EPIL]] ], [ [[ADD9_EPIL:%.*]], [[FOR_INNER_EPIL]] ]
791; CHECK-NEXT:    [[J_EPIL:%.*]] = phi i32 [ 0, [[FOR_OUTER_EPIL]] ], [ [[ADD10_EPIL:%.*]], [[FOR_INNER_EPIL]] ]
792; CHECK-NEXT:    [[ARRAYIDX7_EPIL:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[J_EPIL]]
793; CHECK-NEXT:    [[L1_EPIL:%.*]] = load i32, ptr [[ARRAYIDX7_EPIL]], align 4, !tbaa [[TBAA0]]
794; CHECK-NEXT:    [[ADD9_EPIL]] = add i32 [[L1_EPIL]], [[SUM_EPIL]]
795; CHECK-NEXT:    [[ADD10_EPIL]] = add nuw i32 [[J_EPIL]], 1
796; CHECK-NEXT:    [[EXITCOND_EPIL:%.*]] = icmp eq i32 [[ADD10_EPIL]], [[E]]
797; CHECK-NEXT:    br i1 [[EXITCOND_EPIL]], label [[FOR_LATCH_EPIL:%.*]], label [[FOR_INNER_EPIL]]
798; CHECK:       for.latch.epil:
799; CHECK-NEXT:    [[ADD9_LCSSA_EPIL:%.*]] = phi i32 [ [[ADD9_EPIL]], [[FOR_INNER_EPIL]] ]
800; CHECK-NEXT:    store i32 [[ADD9_LCSSA_EPIL]], ptr [[ARRAYIDX_EPIL]], align 4, !tbaa [[TBAA0]]
801; CHECK-NEXT:    [[EPIL_ITER_CMP:%.*]] = icmp ne i32 1, [[XTRAITER]]
802; CHECK-NEXT:    br i1 [[EPIL_ITER_CMP]], label [[FOR_OUTER_EPIL_1:%.*]], label [[FOR_END_LOOPEXIT_EPILOG_LCSSA:%.*]]
803; CHECK:       for.outer.epil.1:
804; CHECK-NEXT:    [[ARRAYIDX_EPIL_1:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[ADD_EPIL]]
805; CHECK-NEXT:    store i32 0, ptr [[ARRAYIDX_EPIL_1]], align 4, !tbaa [[TBAA0]]
806; CHECK-NEXT:    [[ADD_EPIL_1:%.*]] = add nuw i32 [[I_UNR]], 2
807; CHECK-NEXT:    [[ARRAYIDX2_EPIL_1:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[ADD_EPIL_1]]
808; CHECK-NEXT:    store i32 2, ptr [[ARRAYIDX2_EPIL_1]], align 4, !tbaa [[TBAA0]]
809; CHECK-NEXT:    br label [[FOR_INNER_EPIL_1:%.*]]
810; CHECK:       for.inner.epil.1:
811; CHECK-NEXT:    [[SUM_EPIL_1:%.*]] = phi i32 [ 0, [[FOR_OUTER_EPIL_1]] ], [ [[ADD9_EPIL_1:%.*]], [[FOR_INNER_EPIL_1]] ]
812; CHECK-NEXT:    [[J_EPIL_1:%.*]] = phi i32 [ 0, [[FOR_OUTER_EPIL_1]] ], [ [[ADD10_EPIL_1:%.*]], [[FOR_INNER_EPIL_1]] ]
813; CHECK-NEXT:    [[ARRAYIDX7_EPIL_1:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[J_EPIL_1]]
814; CHECK-NEXT:    [[L1_EPIL_1:%.*]] = load i32, ptr [[ARRAYIDX7_EPIL_1]], align 4, !tbaa [[TBAA0]]
815; CHECK-NEXT:    [[ADD9_EPIL_1]] = add i32 [[L1_EPIL_1]], [[SUM_EPIL_1]]
816; CHECK-NEXT:    [[ADD10_EPIL_1]] = add nuw i32 [[J_EPIL_1]], 1
817; CHECK-NEXT:    [[EXITCOND_EPIL_1:%.*]] = icmp eq i32 [[ADD10_EPIL_1]], [[E]]
818; CHECK-NEXT:    br i1 [[EXITCOND_EPIL_1]], label [[FOR_LATCH_EPIL_1:%.*]], label [[FOR_INNER_EPIL_1]]
819; CHECK:       for.latch.epil.1:
820; CHECK-NEXT:    [[ADD9_LCSSA_EPIL_1:%.*]] = phi i32 [ [[ADD9_EPIL_1]], [[FOR_INNER_EPIL_1]] ]
821; CHECK-NEXT:    store i32 [[ADD9_LCSSA_EPIL_1]], ptr [[ARRAYIDX_EPIL_1]], align 4, !tbaa [[TBAA0]]
822; CHECK-NEXT:    [[EPIL_ITER_CMP_1:%.*]] = icmp ne i32 2, [[XTRAITER]]
823; CHECK-NEXT:    br i1 [[EPIL_ITER_CMP_1]], label [[FOR_OUTER_EPIL_2:%.*]], label [[FOR_END_LOOPEXIT_EPILOG_LCSSA]]
824; CHECK:       for.outer.epil.2:
825; CHECK-NEXT:    [[ARRAYIDX_EPIL_2:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[ADD_EPIL_1]]
826; CHECK-NEXT:    store i32 0, ptr [[ARRAYIDX_EPIL_2]], align 4, !tbaa [[TBAA0]]
827; CHECK-NEXT:    [[ADD_EPIL_2:%.*]] = add nuw i32 [[I_UNR]], 3
828; CHECK-NEXT:    [[ARRAYIDX2_EPIL_2:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[ADD_EPIL_2]]
829; CHECK-NEXT:    store i32 2, ptr [[ARRAYIDX2_EPIL_2]], align 4, !tbaa [[TBAA0]]
830; CHECK-NEXT:    br label [[FOR_INNER_EPIL_2:%.*]]
831; CHECK:       for.inner.epil.2:
832; CHECK-NEXT:    [[SUM_EPIL_2:%.*]] = phi i32 [ 0, [[FOR_OUTER_EPIL_2]] ], [ [[ADD9_EPIL_2:%.*]], [[FOR_INNER_EPIL_2]] ]
833; CHECK-NEXT:    [[J_EPIL_2:%.*]] = phi i32 [ 0, [[FOR_OUTER_EPIL_2]] ], [ [[ADD10_EPIL_2:%.*]], [[FOR_INNER_EPIL_2]] ]
834; CHECK-NEXT:    [[ARRAYIDX7_EPIL_2:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[J_EPIL_2]]
835; CHECK-NEXT:    [[L1_EPIL_2:%.*]] = load i32, ptr [[ARRAYIDX7_EPIL_2]], align 4, !tbaa [[TBAA0]]
836; CHECK-NEXT:    [[ADD9_EPIL_2]] = add i32 [[L1_EPIL_2]], [[SUM_EPIL_2]]
837; CHECK-NEXT:    [[ADD10_EPIL_2]] = add nuw i32 [[J_EPIL_2]], 1
838; CHECK-NEXT:    [[EXITCOND_EPIL_2:%.*]] = icmp eq i32 [[ADD10_EPIL_2]], [[E]]
839; CHECK-NEXT:    br i1 [[EXITCOND_EPIL_2]], label [[FOR_LATCH_EPIL_2:%.*]], label [[FOR_INNER_EPIL_2]]
840; CHECK:       for.latch.epil.2:
841; CHECK-NEXT:    [[ADD9_LCSSA_EPIL_2:%.*]] = phi i32 [ [[ADD9_EPIL_2]], [[FOR_INNER_EPIL_2]] ]
842; CHECK-NEXT:    store i32 [[ADD9_LCSSA_EPIL_2]], ptr [[ARRAYIDX_EPIL_2]], align 4, !tbaa [[TBAA0]]
843; CHECK-NEXT:    br label [[FOR_END_LOOPEXIT_EPILOG_LCSSA]]
844; CHECK:       for.end.loopexit.epilog-lcssa:
845; CHECK-NEXT:    br label [[FOR_END_LOOPEXIT]]
846; CHECK:       for.end.loopexit:
847; CHECK-NEXT:    br label [[FOR_END]]
848; CHECK:       for.end:
849; CHECK-NEXT:    ret void
850;
851entry:
852  %cmp = icmp ne i32 %E, 0
853  %cmp128 = icmp ne i32 %I, 0
854  %or.cond = and i1 %cmp128, %cmp
855  br i1 %or.cond, label %for.preheader, label %for.end
856
857for.preheader:
858  br label %for.outer
859
860for.outer:
861  %i = phi i32 [ %add, %for.latch ], [ 0, %for.preheader ]
862  %arrayidx = getelementptr inbounds i32, ptr %A, i32 %i
863  store i32 0, ptr %arrayidx, align 4, !tbaa !5
864  %add = add nuw i32 %i, 1
865  %arrayidx2 = getelementptr inbounds i32, ptr %A, i32 %add
866  store i32 2, ptr %arrayidx2, align 4, !tbaa !5
867  br label %for.inner
868
869for.latch:
870  store i32 %add9, ptr %arrayidx, align 4, !tbaa !5
871  %exitcond30 = icmp eq i32 %add, %I
872  br i1 %exitcond30, label %for.end, label %for.outer
873
874for.inner:
875  %sum = phi i32 [ 0, %for.outer ], [ %add9, %for.inner ]
876  %j = phi i32 [ 0, %for.outer ], [ %add10, %for.inner ]
877  %arrayidx7 = getelementptr inbounds i32, ptr %B, i32 %j
878  %l1 = load i32, ptr %arrayidx7, align 4, !tbaa !5
879  %add9 = add i32 %l1, %sum
880  %add10 = add nuw i32 %j, 1
881  %exitcond = icmp eq i32 %add10, %E
882  br i1 %exitcond, label %for.latch, label %for.inner
883
884for.end:
885  ret void
886}
887
888
889; Same as test7 with an extra outer loop nest
890define void @test8(i32 %I, i32 %E, ptr noalias nocapture %A, ptr noalias nocapture readonly %B) #0 {
891; CHECK-LABEL: @test8(
892; CHECK-NEXT:  entry:
893; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[E:%.*]], 0
894; CHECK-NEXT:    [[CMP336:%.*]] = icmp eq i32 [[I:%.*]], 0
895; CHECK-NEXT:    [[OR_COND:%.*]] = or i1 [[CMP]], [[CMP336]]
896; CHECK-NEXT:    br i1 [[OR_COND]], label [[FOR_END:%.*]], label [[FOR_PREHEADER:%.*]]
897; CHECK:       for.preheader:
898; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[I]], -1
899; CHECK-NEXT:    br label [[FOR_OUTEST:%.*]]
900; CHECK:       for.outest:
901; CHECK-NEXT:    [[X_038:%.*]] = phi i32 [ [[INC:%.*]], [[FOR_CLEANUP:%.*]] ], [ 0, [[FOR_PREHEADER]] ]
902; CHECK-NEXT:    [[XTRAITER:%.*]] = and i32 [[I]], 3
903; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 [[TMP0]], 3
904; CHECK-NEXT:    br i1 [[TMP1]], label [[FOR_CLEANUP_UNR_LCSSA:%.*]], label [[FOR_OUTEST_NEW:%.*]]
905; CHECK:       for.outest.new:
906; CHECK-NEXT:    [[UNROLL_ITER:%.*]] = sub i32 [[I]], [[XTRAITER]]
907; CHECK-NEXT:    br label [[FOR_OUTER:%.*]]
908; CHECK:       for.outer:
909; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[ADD_3:%.*]], [[FOR_LATCH:%.*]] ], [ 0, [[FOR_OUTEST_NEW]] ]
910; CHECK-NEXT:    [[NITER:%.*]] = phi i32 [ 0, [[FOR_OUTEST_NEW]] ], [ [[NITER_NEXT_3:%.*]], [[FOR_LATCH]] ]
911; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[I]]
912; CHECK-NEXT:    store i32 0, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA0]]
913; CHECK-NEXT:    [[ADD:%.*]] = add nuw nsw i32 [[I]], 1
914; CHECK-NEXT:    [[ARRAYIDX6:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[ADD]]
915; CHECK-NEXT:    store i32 2, ptr [[ARRAYIDX6]], align 4, !tbaa [[TBAA0]]
916; CHECK-NEXT:    [[ARRAYIDX_1:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[ADD]]
917; CHECK-NEXT:    store i32 0, ptr [[ARRAYIDX_1]], align 4, !tbaa [[TBAA0]]
918; CHECK-NEXT:    [[ADD_1:%.*]] = add nuw nsw i32 [[I]], 2
919; CHECK-NEXT:    [[ARRAYIDX6_1:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[ADD_1]]
920; CHECK-NEXT:    store i32 2, ptr [[ARRAYIDX6_1]], align 4, !tbaa [[TBAA0]]
921; CHECK-NEXT:    [[ARRAYIDX_2:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[ADD_1]]
922; CHECK-NEXT:    store i32 0, ptr [[ARRAYIDX_2]], align 4, !tbaa [[TBAA0]]
923; CHECK-NEXT:    [[ADD_2:%.*]] = add nuw nsw i32 [[I]], 3
924; CHECK-NEXT:    [[ARRAYIDX6_2:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[ADD_2]]
925; CHECK-NEXT:    store i32 2, ptr [[ARRAYIDX6_2]], align 4, !tbaa [[TBAA0]]
926; CHECK-NEXT:    [[ARRAYIDX_3:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[ADD_2]]
927; CHECK-NEXT:    store i32 0, ptr [[ARRAYIDX_3]], align 4, !tbaa [[TBAA0]]
928; CHECK-NEXT:    [[ADD_3]] = add nuw i32 [[I]], 4
929; CHECK-NEXT:    [[ARRAYIDX6_3:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[ADD_3]]
930; CHECK-NEXT:    store i32 2, ptr [[ARRAYIDX6_3]], align 4, !tbaa [[TBAA0]]
931; CHECK-NEXT:    [[NITER_NEXT_3]] = add i32 [[NITER]], 4
932; CHECK-NEXT:    br label [[FOR_INNER:%.*]]
933; CHECK:       for.inner:
934; CHECK-NEXT:    [[SUM:%.*]] = phi i32 [ 0, [[FOR_OUTER]] ], [ [[ADD9:%.*]], [[FOR_INNER]] ]
935; CHECK-NEXT:    [[J:%.*]] = phi i32 [ 0, [[FOR_OUTER]] ], [ [[ADD10:%.*]], [[FOR_INNER]] ]
936; CHECK-NEXT:    [[SUM_1:%.*]] = phi i32 [ 0, [[FOR_OUTER]] ], [ [[ADD9_1:%.*]], [[FOR_INNER]] ]
937; CHECK-NEXT:    [[J_1:%.*]] = phi i32 [ 0, [[FOR_OUTER]] ], [ [[ADD10_1:%.*]], [[FOR_INNER]] ]
938; CHECK-NEXT:    [[SUM_2:%.*]] = phi i32 [ 0, [[FOR_OUTER]] ], [ [[ADD9_2:%.*]], [[FOR_INNER]] ]
939; CHECK-NEXT:    [[J_2:%.*]] = phi i32 [ 0, [[FOR_OUTER]] ], [ [[ADD10_2:%.*]], [[FOR_INNER]] ]
940; CHECK-NEXT:    [[SUM_3:%.*]] = phi i32 [ 0, [[FOR_OUTER]] ], [ [[ADD9_3:%.*]], [[FOR_INNER]] ]
941; CHECK-NEXT:    [[J_3:%.*]] = phi i32 [ 0, [[FOR_OUTER]] ], [ [[ADD10_3:%.*]], [[FOR_INNER]] ]
942; CHECK-NEXT:    [[ARRAYIDX11:%.*]] = getelementptr inbounds i32, ptr [[B:%.*]], i32 [[J]]
943; CHECK-NEXT:    [[L1:%.*]] = load i32, ptr [[ARRAYIDX11]], align 4, !tbaa [[TBAA0]]
944; CHECK-NEXT:    [[ADD9]] = add i32 [[L1]], [[SUM]]
945; CHECK-NEXT:    [[ADD10]] = add nuw i32 [[J]], 1
946; CHECK-NEXT:    [[ARRAYIDX11_1:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[J_1]]
947; CHECK-NEXT:    [[L1_1:%.*]] = load i32, ptr [[ARRAYIDX11_1]], align 4, !tbaa [[TBAA0]]
948; CHECK-NEXT:    [[ADD9_1]] = add i32 [[L1_1]], [[SUM_1]]
949; CHECK-NEXT:    [[ADD10_1]] = add nuw i32 [[J_1]], 1
950; CHECK-NEXT:    [[ARRAYIDX11_2:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[J_2]]
951; CHECK-NEXT:    [[L1_2:%.*]] = load i32, ptr [[ARRAYIDX11_2]], align 4, !tbaa [[TBAA0]]
952; CHECK-NEXT:    [[ADD9_2]] = add i32 [[L1_2]], [[SUM_2]]
953; CHECK-NEXT:    [[ADD10_2]] = add nuw i32 [[J_2]], 1
954; CHECK-NEXT:    [[ARRAYIDX11_3:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[J_3]]
955; CHECK-NEXT:    [[L1_3:%.*]] = load i32, ptr [[ARRAYIDX11_3]], align 4, !tbaa [[TBAA0]]
956; CHECK-NEXT:    [[ADD9_3]] = add i32 [[L1_3]], [[SUM_3]]
957; CHECK-NEXT:    [[ADD10_3]] = add nuw i32 [[J_3]], 1
958; CHECK-NEXT:    [[EXITCOND_3:%.*]] = icmp eq i32 [[ADD10_3]], [[E]]
959; CHECK-NEXT:    br i1 [[EXITCOND_3]], label [[FOR_LATCH]], label [[FOR_INNER]]
960; CHECK:       for.latch:
961; CHECK-NEXT:    [[ADD9_LCSSA:%.*]] = phi i32 [ [[ADD9]], [[FOR_INNER]] ]
962; CHECK-NEXT:    [[ADD9_LCSSA_1:%.*]] = phi i32 [ [[ADD9_1]], [[FOR_INNER]] ]
963; CHECK-NEXT:    [[ADD9_LCSSA_2:%.*]] = phi i32 [ [[ADD9_2]], [[FOR_INNER]] ]
964; CHECK-NEXT:    [[ADD9_LCSSA_3:%.*]] = phi i32 [ [[ADD9_3]], [[FOR_INNER]] ]
965; CHECK-NEXT:    store i32 [[ADD9_LCSSA]], ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA0]]
966; CHECK-NEXT:    store i32 [[ADD9_LCSSA_1]], ptr [[ARRAYIDX_1]], align 4, !tbaa [[TBAA0]]
967; CHECK-NEXT:    store i32 [[ADD9_LCSSA_2]], ptr [[ARRAYIDX_2]], align 4, !tbaa [[TBAA0]]
968; CHECK-NEXT:    store i32 [[ADD9_LCSSA_3]], ptr [[ARRAYIDX_3]], align 4, !tbaa [[TBAA0]]
969; CHECK-NEXT:    [[NITER_NCMP_3:%.*]] = icmp eq i32 [[NITER_NEXT_3]], [[UNROLL_ITER]]
970; CHECK-NEXT:    br i1 [[NITER_NCMP_3]], label [[FOR_CLEANUP_UNR_LCSSA_LOOPEXIT:%.*]], label [[FOR_OUTER]], !llvm.loop [[LOOP9:![0-9]+]]
971; CHECK:       for.cleanup.unr-lcssa.loopexit:
972; CHECK-NEXT:    [[I_UNR_PH:%.*]] = phi i32 [ [[ADD_3]], [[FOR_LATCH]] ]
973; CHECK-NEXT:    br label [[FOR_CLEANUP_UNR_LCSSA]]
974; CHECK:       for.cleanup.unr-lcssa:
975; CHECK-NEXT:    [[I_UNR:%.*]] = phi i32 [ 0, [[FOR_OUTEST]] ], [ [[I_UNR_PH]], [[FOR_CLEANUP_UNR_LCSSA_LOOPEXIT]] ]
976; CHECK-NEXT:    [[LCMP_MOD:%.*]] = icmp ne i32 [[XTRAITER]], 0
977; CHECK-NEXT:    br i1 [[LCMP_MOD]], label [[FOR_OUTER_EPIL_PREHEADER:%.*]], label [[FOR_CLEANUP]]
978; CHECK:       for.outer.epil.preheader:
979; CHECK-NEXT:    br label [[FOR_OUTER_EPIL:%.*]]
980; CHECK:       for.outer.epil:
981; CHECK-NEXT:    [[ARRAYIDX_EPIL:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_UNR]]
982; CHECK-NEXT:    store i32 0, ptr [[ARRAYIDX_EPIL]], align 4, !tbaa [[TBAA0]]
983; CHECK-NEXT:    [[ADD_EPIL:%.*]] = add nuw i32 [[I_UNR]], 1
984; CHECK-NEXT:    [[ARRAYIDX6_EPIL:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[ADD_EPIL]]
985; CHECK-NEXT:    store i32 2, ptr [[ARRAYIDX6_EPIL]], align 4, !tbaa [[TBAA0]]
986; CHECK-NEXT:    br label [[FOR_INNER_EPIL:%.*]]
987; CHECK:       for.inner.epil:
988; CHECK-NEXT:    [[SUM_EPIL:%.*]] = phi i32 [ 0, [[FOR_OUTER_EPIL]] ], [ [[ADD9_EPIL:%.*]], [[FOR_INNER_EPIL]] ]
989; CHECK-NEXT:    [[J_EPIL:%.*]] = phi i32 [ 0, [[FOR_OUTER_EPIL]] ], [ [[ADD10_EPIL:%.*]], [[FOR_INNER_EPIL]] ]
990; CHECK-NEXT:    [[ARRAYIDX11_EPIL:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[J_EPIL]]
991; CHECK-NEXT:    [[L1_EPIL:%.*]] = load i32, ptr [[ARRAYIDX11_EPIL]], align 4, !tbaa [[TBAA0]]
992; CHECK-NEXT:    [[ADD9_EPIL]] = add i32 [[L1_EPIL]], [[SUM_EPIL]]
993; CHECK-NEXT:    [[ADD10_EPIL]] = add nuw i32 [[J_EPIL]], 1
994; CHECK-NEXT:    [[EXITCOND_EPIL:%.*]] = icmp eq i32 [[ADD10_EPIL]], [[E]]
995; CHECK-NEXT:    br i1 [[EXITCOND_EPIL]], label [[FOR_LATCH_EPIL:%.*]], label [[FOR_INNER_EPIL]]
996; CHECK:       for.latch.epil:
997; CHECK-NEXT:    [[ADD9_LCSSA_EPIL:%.*]] = phi i32 [ [[ADD9_EPIL]], [[FOR_INNER_EPIL]] ]
998; CHECK-NEXT:    store i32 [[ADD9_LCSSA_EPIL]], ptr [[ARRAYIDX_EPIL]], align 4, !tbaa [[TBAA0]]
999; CHECK-NEXT:    [[EPIL_ITER_CMP:%.*]] = icmp ne i32 1, [[XTRAITER]]
1000; CHECK-NEXT:    br i1 [[EPIL_ITER_CMP]], label [[FOR_OUTER_EPIL_1:%.*]], label [[FOR_CLEANUP_EPILOG_LCSSA:%.*]]
1001; CHECK:       for.outer.epil.1:
1002; CHECK-NEXT:    [[ARRAYIDX_EPIL_1:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[ADD_EPIL]]
1003; CHECK-NEXT:    store i32 0, ptr [[ARRAYIDX_EPIL_1]], align 4, !tbaa [[TBAA0]]
1004; CHECK-NEXT:    [[ADD_EPIL_1:%.*]] = add nuw i32 [[I_UNR]], 2
1005; CHECK-NEXT:    [[ARRAYIDX6_EPIL_1:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[ADD_EPIL_1]]
1006; CHECK-NEXT:    store i32 2, ptr [[ARRAYIDX6_EPIL_1]], align 4, !tbaa [[TBAA0]]
1007; CHECK-NEXT:    br label [[FOR_INNER_EPIL_1:%.*]]
1008; CHECK:       for.inner.epil.1:
1009; CHECK-NEXT:    [[SUM_EPIL_1:%.*]] = phi i32 [ 0, [[FOR_OUTER_EPIL_1]] ], [ [[ADD9_EPIL_1:%.*]], [[FOR_INNER_EPIL_1]] ]
1010; CHECK-NEXT:    [[J_EPIL_1:%.*]] = phi i32 [ 0, [[FOR_OUTER_EPIL_1]] ], [ [[ADD10_EPIL_1:%.*]], [[FOR_INNER_EPIL_1]] ]
1011; CHECK-NEXT:    [[ARRAYIDX11_EPIL_1:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[J_EPIL_1]]
1012; CHECK-NEXT:    [[L1_EPIL_1:%.*]] = load i32, ptr [[ARRAYIDX11_EPIL_1]], align 4, !tbaa [[TBAA0]]
1013; CHECK-NEXT:    [[ADD9_EPIL_1]] = add i32 [[L1_EPIL_1]], [[SUM_EPIL_1]]
1014; CHECK-NEXT:    [[ADD10_EPIL_1]] = add nuw i32 [[J_EPIL_1]], 1
1015; CHECK-NEXT:    [[EXITCOND_EPIL_1:%.*]] = icmp eq i32 [[ADD10_EPIL_1]], [[E]]
1016; CHECK-NEXT:    br i1 [[EXITCOND_EPIL_1]], label [[FOR_LATCH_EPIL_1:%.*]], label [[FOR_INNER_EPIL_1]]
1017; CHECK:       for.latch.epil.1:
1018; CHECK-NEXT:    [[ADD9_LCSSA_EPIL_1:%.*]] = phi i32 [ [[ADD9_EPIL_1]], [[FOR_INNER_EPIL_1]] ]
1019; CHECK-NEXT:    store i32 [[ADD9_LCSSA_EPIL_1]], ptr [[ARRAYIDX_EPIL_1]], align 4, !tbaa [[TBAA0]]
1020; CHECK-NEXT:    [[EPIL_ITER_CMP_1:%.*]] = icmp ne i32 2, [[XTRAITER]]
1021; CHECK-NEXT:    br i1 [[EPIL_ITER_CMP_1]], label [[FOR_OUTER_EPIL_2:%.*]], label [[FOR_CLEANUP_EPILOG_LCSSA]]
1022; CHECK:       for.outer.epil.2:
1023; CHECK-NEXT:    [[ARRAYIDX_EPIL_2:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[ADD_EPIL_1]]
1024; CHECK-NEXT:    store i32 0, ptr [[ARRAYIDX_EPIL_2]], align 4, !tbaa [[TBAA0]]
1025; CHECK-NEXT:    [[ADD_EPIL_2:%.*]] = add nuw i32 [[I_UNR]], 3
1026; CHECK-NEXT:    [[ARRAYIDX6_EPIL_2:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[ADD_EPIL_2]]
1027; CHECK-NEXT:    store i32 2, ptr [[ARRAYIDX6_EPIL_2]], align 4, !tbaa [[TBAA0]]
1028; CHECK-NEXT:    br label [[FOR_INNER_EPIL_2:%.*]]
1029; CHECK:       for.inner.epil.2:
1030; CHECK-NEXT:    [[SUM_EPIL_2:%.*]] = phi i32 [ 0, [[FOR_OUTER_EPIL_2]] ], [ [[ADD9_EPIL_2:%.*]], [[FOR_INNER_EPIL_2]] ]
1031; CHECK-NEXT:    [[J_EPIL_2:%.*]] = phi i32 [ 0, [[FOR_OUTER_EPIL_2]] ], [ [[ADD10_EPIL_2:%.*]], [[FOR_INNER_EPIL_2]] ]
1032; CHECK-NEXT:    [[ARRAYIDX11_EPIL_2:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[J_EPIL_2]]
1033; CHECK-NEXT:    [[L1_EPIL_2:%.*]] = load i32, ptr [[ARRAYIDX11_EPIL_2]], align 4, !tbaa [[TBAA0]]
1034; CHECK-NEXT:    [[ADD9_EPIL_2]] = add i32 [[L1_EPIL_2]], [[SUM_EPIL_2]]
1035; CHECK-NEXT:    [[ADD10_EPIL_2]] = add nuw i32 [[J_EPIL_2]], 1
1036; CHECK-NEXT:    [[EXITCOND_EPIL_2:%.*]] = icmp eq i32 [[ADD10_EPIL_2]], [[E]]
1037; CHECK-NEXT:    br i1 [[EXITCOND_EPIL_2]], label [[FOR_LATCH_EPIL_2:%.*]], label [[FOR_INNER_EPIL_2]]
1038; CHECK:       for.latch.epil.2:
1039; CHECK-NEXT:    [[ADD9_LCSSA_EPIL_2:%.*]] = phi i32 [ [[ADD9_EPIL_2]], [[FOR_INNER_EPIL_2]] ]
1040; CHECK-NEXT:    store i32 [[ADD9_LCSSA_EPIL_2]], ptr [[ARRAYIDX_EPIL_2]], align 4, !tbaa [[TBAA0]]
1041; CHECK-NEXT:    br label [[FOR_CLEANUP_EPILOG_LCSSA]]
1042; CHECK:       for.cleanup.epilog-lcssa:
1043; CHECK-NEXT:    br label [[FOR_CLEANUP]]
1044; CHECK:       for.cleanup:
1045; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[X_038]], 1
1046; CHECK-NEXT:    [[EXITCOND41:%.*]] = icmp eq i32 [[INC]], 5
1047; CHECK-NEXT:    br i1 [[EXITCOND41]], label [[FOR_END_LOOPEXIT:%.*]], label [[FOR_OUTEST]]
1048; CHECK:       for.end.loopexit:
1049; CHECK-NEXT:    br label [[FOR_END]]
1050; CHECK:       for.end:
1051; CHECK-NEXT:    ret void
1052;
1053entry:
1054  %cmp = icmp eq i32 %E, 0
1055  %cmp336 = icmp eq i32 %I, 0
1056  %or.cond = or i1 %cmp, %cmp336
1057  br i1 %or.cond, label %for.end, label %for.preheader
1058
1059for.preheader:
1060  br label %for.outest
1061
1062for.outest:
1063  %x.038 = phi i32 [ %inc, %for.cleanup ], [ 0, %for.preheader ]
1064  br label %for.outer
1065
1066for.outer:
1067  %i = phi i32 [ %add, %for.latch ], [ 0, %for.outest ]
1068  %arrayidx = getelementptr inbounds i32, ptr %A, i32 %i
1069  store i32 0, ptr %arrayidx, align 4, !tbaa !5
1070  %add = add nuw i32 %i, 1
1071  %arrayidx6 = getelementptr inbounds i32, ptr %A, i32 %add
1072  store i32 2, ptr %arrayidx6, align 4, !tbaa !5
1073  br label %for.inner
1074
1075for.inner:
1076  %sum = phi i32 [ 0, %for.outer ], [ %add9, %for.inner ]
1077  %j = phi i32 [ 0, %for.outer ], [ %add10, %for.inner ]
1078  %arrayidx11 = getelementptr inbounds i32, ptr %B, i32 %j
1079  %l1 = load i32, ptr %arrayidx11, align 4, !tbaa !5
1080  %add9 = add i32 %l1, %sum
1081  %add10 = add nuw i32 %j, 1
1082  %exitcond = icmp eq i32 %add10, %E
1083  br i1 %exitcond, label %for.latch, label %for.inner
1084
1085for.latch:
1086  store i32 %add9, ptr %arrayidx, align 4, !tbaa !5
1087  %exitcond39 = icmp eq i32 %add, %I
1088  br i1 %exitcond39, label %for.cleanup, label %for.outer
1089
1090for.cleanup:
1091  %inc = add nuw nsw i32 %x.038, 1
1092  %exitcond41 = icmp eq i32 %inc, 5
1093  br i1 %exitcond41, label %for.end, label %for.outest
1094
1095for.end:
1096  ret void
1097}
1098
1099
1100; Same as test1 with tbaa, not noalias
1101define void @test9(i32 %I, i32 %E, ptr nocapture %A, ptr nocapture readonly %B) #0 {
1102; CHECK-LABEL: @test9(
1103; CHECK-NEXT:  entry:
1104; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[E:%.*]], 0
1105; CHECK-NEXT:    [[CMPJ:%.*]] = icmp ne i32 [[I:%.*]], 0
1106; CHECK-NEXT:    [[OR_COND:%.*]] = and i1 [[CMP]], [[CMPJ]]
1107; CHECK-NEXT:    br i1 [[OR_COND]], label [[FOR_OUTER_PREHEADER:%.*]], label [[FOR_END:%.*]]
1108; CHECK:       for.outer.preheader:
1109; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[I]], -1
1110; CHECK-NEXT:    [[XTRAITER:%.*]] = and i32 [[I]], 3
1111; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 [[TMP0]], 3
1112; CHECK-NEXT:    br i1 [[TMP1]], label [[FOR_END_LOOPEXIT_UNR_LCSSA:%.*]], label [[FOR_OUTER_PREHEADER_NEW:%.*]]
1113; CHECK:       for.outer.preheader.new:
1114; CHECK-NEXT:    [[UNROLL_ITER:%.*]] = sub i32 [[I]], [[XTRAITER]]
1115; CHECK-NEXT:    br label [[FOR_OUTER:%.*]]
1116; CHECK:       for.outer:
1117; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[ADD8_3:%.*]], [[FOR_LATCH:%.*]] ], [ 0, [[FOR_OUTER_PREHEADER_NEW]] ]
1118; CHECK-NEXT:    [[NITER:%.*]] = phi i32 [ 0, [[FOR_OUTER_PREHEADER_NEW]] ], [ [[NITER_NEXT_3:%.*]], [[FOR_LATCH]] ]
1119; CHECK-NEXT:    [[ADD8:%.*]] = add nuw nsw i32 [[I]], 1
1120; CHECK-NEXT:    [[ADD8_1:%.*]] = add nuw nsw i32 [[I]], 2
1121; CHECK-NEXT:    [[ADD8_2:%.*]] = add nuw nsw i32 [[I]], 3
1122; CHECK-NEXT:    [[ADD8_3]] = add nuw i32 [[I]], 4
1123; CHECK-NEXT:    [[NITER_NEXT_3]] = add i32 [[NITER]], 4
1124; CHECK-NEXT:    br label [[FOR_INNER:%.*]]
1125; CHECK:       for.inner:
1126; CHECK-NEXT:    [[J:%.*]] = phi i32 [ 0, [[FOR_OUTER]] ], [ [[INC:%.*]], [[FOR_INNER]] ]
1127; CHECK-NEXT:    [[SUM:%.*]] = phi i32 [ 0, [[FOR_OUTER]] ], [ [[ADD:%.*]], [[FOR_INNER]] ]
1128; CHECK-NEXT:    [[J_1:%.*]] = phi i32 [ 0, [[FOR_OUTER]] ], [ [[INC_1:%.*]], [[FOR_INNER]] ]
1129; CHECK-NEXT:    [[SUM_1:%.*]] = phi i32 [ 0, [[FOR_OUTER]] ], [ [[ADD_1:%.*]], [[FOR_INNER]] ]
1130; CHECK-NEXT:    [[J_2:%.*]] = phi i32 [ 0, [[FOR_OUTER]] ], [ [[INC_2:%.*]], [[FOR_INNER]] ]
1131; CHECK-NEXT:    [[SUM_2:%.*]] = phi i32 [ 0, [[FOR_OUTER]] ], [ [[ADD_2:%.*]], [[FOR_INNER]] ]
1132; CHECK-NEXT:    [[J_3:%.*]] = phi i32 [ 0, [[FOR_OUTER]] ], [ [[INC_3:%.*]], [[FOR_INNER]] ]
1133; CHECK-NEXT:    [[SUM_3:%.*]] = phi i32 [ 0, [[FOR_OUTER]] ], [ [[ADD_3:%.*]], [[FOR_INNER]] ]
1134; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i16, ptr [[B:%.*]], i32 [[J]]
1135; CHECK-NEXT:    [[TMP2:%.*]] = load i16, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA10:![0-9]+]]
1136; CHECK-NEXT:    [[SEXT:%.*]] = sext i16 [[TMP2]] to i32
1137; CHECK-NEXT:    [[ADD]] = add i32 [[SEXT]], [[SUM]]
1138; CHECK-NEXT:    [[INC]] = add nuw i32 [[J]], 1
1139; CHECK-NEXT:    [[ARRAYIDX_1:%.*]] = getelementptr inbounds i16, ptr [[B]], i32 [[J_1]]
1140; CHECK-NEXT:    [[TMP3:%.*]] = load i16, ptr [[ARRAYIDX_1]], align 4, !tbaa [[TBAA10]]
1141; CHECK-NEXT:    [[SEXT_1:%.*]] = sext i16 [[TMP3]] to i32
1142; CHECK-NEXT:    [[ADD_1]] = add i32 [[SEXT_1]], [[SUM_1]]
1143; CHECK-NEXT:    [[INC_1]] = add nuw i32 [[J_1]], 1
1144; CHECK-NEXT:    [[ARRAYIDX_2:%.*]] = getelementptr inbounds i16, ptr [[B]], i32 [[J_2]]
1145; CHECK-NEXT:    [[TMP4:%.*]] = load i16, ptr [[ARRAYIDX_2]], align 4, !tbaa [[TBAA10]]
1146; CHECK-NEXT:    [[SEXT_2:%.*]] = sext i16 [[TMP4]] to i32
1147; CHECK-NEXT:    [[ADD_2]] = add i32 [[SEXT_2]], [[SUM_2]]
1148; CHECK-NEXT:    [[INC_2]] = add nuw i32 [[J_2]], 1
1149; CHECK-NEXT:    [[ARRAYIDX_3:%.*]] = getelementptr inbounds i16, ptr [[B]], i32 [[J_3]]
1150; CHECK-NEXT:    [[TMP5:%.*]] = load i16, ptr [[ARRAYIDX_3]], align 4, !tbaa [[TBAA10]]
1151; CHECK-NEXT:    [[SEXT_3:%.*]] = sext i16 [[TMP5]] to i32
1152; CHECK-NEXT:    [[ADD_3]] = add i32 [[SEXT_3]], [[SUM_3]]
1153; CHECK-NEXT:    [[INC_3]] = add nuw i32 [[J_3]], 1
1154; CHECK-NEXT:    [[EXITCOND_3:%.*]] = icmp eq i32 [[INC_3]], [[E]]
1155; CHECK-NEXT:    br i1 [[EXITCOND_3]], label [[FOR_LATCH]], label [[FOR_INNER]]
1156; CHECK:       for.latch:
1157; CHECK-NEXT:    [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[FOR_INNER]] ]
1158; CHECK-NEXT:    [[ADD_LCSSA_1:%.*]] = phi i32 [ [[ADD_1]], [[FOR_INNER]] ]
1159; CHECK-NEXT:    [[ADD_LCSSA_2:%.*]] = phi i32 [ [[ADD_2]], [[FOR_INNER]] ]
1160; CHECK-NEXT:    [[ADD_LCSSA_3:%.*]] = phi i32 [ [[ADD_3]], [[FOR_INNER]] ]
1161; CHECK-NEXT:    [[ARRAYIDX6:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[I]]
1162; CHECK-NEXT:    store i32 [[ADD_LCSSA]], ptr [[ARRAYIDX6]], align 4, !tbaa [[TBAA0]]
1163; CHECK-NEXT:    [[ARRAYIDX6_1:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[ADD8]]
1164; CHECK-NEXT:    store i32 [[ADD_LCSSA_1]], ptr [[ARRAYIDX6_1]], align 4, !tbaa [[TBAA0]]
1165; CHECK-NEXT:    [[ARRAYIDX6_2:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[ADD8_1]]
1166; CHECK-NEXT:    store i32 [[ADD_LCSSA_2]], ptr [[ARRAYIDX6_2]], align 4, !tbaa [[TBAA0]]
1167; CHECK-NEXT:    [[ARRAYIDX6_3:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[ADD8_2]]
1168; CHECK-NEXT:    store i32 [[ADD_LCSSA_3]], ptr [[ARRAYIDX6_3]], align 4, !tbaa [[TBAA0]]
1169; CHECK-NEXT:    [[NITER_NCMP_3:%.*]] = icmp eq i32 [[NITER_NEXT_3]], [[UNROLL_ITER]]
1170; CHECK-NEXT:    br i1 [[NITER_NCMP_3]], label [[FOR_END_LOOPEXIT_UNR_LCSSA_LOOPEXIT:%.*]], label [[FOR_OUTER]], !llvm.loop [[LOOP12:![0-9]+]]
1171; CHECK:       for.end.loopexit.unr-lcssa.loopexit:
1172; CHECK-NEXT:    [[I_UNR_PH:%.*]] = phi i32 [ [[ADD8_3]], [[FOR_LATCH]] ]
1173; CHECK-NEXT:    br label [[FOR_END_LOOPEXIT_UNR_LCSSA]]
1174; CHECK:       for.end.loopexit.unr-lcssa:
1175; CHECK-NEXT:    [[I_UNR:%.*]] = phi i32 [ 0, [[FOR_OUTER_PREHEADER]] ], [ [[I_UNR_PH]], [[FOR_END_LOOPEXIT_UNR_LCSSA_LOOPEXIT]] ]
1176; CHECK-NEXT:    [[LCMP_MOD:%.*]] = icmp ne i32 [[XTRAITER]], 0
1177; CHECK-NEXT:    br i1 [[LCMP_MOD]], label [[FOR_OUTER_EPIL_PREHEADER:%.*]], label [[FOR_END_LOOPEXIT:%.*]]
1178; CHECK:       for.outer.epil.preheader:
1179; CHECK-NEXT:    br label [[FOR_OUTER_EPIL:%.*]]
1180; CHECK:       for.outer.epil:
1181; CHECK-NEXT:    br label [[FOR_INNER_EPIL:%.*]]
1182; CHECK:       for.inner.epil:
1183; CHECK-NEXT:    [[J_EPIL:%.*]] = phi i32 [ 0, [[FOR_OUTER_EPIL]] ], [ [[INC_EPIL:%.*]], [[FOR_INNER_EPIL]] ]
1184; CHECK-NEXT:    [[SUM_EPIL:%.*]] = phi i32 [ 0, [[FOR_OUTER_EPIL]] ], [ [[ADD_EPIL:%.*]], [[FOR_INNER_EPIL]] ]
1185; CHECK-NEXT:    [[ARRAYIDX_EPIL:%.*]] = getelementptr inbounds i16, ptr [[B]], i32 [[J_EPIL]]
1186; CHECK-NEXT:    [[TMP6:%.*]] = load i16, ptr [[ARRAYIDX_EPIL]], align 4, !tbaa [[TBAA10]]
1187; CHECK-NEXT:    [[SEXT_EPIL:%.*]] = sext i16 [[TMP6]] to i32
1188; CHECK-NEXT:    [[ADD_EPIL]] = add i32 [[SEXT_EPIL]], [[SUM_EPIL]]
1189; CHECK-NEXT:    [[INC_EPIL]] = add nuw i32 [[J_EPIL]], 1
1190; CHECK-NEXT:    [[EXITCOND_EPIL:%.*]] = icmp eq i32 [[INC_EPIL]], [[E]]
1191; CHECK-NEXT:    br i1 [[EXITCOND_EPIL]], label [[FOR_LATCH_EPIL:%.*]], label [[FOR_INNER_EPIL]]
1192; CHECK:       for.latch.epil:
1193; CHECK-NEXT:    [[ADD_LCSSA_EPIL:%.*]] = phi i32 [ [[ADD_EPIL]], [[FOR_INNER_EPIL]] ]
1194; CHECK-NEXT:    [[ARRAYIDX6_EPIL:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_UNR]]
1195; CHECK-NEXT:    store i32 [[ADD_LCSSA_EPIL]], ptr [[ARRAYIDX6_EPIL]], align 4, !tbaa [[TBAA0]]
1196; CHECK-NEXT:    [[ADD8_EPIL:%.*]] = add nuw i32 [[I_UNR]], 1
1197; CHECK-NEXT:    [[EPIL_ITER_CMP:%.*]] = icmp ne i32 1, [[XTRAITER]]
1198; CHECK-NEXT:    br i1 [[EPIL_ITER_CMP]], label [[FOR_OUTER_EPIL_1:%.*]], label [[FOR_END_LOOPEXIT_EPILOG_LCSSA:%.*]]
1199; CHECK:       for.outer.epil.1:
1200; CHECK-NEXT:    br label [[FOR_INNER_EPIL_1:%.*]]
1201; CHECK:       for.inner.epil.1:
1202; CHECK-NEXT:    [[J_EPIL_1:%.*]] = phi i32 [ 0, [[FOR_OUTER_EPIL_1]] ], [ [[INC_EPIL_1:%.*]], [[FOR_INNER_EPIL_1]] ]
1203; CHECK-NEXT:    [[SUM_EPIL_1:%.*]] = phi i32 [ 0, [[FOR_OUTER_EPIL_1]] ], [ [[ADD_EPIL_1:%.*]], [[FOR_INNER_EPIL_1]] ]
1204; CHECK-NEXT:    [[ARRAYIDX_EPIL_1:%.*]] = getelementptr inbounds i16, ptr [[B]], i32 [[J_EPIL_1]]
1205; CHECK-NEXT:    [[TMP7:%.*]] = load i16, ptr [[ARRAYIDX_EPIL_1]], align 4, !tbaa [[TBAA10]]
1206; CHECK-NEXT:    [[SEXT_EPIL_1:%.*]] = sext i16 [[TMP7]] to i32
1207; CHECK-NEXT:    [[ADD_EPIL_1]] = add i32 [[SEXT_EPIL_1]], [[SUM_EPIL_1]]
1208; CHECK-NEXT:    [[INC_EPIL_1]] = add nuw i32 [[J_EPIL_1]], 1
1209; CHECK-NEXT:    [[EXITCOND_EPIL_1:%.*]] = icmp eq i32 [[INC_EPIL_1]], [[E]]
1210; CHECK-NEXT:    br i1 [[EXITCOND_EPIL_1]], label [[FOR_LATCH_EPIL_1:%.*]], label [[FOR_INNER_EPIL_1]]
1211; CHECK:       for.latch.epil.1:
1212; CHECK-NEXT:    [[ADD_LCSSA_EPIL_1:%.*]] = phi i32 [ [[ADD_EPIL_1]], [[FOR_INNER_EPIL_1]] ]
1213; CHECK-NEXT:    [[ARRAYIDX6_EPIL_1:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[ADD8_EPIL]]
1214; CHECK-NEXT:    store i32 [[ADD_LCSSA_EPIL_1]], ptr [[ARRAYIDX6_EPIL_1]], align 4, !tbaa [[TBAA0]]
1215; CHECK-NEXT:    [[ADD8_EPIL_1:%.*]] = add nuw i32 [[I_UNR]], 2
1216; CHECK-NEXT:    [[EPIL_ITER_CMP_1:%.*]] = icmp ne i32 2, [[XTRAITER]]
1217; CHECK-NEXT:    br i1 [[EPIL_ITER_CMP_1]], label [[FOR_OUTER_EPIL_2:%.*]], label [[FOR_END_LOOPEXIT_EPILOG_LCSSA]]
1218; CHECK:       for.outer.epil.2:
1219; CHECK-NEXT:    br label [[FOR_INNER_EPIL_2:%.*]]
1220; CHECK:       for.inner.epil.2:
1221; CHECK-NEXT:    [[J_EPIL_2:%.*]] = phi i32 [ 0, [[FOR_OUTER_EPIL_2]] ], [ [[INC_EPIL_2:%.*]], [[FOR_INNER_EPIL_2]] ]
1222; CHECK-NEXT:    [[SUM_EPIL_2:%.*]] = phi i32 [ 0, [[FOR_OUTER_EPIL_2]] ], [ [[ADD_EPIL_2:%.*]], [[FOR_INNER_EPIL_2]] ]
1223; CHECK-NEXT:    [[ARRAYIDX_EPIL_2:%.*]] = getelementptr inbounds i16, ptr [[B]], i32 [[J_EPIL_2]]
1224; CHECK-NEXT:    [[TMP8:%.*]] = load i16, ptr [[ARRAYIDX_EPIL_2]], align 4, !tbaa [[TBAA10]]
1225; CHECK-NEXT:    [[SEXT_EPIL_2:%.*]] = sext i16 [[TMP8]] to i32
1226; CHECK-NEXT:    [[ADD_EPIL_2]] = add i32 [[SEXT_EPIL_2]], [[SUM_EPIL_2]]
1227; CHECK-NEXT:    [[INC_EPIL_2]] = add nuw i32 [[J_EPIL_2]], 1
1228; CHECK-NEXT:    [[EXITCOND_EPIL_2:%.*]] = icmp eq i32 [[INC_EPIL_2]], [[E]]
1229; CHECK-NEXT:    br i1 [[EXITCOND_EPIL_2]], label [[FOR_LATCH_EPIL_2:%.*]], label [[FOR_INNER_EPIL_2]]
1230; CHECK:       for.latch.epil.2:
1231; CHECK-NEXT:    [[ADD_LCSSA_EPIL_2:%.*]] = phi i32 [ [[ADD_EPIL_2]], [[FOR_INNER_EPIL_2]] ]
1232; CHECK-NEXT:    [[ARRAYIDX6_EPIL_2:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[ADD8_EPIL_1]]
1233; CHECK-NEXT:    store i32 [[ADD_LCSSA_EPIL_2]], ptr [[ARRAYIDX6_EPIL_2]], align 4, !tbaa [[TBAA0]]
1234; CHECK-NEXT:    br label [[FOR_END_LOOPEXIT_EPILOG_LCSSA]]
1235; CHECK:       for.end.loopexit.epilog-lcssa:
1236; CHECK-NEXT:    br label [[FOR_END_LOOPEXIT]]
1237; CHECK:       for.end.loopexit:
1238; CHECK-NEXT:    br label [[FOR_END]]
1239; CHECK:       for.end:
1240; CHECK-NEXT:    ret void
1241;
1242entry:
1243  %cmp = icmp ne i32 %E, 0
1244  %cmpJ = icmp ne i32 %I, 0
1245  %or.cond = and i1 %cmp, %cmpJ
1246  br i1 %or.cond, label %for.outer.preheader, label %for.end
1247
1248for.outer.preheader:
1249  br label %for.outer
1250
1251for.outer:
1252  %i = phi i32 [ %add8, %for.latch ], [ 0, %for.outer.preheader ]
1253  br label %for.inner
1254
1255for.inner:
1256  %j = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ]
1257  %sum = phi i32 [ 0, %for.outer ], [ %add, %for.inner ]
1258  %arrayidx = getelementptr inbounds i16, ptr %B, i32 %j
1259  %0 = load i16, ptr %arrayidx, align 4, !tbaa !9
1260  %sext = sext i16 %0 to i32
1261  %add = add i32 %sext, %sum
1262  %inc = add nuw i32 %j, 1
1263  %exitcond = icmp eq i32 %inc, %E
1264  br i1 %exitcond, label %for.latch, label %for.inner
1265
1266for.latch:
1267  %add.lcssa = phi i32 [ %add, %for.inner ]
1268  %arrayidx6 = getelementptr inbounds i32, ptr %A, i32 %i
1269  store i32 %add.lcssa, ptr %arrayidx6, align 4, !tbaa !5
1270  %add8 = add nuw i32 %i, 1
1271  %exitcond25 = icmp eq i32 %add8, %I
1272  br i1 %exitcond25, label %for.end.loopexit, label %for.outer
1273
1274for.end.loopexit:
1275  br label %for.end
1276
1277for.end:
1278  ret void
1279}
1280
1281
1282; Be careful not to incorrectly update the exit phi nodes
1283%struct.a = type { i64 }
1284@g = common global %struct.a zeroinitializer, align 8
1285@c = common global [1 x i8] zeroinitializer, align 1
1286define signext i16 @test10(i32 %k) #0 {
1287; CHECK-LABEL: @test10(
1288; CHECK-NEXT:  entry:
1289; CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr @c, align 1
1290; CHECK-NEXT:    [[TOBOOL9:%.*]] = icmp eq i8 [[TMP0]], 0
1291; CHECK-NEXT:    [[TOBOOL13:%.*]] = icmp ne i32 [[K:%.*]], 0
1292; CHECK-NEXT:    br i1 false, label [[FOR_END26_UNR_LCSSA:%.*]], label [[ENTRY_NEW:%.*]]
1293; CHECK:       entry.new:
1294; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
1295; CHECK:       for.body:
1296; CHECK-NEXT:    [[STOREMERGE82:%.*]] = phi i64 [ 0, [[ENTRY_NEW]] ], [ [[INC25_3:%.*]], [[FOR_INC24:%.*]] ]
1297; CHECK-NEXT:    [[NITER:%.*]] = phi i64 [ 0, [[ENTRY_NEW]] ], [ [[NITER_NEXT_3:%.*]], [[FOR_INC24]] ]
1298; CHECK-NEXT:    [[INC25_3]] = add nuw nsw i64 [[STOREMERGE82]], 4
1299; CHECK-NEXT:    [[NITER_NEXT_3]] = add nuw nsw i64 [[NITER]], 4
1300; CHECK-NEXT:    br label [[FOR_BODY2:%.*]]
1301; CHECK:       for.body2:
1302; CHECK-NEXT:    [[STOREMERGE:%.*]] = phi i64 [ 4, [[FOR_BODY]] ], [ [[DEC:%.*]], [[FOR_INC21_3:%.*]] ]
1303; CHECK-NEXT:    [[STOREMERGE_14:%.*]] = phi i64 [ 4, [[FOR_BODY]] ], [ [[DEC_1:%.*]], [[FOR_INC21_3]] ]
1304; CHECK-NEXT:    [[STOREMERGE_25:%.*]] = phi i64 [ 4, [[FOR_BODY]] ], [ [[DEC_2:%.*]], [[FOR_INC21_3]] ]
1305; CHECK-NEXT:    [[STOREMERGE_36:%.*]] = phi i64 [ 4, [[FOR_BODY]] ], [ [[DEC_3:%.*]], [[FOR_INC21_3]] ]
1306; CHECK-NEXT:    br i1 [[TOBOOL9]], label [[FOR_BODY2_SPLIT:%.*]], label [[FOR_BODY2_SPLIT2:%.*]]
1307; CHECK:       for.body2.split2:
1308; CHECK-NEXT:    br i1 [[TOBOOL13]], label [[FOR_INC21:%.*]], label [[FOR_INC21_IF:%.*]]
1309; CHECK:       for.body2.split:
1310; CHECK-NEXT:    br i1 [[TOBOOL13]], label [[FOR_INC21]], label [[FOR_INC21_THEN:%.*]]
1311; CHECK:       for.inc21.if:
1312; CHECK-NEXT:    br label [[FOR_INC21]]
1313; CHECK:       for.inc21.then:
1314; CHECK-NEXT:    br label [[FOR_INC21]]
1315; CHECK:       for.inc21:
1316; CHECK-NEXT:    [[DEC]] = add nsw i64 [[STOREMERGE]], -1
1317; CHECK-NEXT:    br i1 [[TOBOOL9]], label [[FOR_BODY2_SPLIT_1:%.*]], label [[FOR_BODY2_SPLIT2_1:%.*]]
1318; CHECK:       for.inc24:
1319; CHECK-NEXT:    [[STOREMERGE_4_LCSSA_3:%.*]] = phi i64 [ [[STOREMERGE_4_3:%.*]], [[FOR_INC21_3]] ]
1320; CHECK-NEXT:    br i1 false, label [[FOR_BODY]], label [[FOR_END26_UNR_LCSSA_LOOPEXIT:%.*]], !llvm.loop [[LOOP13:![0-9]+]]
1321; CHECK:       for.end26.unr-lcssa.loopexit:
1322; CHECK-NEXT:    [[DEC_LCSSA_LCSSA_PH_PH:%.*]] = phi i64 [ 0, [[FOR_INC24]] ]
1323; CHECK-NEXT:    [[STOREMERGE_4_LCSSA_LCSSA_PH_PH:%.*]] = phi i64 [ [[STOREMERGE_4_LCSSA_3]], [[FOR_INC24]] ]
1324; CHECK-NEXT:    [[STOREMERGE_5_LCSSA_LCSSA_PH_PH:%.*]] = phi i32 [ 0, [[FOR_INC24]] ]
1325; CHECK-NEXT:    br label [[FOR_END26_UNR_LCSSA]]
1326; CHECK:       for.end26.unr-lcssa:
1327; CHECK-NEXT:    [[DEC_LCSSA_LCSSA_PH:%.*]] = phi i64 [ poison, [[ENTRY:%.*]] ], [ [[DEC_LCSSA_LCSSA_PH_PH]], [[FOR_END26_UNR_LCSSA_LOOPEXIT]] ]
1328; CHECK-NEXT:    [[STOREMERGE_4_LCSSA_LCSSA_PH:%.*]] = phi i64 [ poison, [[ENTRY]] ], [ [[STOREMERGE_4_LCSSA_LCSSA_PH_PH]], [[FOR_END26_UNR_LCSSA_LOOPEXIT]] ]
1329; CHECK-NEXT:    [[STOREMERGE_5_LCSSA_LCSSA_PH:%.*]] = phi i32 [ poison, [[ENTRY]] ], [ [[STOREMERGE_5_LCSSA_LCSSA_PH_PH]], [[FOR_END26_UNR_LCSSA_LOOPEXIT]] ]
1330; CHECK-NEXT:    br i1 true, label [[FOR_BODY_EPIL_PREHEADER:%.*]], label [[FOR_END26:%.*]]
1331; CHECK:       for.body.epil.preheader:
1332; CHECK-NEXT:    br label [[FOR_BODY_EPIL:%.*]]
1333; CHECK:       for.body.epil:
1334; CHECK-NEXT:    br label [[FOR_BODY2_EPIL:%.*]]
1335; CHECK:       for.body2.epil:
1336; CHECK-NEXT:    [[STOREMERGE_EPIL:%.*]] = phi i64 [ 4, [[FOR_BODY_EPIL]] ], [ [[DEC_EPIL:%.*]], [[FOR_INC21_EPIL:%.*]] ]
1337; CHECK-NEXT:    br i1 [[TOBOOL9]], label [[FOR_BODY2_SPLIT_EPIL:%.*]], label [[FOR_BODY2_SPLIT2_EPIL:%.*]]
1338; CHECK:       for.body2.split2.epil:
1339; CHECK-NEXT:    br i1 [[TOBOOL13]], label [[FOR_INC21_EPIL]], label [[FOR_INC21_IF_EPIL:%.*]]
1340; CHECK:       for.inc21.if.epil:
1341; CHECK-NEXT:    br label [[FOR_INC21_EPIL]]
1342; CHECK:       for.body2.split.epil:
1343; CHECK-NEXT:    br i1 [[TOBOOL13]], label [[FOR_INC21_EPIL]], label [[FOR_INC21_THEN_EPIL:%.*]]
1344; CHECK:       for.inc21.then.epil:
1345; CHECK-NEXT:    br label [[FOR_INC21_EPIL]]
1346; CHECK:       for.inc21.epil:
1347; CHECK-NEXT:    [[STOREMERGE_4_EPIL:%.*]] = phi i64 [ 0, [[FOR_INC21_IF_EPIL]] ], [ 0, [[FOR_INC21_THEN_EPIL]] ], [ 4, [[FOR_BODY2_SPLIT2_EPIL]] ], [ 4, [[FOR_BODY2_SPLIT_EPIL]] ]
1348; CHECK-NEXT:    [[DEC_EPIL]] = add nsw i64 [[STOREMERGE_EPIL]], -1
1349; CHECK-NEXT:    [[TOBOOL_EPIL:%.*]] = icmp eq i64 [[DEC_EPIL]], 0
1350; CHECK-NEXT:    br i1 [[TOBOOL_EPIL]], label [[FOR_INC24_EPIL:%.*]], label [[FOR_BODY2_EPIL]]
1351; CHECK:       for.inc24.epil:
1352; CHECK-NEXT:    [[STOREMERGE_4_LCSSA_EPIL:%.*]] = phi i64 [ [[STOREMERGE_4_EPIL]], [[FOR_INC21_EPIL]] ]
1353; CHECK-NEXT:    br label [[FOR_END26]]
1354; CHECK:       for.end26:
1355; CHECK-NEXT:    [[DEC_LCSSA_LCSSA:%.*]] = phi i64 [ [[DEC_LCSSA_LCSSA_PH]], [[FOR_END26_UNR_LCSSA]] ], [ 0, [[FOR_INC24_EPIL]] ]
1356; CHECK-NEXT:    [[STOREMERGE_4_LCSSA_LCSSA:%.*]] = phi i64 [ [[STOREMERGE_4_LCSSA_LCSSA_PH]], [[FOR_END26_UNR_LCSSA]] ], [ [[STOREMERGE_4_LCSSA_EPIL]], [[FOR_INC24_EPIL]] ]
1357; CHECK-NEXT:    [[STOREMERGE_5_LCSSA_LCSSA:%.*]] = phi i32 [ [[STOREMERGE_5_LCSSA_LCSSA_PH]], [[FOR_END26_UNR_LCSSA]] ], [ 0, [[FOR_INC24_EPIL]] ]
1358; CHECK-NEXT:    store i64 [[DEC_LCSSA_LCSSA]], ptr @g, align 8
1359; CHECK-NEXT:    ret i16 0
1360; CHECK:       for.body2.split2.1:
1361; CHECK-NEXT:    br i1 [[TOBOOL13]], label [[FOR_INC21_1:%.*]], label [[FOR_INC21_IF_1:%.*]]
1362; CHECK:       for.inc21.if.1:
1363; CHECK-NEXT:    br label [[FOR_INC21_1]]
1364; CHECK:       for.body2.split.1:
1365; CHECK-NEXT:    br i1 [[TOBOOL13]], label [[FOR_INC21_1]], label [[FOR_INC21_THEN_1:%.*]]
1366; CHECK:       for.inc21.then.1:
1367; CHECK-NEXT:    br label [[FOR_INC21_1]]
1368; CHECK:       for.inc21.1:
1369; CHECK-NEXT:    [[DEC_1]] = add nsw i64 [[STOREMERGE_14]], -1
1370; CHECK-NEXT:    br i1 [[TOBOOL9]], label [[FOR_BODY2_SPLIT_2:%.*]], label [[FOR_BODY2_SPLIT2_2:%.*]]
1371; CHECK:       for.body2.split2.2:
1372; CHECK-NEXT:    br i1 [[TOBOOL13]], label [[FOR_INC21_2:%.*]], label [[FOR_INC21_IF_2:%.*]]
1373; CHECK:       for.inc21.if.2:
1374; CHECK-NEXT:    br label [[FOR_INC21_2]]
1375; CHECK:       for.body2.split.2:
1376; CHECK-NEXT:    br i1 [[TOBOOL13]], label [[FOR_INC21_2]], label [[FOR_INC21_THEN_2:%.*]]
1377; CHECK:       for.inc21.then.2:
1378; CHECK-NEXT:    br label [[FOR_INC21_2]]
1379; CHECK:       for.inc21.2:
1380; CHECK-NEXT:    [[DEC_2]] = add nsw i64 [[STOREMERGE_25]], -1
1381; CHECK-NEXT:    br i1 [[TOBOOL9]], label [[FOR_BODY2_SPLIT_3:%.*]], label [[FOR_BODY2_SPLIT2_3:%.*]]
1382; CHECK:       for.body2.split2.3:
1383; CHECK-NEXT:    br i1 [[TOBOOL13]], label [[FOR_INC21_3]], label [[FOR_INC21_IF_3:%.*]]
1384; CHECK:       for.inc21.if.3:
1385; CHECK-NEXT:    br label [[FOR_INC21_3]]
1386; CHECK:       for.body2.split.3:
1387; CHECK-NEXT:    br i1 [[TOBOOL13]], label [[FOR_INC21_3]], label [[FOR_INC21_THEN_3:%.*]]
1388; CHECK:       for.inc21.then.3:
1389; CHECK-NEXT:    br label [[FOR_INC21_3]]
1390; CHECK:       for.inc21.3:
1391; CHECK-NEXT:    [[STOREMERGE_4_3]] = phi i64 [ 0, [[FOR_INC21_IF_3]] ], [ 0, [[FOR_INC21_THEN_3]] ], [ 4, [[FOR_BODY2_SPLIT2_3]] ], [ 4, [[FOR_BODY2_SPLIT_3]] ]
1392; CHECK-NEXT:    [[DEC_3]] = add nsw i64 [[STOREMERGE_36]], -1
1393; CHECK-NEXT:    [[TOBOOL_3:%.*]] = icmp eq i64 [[DEC_3]], 0
1394; CHECK-NEXT:    br i1 [[TOBOOL_3]], label [[FOR_INC24]], label [[FOR_BODY2]]
1395;
1396entry:
1397  %0 = load i8, ptr @c, align 1
1398  %tobool9 = icmp eq i8 %0, 0
1399  %tobool13 = icmp ne i32 %k, 0
1400  br label %for.body
1401
1402for.body:
1403  %storemerge82 = phi i64 [ 0, %entry ], [ %inc25, %for.inc24 ]
1404  br label %for.body2
1405
1406for.body2:
1407  %storemerge = phi i64 [ 4, %for.body ], [ %dec, %for.inc21 ]
1408  br i1 %tobool9, label %for.body2.split, label %for.body2.split2
1409
1410for.body2.split2:
1411  br i1 %tobool13, label %for.inc21, label %for.inc21.if
1412
1413for.body2.split:
1414  br i1 %tobool13, label %for.inc21, label %for.inc21.then
1415
1416for.inc21.if:
1417  %storemerge.1 = phi i64 [ 0, %for.body2.split2 ]
1418  br label %for.inc21
1419
1420for.inc21.then:
1421  %storemerge.2 = phi i64 [ 0, %for.body2.split ]
1422  %storemerge.3 = phi i32 [ 0, %for.body2.split ]
1423  br label %for.inc21
1424
1425for.inc21:
1426  %storemerge.4 = phi i64 [ %storemerge.1, %for.inc21.if ], [ %storemerge.2, %for.inc21.then ], [ 4, %for.body2.split2 ], [ 4, %for.body2.split ]
1427  %storemerge.5 = phi i32 [ 0, %for.inc21.if ], [ %storemerge.3, %for.inc21.then ], [ 0, %for.body2.split2 ], [ 0, %for.body2.split ]
1428  %dec = add nsw i64 %storemerge, -1
1429  %tobool = icmp eq i64 %dec, 0
1430  br i1 %tobool, label %for.inc24, label %for.body2
1431
1432for.inc24:
1433  %storemerge.4.lcssa = phi i64 [ %storemerge.4, %for.inc21 ]
1434  %storemerge.5.lcssa = phi i32 [ %storemerge.5, %for.inc21 ]
1435  %inc25 = add nuw nsw i64 %storemerge82, 1
1436  %exitcond = icmp ne i64 %inc25, 5
1437  br i1 %exitcond, label %for.body, label %for.end26
1438
1439for.end26:
1440  %dec.lcssa.lcssa = phi i64 [ 0, %for.inc24 ]
1441  %storemerge.4.lcssa.lcssa = phi i64 [ %storemerge.4.lcssa, %for.inc24 ]
1442  %storemerge.5.lcssa.lcssa = phi i32 [ %storemerge.5.lcssa, %for.inc24 ]
1443  store i64 %dec.lcssa.lcssa, ptr @g, align 8
1444  ret i16 0
1445}
1446
1447
1448!5 = !{!6, !6, i64 0}
1449!6 = !{!"int", !7, i64 0}
1450!7 = !{!"omnipotent char", !8, i64 0}
1451!8 = !{!"Simple C/C++ TBAA"}
1452!9 = !{!10, !10, i64 0}
1453!10 = !{!"short", !7, i64 0}
1454