[DAGCombiner] Add target hook function to decide folding (mul (add x, c1), c2)
[llvm-project.git] / llvm / test / Transforms / LoopUnrollAndJam / unroll-and-jam.ll
blob88fdd43fafff69858a97477345eacf42db078f14
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -basic-aa -tbaa -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
5 target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
7 ; CHECK-LABEL: test1
8 ; Tests for(i) { sum = 0; for(j) sum += B[j]; A[i] = sum; }
9 ; CHECK-NEXT:  entry:
10 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[J:%.*]], 0
11 ; CHECK-NEXT:    [[CMPJ:%.*]] = icmp ne i32 [[I:%.*]], 0
12 ; CHECK-NEXT:    [[OR_COND:%.*]] = and i1 [[CMP]], [[CMPJ]]
13 ; CHECK-NEXT:    br i1 [[OR_COND]], label [[FOR_OUTER_PREHEADER:%.*]], label [[FOR_END:%.*]]
14 ; CHECK:       for.outer.preheader:
15 ; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[I]], -1
16 ; CHECK-NEXT:    [[XTRAITER:%.*]] = and i32 [[I]], 3
17 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 [[TMP0]], 3
18 ; CHECK-NEXT:    br i1 [[TMP1]], label [[FOR_END_LOOPEXIT_UNR_LCSSA:%.*]], label [[FOR_OUTER_PREHEADER_NEW:%.*]]
19 ; CHECK:       for.outer.preheader.new:
20 ; CHECK-NEXT:    [[UNROLL_ITER:%.*]] = sub i32 [[I]], [[XTRAITER]]
21 ; CHECK-NEXT:    br label [[FOR_OUTER:%.*]]
22 ; CHECK:       for.outer:
23 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[ADD8_3:%.*]], [[FOR_LATCH:%.*]] ], [ 0, [[FOR_OUTER_PREHEADER_NEW]] ]
24 ; CHECK-NEXT:    [[NITER:%.*]] = phi i32 [ [[UNROLL_ITER]], [[FOR_OUTER_PREHEADER_NEW]] ], [ [[NITER_NSUB_3:%.*]], [[FOR_LATCH]] ]
25 ; CHECK-NEXT:    [[ADD8:%.*]] = add nuw nsw i32 [[I]], 1
26 ; CHECK-NEXT:    [[NITER_NSUB:%.*]] = sub i32 [[NITER]], 1
27 ; CHECK-NEXT:    [[ADD8_1:%.*]] = add nuw nsw i32 [[ADD8]], 1
28 ; CHECK-NEXT:    [[NITER_NSUB_1:%.*]] = sub i32 [[NITER_NSUB]], 1
29 ; CHECK-NEXT:    [[ADD8_2:%.*]] = add nuw nsw i32 [[ADD8_1]], 1
30 ; CHECK-NEXT:    [[NITER_NSUB_2:%.*]] = sub i32 [[NITER_NSUB_1]], 1
31 ; CHECK-NEXT:    [[ADD8_3]] = add nuw i32 [[ADD8_2]], 1
32 ; CHECK-NEXT:    [[NITER_NSUB_3]] = sub i32 [[NITER_NSUB_2]], 1
33 ; CHECK-NEXT:    br label [[FOR_INNER:%.*]]
34 ; CHECK:       for.inner:
35 ; CHECK-NEXT:    [[J_0:%.*]] = phi i32 [ 0, [[FOR_OUTER]] ], [ [[INC:%.*]], [[FOR_INNER]] ]
36 ; CHECK-NEXT:    [[SUM:%.*]] = phi i32 [ 0, [[FOR_OUTER]] ], [ [[ADD:%.*]], [[FOR_INNER]] ]
37 ; CHECK-NEXT:    [[J_1:%.*]] = phi i32 [ 0, [[FOR_OUTER]] ], [ [[INC_1:%.*]], [[FOR_INNER]] ]
38 ; CHECK-NEXT:    [[SUM_1:%.*]] = phi i32 [ 0, [[FOR_OUTER]] ], [ [[ADD_1:%.*]], [[FOR_INNER]] ]
39 ; CHECK-NEXT:    [[J_2:%.*]] = phi i32 [ 0, [[FOR_OUTER]] ], [ [[INC_2:%.*]], [[FOR_INNER]] ]
40 ; CHECK-NEXT:    [[SUM_2:%.*]] = phi i32 [ 0, [[FOR_OUTER]] ], [ [[ADD_2:%.*]], [[FOR_INNER]] ]
41 ; CHECK-NEXT:    [[J_3:%.*]] = phi i32 [ 0, [[FOR_OUTER]] ], [ [[INC_3:%.*]], [[FOR_INNER]] ]
42 ; CHECK-NEXT:    [[SUM_3:%.*]] = phi i32 [ 0, [[FOR_OUTER]] ], [ [[ADD_3:%.*]], [[FOR_INNER]] ]
43 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[B:%.*]], i32 [[J_0]]
44 ; CHECK-NEXT:    [[TMP2:%.*]] = load i32, i32* [[ARRAYIDX]], align 4, !tbaa !0
45 ; CHECK-NEXT:    [[ADD]] = add i32 [[TMP2]], [[SUM]]
46 ; CHECK-NEXT:    [[INC]] = add nuw i32 [[J_0]], 1
47 ; CHECK-NEXT:    [[ARRAYIDX_1:%.*]] = getelementptr inbounds i32, i32* [[B]], i32 [[J_1]]
48 ; CHECK-NEXT:    [[TMP3:%.*]] = load i32, i32* [[ARRAYIDX_1]], align 4, !tbaa !0
49 ; CHECK-NEXT:    [[ADD_1]] = add i32 [[TMP3]], [[SUM_1]]
50 ; CHECK-NEXT:    [[INC_1]] = add nuw i32 [[J_1]], 1
51 ; CHECK-NEXT:    [[ARRAYIDX_2:%.*]] = getelementptr inbounds i32, i32* [[B]], i32 [[J_2]]
52 ; CHECK-NEXT:    [[TMP4:%.*]] = load i32, i32* [[ARRAYIDX_2]], align 4, !tbaa !0
53 ; CHECK-NEXT:    [[ADD_2]] = add i32 [[TMP4]], [[SUM_2]]
54 ; CHECK-NEXT:    [[INC_2]] = add nuw i32 [[J_2]], 1
55 ; CHECK-NEXT:    [[ARRAYIDX_3:%.*]] = getelementptr inbounds i32, i32* [[B]], i32 [[J_3]]
56 ; CHECK-NEXT:    [[TMP5:%.*]] = load i32, i32* [[ARRAYIDX_3]], align 4, !tbaa !0
57 ; CHECK-NEXT:    [[ADD_3]] = add i32 [[TMP5]], [[SUM_3]]
58 ; CHECK-NEXT:    [[INC_3]] = add nuw i32 [[J_3]], 1
59 ; CHECK-NEXT:    [[EXITCOND_3:%.*]] = icmp eq i32 [[INC_3]], [[J]]
60 ; CHECK-NEXT:    br i1 [[EXITCOND_3]], label [[FOR_LATCH]], label [[FOR_INNER]]
61 ; CHECK:       for.latch:
62 ; CHECK-NEXT:    [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[FOR_INNER]] ]
63 ; CHECK-NEXT:    [[ADD_LCSSA_1:%.*]] = phi i32 [ [[ADD_1]], [[FOR_INNER]] ]
64 ; CHECK-NEXT:    [[ADD_LCSSA_2:%.*]] = phi i32 [ [[ADD_2]], [[FOR_INNER]] ]
65 ; CHECK-NEXT:    [[ADD_LCSSA_3:%.*]] = phi i32 [ [[ADD_3]], [[FOR_INNER]] ]
66 ; CHECK-NEXT:    [[ARRAYIDX6:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i32 [[I]]
67 ; CHECK-NEXT:    store i32 [[ADD_LCSSA]], i32* [[ARRAYIDX6]], align 4, !tbaa !0
68 ; CHECK-NEXT:    [[ARRAYIDX6_1:%.*]] = getelementptr inbounds i32, i32* [[A]], i32 [[ADD8]]
69 ; CHECK-NEXT:    store i32 [[ADD_LCSSA_1]], i32* [[ARRAYIDX6_1]], align 4, !tbaa !0
70 ; CHECK-NEXT:    [[ARRAYIDX6_2:%.*]] = getelementptr inbounds i32, i32* [[A]], i32 [[ADD8_1]]
71 ; CHECK-NEXT:    store i32 [[ADD_LCSSA_2]], i32* [[ARRAYIDX6_2]], align 4, !tbaa !0
72 ; CHECK-NEXT:    [[ARRAYIDX6_3:%.*]] = getelementptr inbounds i32, i32* [[A]], i32 [[ADD8_2]]
73 ; CHECK-NEXT:    store i32 [[ADD_LCSSA_3]], i32* [[ARRAYIDX6_3]], align 4, !tbaa !0
74 ; CHECK-NEXT:    [[NITER_NCMP_3:%.*]] = icmp eq i32 [[NITER_NSUB_3]], 0
75 ; CHECK-NEXT:    br i1 [[NITER_NCMP_3]], label [[FOR_END_LOOPEXIT_UNR_LCSSA_LOOPEXIT:%.*]], label [[FOR_OUTER]], !llvm.loop !4
76 ; CHECK:       for.end.loopexit.unr-lcssa.loopexit:
77 ; CHECK-NEXT:    [[I_UNR_PH:%.*]] = phi i32 [ [[ADD8_3]], [[FOR_LATCH]] ]
78 ; CHECK-NEXT:    br label [[FOR_END_LOOPEXIT_UNR_LCSSA]]
79 ; CHECK:       for.end.loopexit.unr-lcssa:
80 ; CHECK-NEXT:    [[I_UNR:%.*]] = phi i32 [ 0, [[FOR_OUTER_PREHEADER]] ], [ [[I_UNR_PH]], [[FOR_END_LOOPEXIT_UNR_LCSSA_LOOPEXIT]] ]
81 ; CHECK-NEXT:    [[LCMP_MOD:%.*]] = icmp ne i32 [[XTRAITER]], 0
82 ; CHECK-NEXT:    br i1 [[LCMP_MOD]], label [[FOR_OUTER_EPIL_PREHEADER:%.*]], label [[FOR_END_LOOPEXIT:%.*]]
83 ; CHECK:       for.outer.epil.preheader:
84 ; CHECK-NEXT:    br label [[FOR_OUTER_EPIL:%.*]]
85 ; CHECK:       for.outer.epil:
86 ; CHECK-NEXT:    br label [[FOR_INNER_EPIL:%.*]]
87 ; CHECK:       for.inner.epil:
88 ; CHECK-NEXT:    [[J_EPIL:%.*]] = phi i32 [ 0, [[FOR_OUTER_EPIL]] ], [ [[INC_EPIL:%.*]], [[FOR_INNER_EPIL]] ]
89 ; CHECK-NEXT:    [[SUM_EPIL:%.*]] = phi i32 [ 0, [[FOR_OUTER_EPIL]] ], [ [[ADD_EPIL:%.*]], [[FOR_INNER_EPIL]] ]
90 ; CHECK-NEXT:    [[ARRAYIDX_EPIL:%.*]] = getelementptr inbounds i32, i32* [[B]], i32 [[J_EPIL]]
91 ; CHECK-NEXT:    [[TMP6:%.*]] = load i32, i32* [[ARRAYIDX_EPIL]], align 4, !tbaa !0
92 ; CHECK-NEXT:    [[ADD_EPIL]] = add i32 [[TMP6]], [[SUM_EPIL]]
93 ; CHECK-NEXT:    [[INC_EPIL]] = add nuw i32 [[J_EPIL]], 1
94 ; CHECK-NEXT:    [[EXITCOND_EPIL:%.*]] = icmp eq i32 [[INC_EPIL]], [[J]]
95 ; CHECK-NEXT:    br i1 [[EXITCOND_EPIL]], label [[FOR_LATCH_EPIL:%.*]], label [[FOR_INNER_EPIL]]
96 ; CHECK:       for.latch.epil:
97 ; CHECK-NEXT:    [[ADD_LCSSA_EPIL:%.*]] = phi i32 [ [[ADD_EPIL]], [[FOR_INNER_EPIL]] ]
98 ; CHECK-NEXT:    [[ARRAYIDX6_EPIL:%.*]] = getelementptr inbounds i32, i32* [[A]], i32 [[I_UNR]]
99 ; CHECK-NEXT:    store i32 [[ADD_LCSSA_EPIL]], i32* [[ARRAYIDX6_EPIL]], align 4, !tbaa !0
100 ; CHECK-NEXT:    [[ADD8_EPIL:%.*]] = add nuw i32 [[I_UNR]], 1
101 ; CHECK-NEXT:    [[EPIL_ITER_SUB:%.*]] = sub i32 [[XTRAITER]], 1
102 ; CHECK-NEXT:    [[EPIL_ITER_CMP:%.*]] = icmp ne i32 [[EPIL_ITER_SUB]], 0
103 ; CHECK-NEXT:    br i1 [[EPIL_ITER_CMP]], label [[FOR_OUTER_EPIL_1:%.*]], label [[FOR_END_LOOPEXIT_EPILOG_LCSSA:%.*]]
104 ; CHECK:       for.end.loopexit.epilog-lcssa:
105 ; CHECK-NEXT:    br label [[FOR_END_LOOPEXIT]]
106 ; CHECK:       for.end.loopexit:
107 ; CHECK-NEXT:    br label [[FOR_END]]
108 ; CHECK:       for.end:
109 ; CHECK-NEXT:    ret void
110 ; CHECK:       for.outer.epil.1:
111 ; CHECK-NEXT:    br label [[FOR_INNER_EPIL_1:%.*]]
112 ; CHECK:       for.inner.epil.1:
113 ; CHECK-NEXT:    [[J_EPIL_1:%.*]] = phi i32 [ 0, [[FOR_OUTER_EPIL_1]] ], [ [[INC_EPIL_1:%.*]], [[FOR_INNER_EPIL_1]] ]
114 ; CHECK-NEXT:    [[SUM_EPIL_1:%.*]] = phi i32 [ 0, [[FOR_OUTER_EPIL_1]] ], [ [[ADD_EPIL_1:%.*]], [[FOR_INNER_EPIL_1]] ]
115 ; CHECK-NEXT:    [[ARRAYIDX_EPIL_1:%.*]] = getelementptr inbounds i32, i32* [[B]], i32 [[J_EPIL_1]]
116 ; CHECK-NEXT:    [[TMP7:%.*]] = load i32, i32* [[ARRAYIDX_EPIL_1]], align 4, !tbaa !0
117 ; CHECK-NEXT:    [[ADD_EPIL_1]] = add i32 [[TMP7]], [[SUM_EPIL_1]]
118 ; CHECK-NEXT:    [[INC_EPIL_1]] = add nuw i32 [[J_EPIL_1]], 1
119 ; CHECK-NEXT:    [[EXITCOND_EPIL_1:%.*]] = icmp eq i32 [[INC_EPIL_1]], [[J]]
120 ; CHECK-NEXT:    br i1 [[EXITCOND_EPIL_1]], label [[FOR_LATCH_EPIL_1:%.*]], label [[FOR_INNER_EPIL_1]]
121 ; CHECK:       for.latch.epil.1:
122 ; CHECK-NEXT:    [[ADD_LCSSA_EPIL_1:%.*]] = phi i32 [ [[ADD_EPIL_1]], [[FOR_INNER_EPIL_1]] ]
123 ; CHECK-NEXT:    [[ARRAYIDX6_EPIL_1:%.*]] = getelementptr inbounds i32, i32* [[A]], i32 [[ADD8_EPIL]]
124 ; CHECK-NEXT:    store i32 [[ADD_LCSSA_EPIL_1]], i32* [[ARRAYIDX6_EPIL_1]], align 4, !tbaa !0
125 ; CHECK-NEXT:    [[ADD8_EPIL_1:%.*]] = add nuw i32 [[ADD8_EPIL]], 1
126 ; CHECK-NEXT:    [[EPIL_ITER_SUB_1:%.*]] = sub i32 [[EPIL_ITER_SUB]], 1
127 ; CHECK-NEXT:    [[EPIL_ITER_CMP_1:%.*]] = icmp ne i32 [[EPIL_ITER_SUB_1]], 0
128 ; CHECK-NEXT:    br i1 [[EPIL_ITER_CMP_1]], label [[FOR_OUTER_EPIL_2:%.*]], label [[FOR_END_LOOPEXIT_EPILOG_LCSSA]]
129 ; CHECK:       for.outer.epil.2:
130 ; CHECK-NEXT:    br label [[FOR_INNER_EPIL_2:%.*]]
131 ; CHECK:       for.inner.epil.2:
132 ; CHECK-NEXT:    [[J_EPIL_2:%.*]] = phi i32 [ 0, [[FOR_OUTER_EPIL_2]] ], [ [[INC_EPIL_2:%.*]], [[FOR_INNER_EPIL_2]] ]
133 ; CHECK-NEXT:    [[SUM_EPIL_2:%.*]] = phi i32 [ 0, [[FOR_OUTER_EPIL_2]] ], [ [[ADD_EPIL_2:%.*]], [[FOR_INNER_EPIL_2]] ]
134 ; CHECK-NEXT:    [[ARRAYIDX_EPIL_2:%.*]] = getelementptr inbounds i32, i32* [[B]], i32 [[J_EPIL_2]]
135 ; CHECK-NEXT:    [[TMP8:%.*]] = load i32, i32* [[ARRAYIDX_EPIL_2]], align 4, !tbaa !0
136 ; CHECK-NEXT:    [[ADD_EPIL_2]] = add i32 [[TMP8]], [[SUM_EPIL_2]]
137 ; CHECK-NEXT:    [[INC_EPIL_2]] = add nuw i32 [[J_EPIL_2]], 1
138 ; CHECK-NEXT:    [[EXITCOND_EPIL_2:%.*]] = icmp eq i32 [[INC_EPIL_2]], [[J]]
139 ; CHECK-NEXT:    br i1 [[EXITCOND_EPIL_2]], label [[FOR_LATCH_EPIL_2:%.*]], label [[FOR_INNER_EPIL_2]]
140 ; CHECK:       for.latch.epil.2:
141 ; CHECK-NEXT:    [[ADD_LCSSA_EPIL_2:%.*]] = phi i32 [ [[ADD_EPIL_2]], [[FOR_INNER_EPIL_2]] ]
142 ; CHECK-NEXT:    [[ARRAYIDX6_EPIL_2:%.*]] = getelementptr inbounds i32, i32* [[A]], i32 [[ADD8_EPIL_1]]
143 ; CHECK-NEXT:    store i32 [[ADD_LCSSA_EPIL_2]], i32* [[ARRAYIDX6_EPIL_2]], align 4, !tbaa !0
144 ; CHECK-NEXT:    br label [[FOR_END_LOOPEXIT_EPILOG_LCSSA]]
145 define void @test1(i32 %I, i32 %J, i32* noalias nocapture %A, i32* noalias nocapture readonly %B) #0 {
146 entry:
147   %cmp = icmp ne i32 %J, 0
148   %cmpJ = icmp ne i32 %I, 0
149   %or.cond = and i1 %cmp, %cmpJ
150   br i1 %or.cond, label %for.outer.preheader, label %for.end
152 for.outer.preheader:
153   br label %for.outer
155 for.outer:
156   %i = phi i32 [ %add8, %for.latch ], [ 0, %for.outer.preheader ]
157   br label %for.inner
159 for.inner:
160   %j = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ]
161   %sum = phi i32 [ 0, %for.outer ], [ %add, %for.inner ]
162   %arrayidx = getelementptr inbounds i32, i32* %B, i32 %j
163   %0 = load i32, i32* %arrayidx, align 4, !tbaa !5
164   %add = add i32 %0, %sum
165   %inc = add nuw i32 %j, 1
166   %exitcond = icmp eq i32 %inc, %J
167   br i1 %exitcond, label %for.latch, label %for.inner
169 for.latch:
170   %add.lcssa = phi i32 [ %add, %for.inner ]
171   %arrayidx6 = getelementptr inbounds i32, i32* %A, i32 %i
172   store i32 %add.lcssa, i32* %arrayidx6, align 4, !tbaa !5
173   %add8 = add nuw i32 %i, 1
174   %exitcond25 = icmp eq i32 %add8, %I
175   br i1 %exitcond25, label %for.end.loopexit, label %for.outer
177 for.end.loopexit:
178   br label %for.end
180 for.end:
181   ret void
185 ; CHECK-LABEL: test2
186 ; Tests for(i) { sum = A[i]; for(j) sum += B[j]; A[i] = sum; }
187 ; A[i] load/store dependency should not block unroll-and-jam
188 ; CHECK: for.outer:
189 ; CHECK:   %i = phi i32 [ %add9.3, %for.latch ], [ 0, %for.outer.preheader.new ]
190 ; CHECK:   %niter = phi i32 [ %unroll_iter, %for.outer.preheader.new ], [ %niter.nsub.3, %for.latch ]
191 ; CHECK:   br label %for.inner
192 ; CHECK: for.inner:
193 ; CHECK:   %j = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ]
194 ; CHECK:   %sum = phi i32 [ %2, %for.outer ], [ %add, %for.inner ]
195 ; CHECK:   %j.1 = phi i32 [ 0, %for.outer ], [ %inc.1, %for.inner ]
196 ; CHECK:   %sum.1 = phi i32 [ %3, %for.outer ], [ %add.1, %for.inner ]
197 ; CHECK:   %j.2 = phi i32 [ 0, %for.outer ], [ %inc.2, %for.inner ]
198 ; CHECK:   %sum.2 = phi i32 [ %4, %for.outer ], [ %add.2, %for.inner ]
199 ; CHECK:   %j.3 = phi i32 [ 0, %for.outer ], [ %inc.3, %for.inner ]
200 ; CHECK:   %sum.3 = phi i32 [ %5, %for.outer ], [ %add.3, %for.inner ]
201 ; CHECK:   br i1 %exitcond.3, label %for.latch, label %for.inner
202 ; CHECK: for.latch:
203 ; CHECK:   %add.lcssa = phi i32 [ %add, %for.inner ]
204 ; CHECK:   %add.lcssa.1 = phi i32 [ %add.1, %for.inner ]
205 ; CHECK:   %add.lcssa.2 = phi i32 [ %add.2, %for.inner ]
206 ; CHECK:   %add.lcssa.3 = phi i32 [ %add.3, %for.inner ]
207 ; CHECK:   br i1 %niter.ncmp.3, label %for.end10.loopexit.unr-lcssa.loopexit, label %for.outer
208 ; CHECK: for.end10.loopexit.unr-lcssa.loopexit:
209 define void @test2(i32 %I, i32 %J, i32* noalias nocapture %A, i32* noalias nocapture readonly %B) #0 {
210 entry:
211   %cmp = icmp ne i32 %J, 0
212   %cmp125 = icmp ne i32 %I, 0
213   %or.cond = and i1 %cmp, %cmp125
214   br i1 %or.cond, label %for.outer.preheader, label %for.end10
216 for.outer.preheader:
217   br label %for.outer
219 for.outer:
220   %i = phi i32 [ %add9, %for.latch ], [ 0, %for.outer.preheader ]
221   %arrayidx = getelementptr inbounds i32, i32* %A, i32 %i
222   %0 = load i32, i32* %arrayidx, align 4, !tbaa !5
223   br label %for.inner
225 for.inner:
226   %j = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ]
227   %sum = phi i32 [ %0, %for.outer ], [ %add, %for.inner ]
228   %arrayidx6 = getelementptr inbounds i32, i32* %B, i32 %j
229   %1 = load i32, i32* %arrayidx6, align 4, !tbaa !5
230   %add = add i32 %1, %sum
231   %inc = add nuw i32 %j, 1
232   %exitcond = icmp eq i32 %inc, %J
233   br i1 %exitcond, label %for.latch, label %for.inner
235 for.latch:
236   %add.lcssa = phi i32 [ %add, %for.inner ]
237   store i32 %add.lcssa, i32* %arrayidx, align 4, !tbaa !5
238   %add9 = add nuw i32 %i, 1
239   %exitcond28 = icmp eq i32 %add9, %I
240   br i1 %exitcond28, label %for.end10.loopexit, label %for.outer
242 for.end10.loopexit:
243   br label %for.end10
245 for.end10:
246   ret void
250 ; CHECK-LABEL: test3
251 ; Tests Complete unroll-and-jam of the outer loop
252 ; CHECK: for.outer:
253 ; CHECK:   br label %for.inner
254 ; CHECK: for.inner:
255 ; CHECK:   %j = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ]
256 ; CHECK:   %sum = phi i32 [ 0, %for.outer ], [ %add, %for.inner ]
257 ; CHECK:   %j.1 = phi i32 [ 0, %for.outer ], [ %inc.1, %for.inner ]
258 ; CHECK:   %sum.1 = phi i32 [ 0, %for.outer ], [ %add.1, %for.inner ]
259 ; CHECK:   %j.2 = phi i32 [ 0, %for.outer ], [ %inc.2, %for.inner ]
260 ; CHECK:   %sum.2 = phi i32 [ 0, %for.outer ], [ %add.2, %for.inner ]
261 ; CHECK:   %j.3 = phi i32 [ 0, %for.outer ], [ %inc.3, %for.inner ]
262 ; CHECK:   %sum.3 = phi i32 [ 0, %for.outer ], [ %add.3, %for.inner ]
263 ; CHECK:   br i1 %exitcond.3, label %for.latch, label %for.inner
264 ; CHECK: for.latch:
265 ; CHECK:   %add.lcssa = phi i32 [ %add, %for.inner ]
266 ; CHECK:   %add.lcssa.1 = phi i32 [ %add.1, %for.inner ]
267 ; CHECK:   %add.lcssa.2 = phi i32 [ %add.2, %for.inner ]
268 ; CHECK:   %add.lcssa.3 = phi i32 [ %add.3, %for.inner ]
269 ; CHECK:   br label %for.end
270 ; CHECK: for.end:
271 define void @test3(i32 %I, i32 %J, i32* noalias nocapture %A, i32* noalias nocapture readonly %B) #0 {
272 entry:
273   %cmp = icmp eq i32 %J, 0
274   br i1 %cmp, label %for.end, label %for.preheader
276 for.preheader:
277   br label %for.outer
279 for.outer:
280   %i = phi i32 [ %add8, %for.latch ], [ 0, %for.preheader ]
281   br label %for.inner
283 for.inner:
284   %j = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ]
285   %sum = phi i32 [ 0, %for.outer ], [ %add, %for.inner ]
286   %arrayidx = getelementptr inbounds i32, i32* %B, i32 %j
287   %0 = load i32, i32* %arrayidx, align 4, !tbaa !5
288   %sub = add i32 %sum, 10
289   %add = sub i32 %sub, %0
290   %inc = add nuw i32 %j, 1
291   %exitcond = icmp eq i32 %inc, %J
292   br i1 %exitcond, label %for.latch, label %for.inner
294 for.latch:
295   %arrayidx6 = getelementptr inbounds i32, i32* %A, i32 %i
296   store i32 %add, i32* %arrayidx6, align 4, !tbaa !5
297   %add8 = add nuw nsw i32 %i, 1
298   %exitcond23 = icmp eq i32 %add8, 4
299   br i1 %exitcond23, label %for.end, label %for.outer
301 for.end:
302   ret void
306 ; CHECK-LABEL: test4
307 ; Tests Complete unroll-and-jam with a trip count of 1
308 ; CHECK: for.outer:
309 ; CHECK:   br label %for.inner
310 ; CHECK: for.inner:
311 ; CHECK:   %j = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ]
312 ; CHECK:   %sum = phi i32 [ 0, %for.outer ], [ %add, %for.inner ]
313 ; CHECK:   br i1 %exitcond, label %for.latch, label %for.inner
314 ; CHECK: for.latch:
315 ; CHECK:   %add.lcssa = phi i32 [ %add, %for.inner ]
316 ; CHECK:   br label %for.end
317 ; CHECK: for.end:
318 define void @test4(i32 %I, i32 %J, i32* noalias nocapture %A, i32* noalias nocapture readonly %B) #0 {
319 entry:
320   %cmp = icmp eq i32 %J, 0
321   br i1 %cmp, label %for.end, label %for.preheader
323 for.preheader:
324   br label %for.outer
326 for.outer:
327   %i = phi i32 [ %add8, %for.latch ], [ 0, %for.preheader ]
328   br label %for.inner
330 for.inner:
331   %j = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ]
332   %sum = phi i32 [ 0, %for.outer ], [ %add, %for.inner ]
333   %arrayidx = getelementptr inbounds i32, i32* %B, i32 %j
334   %0 = load i32, i32* %arrayidx, align 4, !tbaa !5
335   %sub = add i32 %sum, 10
336   %add = sub i32 %sub, %0
337   %inc = add nuw i32 %j, 1
338   %exitcond = icmp eq i32 %inc, %J
339   br i1 %exitcond, label %for.latch, label %for.inner
341 for.latch:
342   %arrayidx6 = getelementptr inbounds i32, i32* %A, i32 %i
343   store i32 %add, i32* %arrayidx6, align 4, !tbaa !5
344   %add8 = add nuw nsw i32 %i, 1
345   %exitcond23 = icmp eq i32 %add8, 1
346   br i1 %exitcond23, label %for.end, label %for.outer
348 for.end:
349   ret void
353 ; CHECK-LABEL: test5
354 ; Multiple SubLoopBlocks
355 ; CHECK: for.outer:
356 ; CHECK:   br label %for.inner
357 ; CHECK: for.inner:
358 ; CHECK:   %inc8.sink15 = phi i32 [ 0, %for.outer ], [ %inc8, %for.inc.1 ]
359 ; CHECK:   %inc8.sink15.1 = phi i32 [ 0, %for.outer ], [ %inc8.1, %for.inc.1 ]
360 ; CHECK:   br label %for.inner2
361 ; CHECK: for.inner2:
362 ; CHECK:   br i1 %tobool, label %for.cond4, label %for.inc
363 ; CHECK: for.cond4:
364 ; CHECK:   br i1 %tobool.1, label %for.cond4a, label %for.inc
365 ; CHECK: for.cond4a:
366 ; CHECK:   br label %for.inc
367 ; CHECK: for.inc:
368 ; CHECK:   br i1 %tobool.11, label %for.cond4.1, label %for.inc.1
369 ; CHECK: for.latch:
370 ; CHECK:   br label %for.end
371 ; CHECK: for.end:
372 ; CHECK:   ret i32 0
373 ; CHECK: for.cond4.1:
374 ; CHECK:   br i1 %tobool.1.1, label %for.cond4a.1, label %for.inc.1
375 ; CHECK: for.cond4a.1:
376 ; CHECK:   br label %for.inc.1
377 ; CHECK: for.inc.1:
378 ; CHECK:   br i1 %exitcond.1, label %for.latch, label %for.inner
379 @a = hidden global [1 x i32] zeroinitializer, align 4
380 define i32 @test5() #0 {
381 entry:
382   br label %for.outer
384 for.outer:
385   %.sink16 = phi i32 [ 0, %entry ], [ %add, %for.latch ]
386   br label %for.inner
388 for.inner:
389   %inc8.sink15 = phi i32 [ 0, %for.outer ], [ %inc8, %for.inc ]
390   br label %for.inner2
392 for.inner2:
393   %l1 = load i32, i32* getelementptr inbounds ([1 x i32], [1 x i32]* @a, i32 0, i32 0), align 4
394   %tobool = icmp eq i32 %l1, 0
395   br i1 %tobool, label %for.cond4, label %for.inc
397 for.cond4:
398   %l0 = load i32, i32* getelementptr inbounds ([1 x i32], [1 x i32]* @a, i32 1, i32 0), align 4
399   %tobool.1 = icmp eq i32 %l0, 0
400   br i1 %tobool.1, label %for.cond4a, label %for.inc
402 for.cond4a:
403   br label %for.inc
405 for.inc:
406   %l2 = phi i32 [ 0, %for.inner2 ], [ 1, %for.cond4 ], [ 2, %for.cond4a ]
407   %inc8 = add nuw nsw i32 %inc8.sink15, 1
408   %exitcond = icmp eq i32 %inc8, 3
409   br i1 %exitcond, label %for.latch, label %for.inner
411 for.latch:
412   %.lcssa = phi i32 [ %l2, %for.inc ]
413   %conv11 = and i32 %.sink16, 255
414   %add = add nuw nsw i32 %conv11, 4
415   %cmp = icmp eq i32 %add, 8
416   br i1 %cmp, label %for.end, label %for.outer
418 for.end:
419   %.lcssa.lcssa = phi i32 [ %.lcssa, %for.latch ]
420   ret i32 0
424 ; CHECK-LABEL: test6
425 ; Test odd uses of phi nodes
426 ; CHECK: for.outer:
427 ; CHECK:   br label %for.inner
428 ; CHECK: for.inner:
429 ; CHECK:   br i1 %exitcond.3, label %for.inner, label %for.latch
430 ; CHECK: for.latch:
431 ; CHECK:   br label %for.end
432 ; CHECK: for.end:
433 ; CHECK:   ret i32 0
434 @f = hidden global i32 0, align 4
435 define i32 @test6() #0 {
436 entry:
437   %f.promoted10 = load i32, i32* @f, align 4, !tbaa !5
438   br label %for.outer
440 for.outer:
441   %p0 = phi i32 [ %f.promoted10, %entry ], [ 2, %for.latch ]
442   %inc5.sink9 = phi i32 [ 2, %entry ], [ %inc5, %for.latch ]
443   br label %for.inner
445 for.inner:
446   %p1 = phi i32 [ %p0, %for.outer ], [ 2, %for.inner ]
447   %inc.sink8 = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ]
448   %inc = add nuw nsw i32 %inc.sink8, 1
449   %exitcond = icmp ne i32 %inc, 7
450   br i1 %exitcond, label %for.inner, label %for.latch
452 for.latch:
453   %.lcssa = phi i32 [ %p1, %for.inner ]
454   %inc5 = add nuw nsw i32 %inc5.sink9, 1
455   %exitcond11 = icmp ne i32 %inc5, 7
456   br i1 %exitcond11, label %for.outer, label %for.end
458 for.end:
459   %.lcssa.lcssa = phi i32 [ %.lcssa, %for.latch ]
460   %inc.lcssa.lcssa = phi i32 [ 7, %for.latch ]
461   ret i32 0
465 ; CHECK-LABEL: test7
466 ; Has a positive dependency between two stores. Still valid.
467 ; The negative dependecy is in unroll-and-jam-disabled.ll
468 ; CHECK: for.outer:
469 ; CHECK:   %i = phi i32 [ %add.3, %for.latch ], [ 0, %for.preheader.new ]
470 ; CHECK:   %niter = phi i32 [ %unroll_iter, %for.preheader.new ], [ %niter.nsub.3, %for.latch ]
471 ; CHECK:   br label %for.inner
472 ; CHECK: for.latch:
473 ; CHECK:   %add9.lcssa = phi i32 [ %add9, %for.inner ]
474 ; CHECK:   %add9.lcssa.1 = phi i32 [ %add9.1, %for.inner ]
475 ; CHECK:   %add9.lcssa.2 = phi i32 [ %add9.2, %for.inner ]
476 ; CHECK:   %add9.lcssa.3 = phi i32 [ %add9.3, %for.inner ]
477 ; CHECK:   br i1 %niter.ncmp.3, label %for.end.loopexit.unr-lcssa.loopexit, label %for.outer
478 ; CHECK: for.inner:
479 ; CHECK:   %sum = phi i32 [ 0, %for.outer ], [ %add9, %for.inner ]
480 ; CHECK:   %j = phi i32 [ 0, %for.outer ], [ %add10, %for.inner ]
481 ; CHECK:   %sum.1 = phi i32 [ 0, %for.outer ], [ %add9.1, %for.inner ]
482 ; CHECK:   %j.1 = phi i32 [ 0, %for.outer ], [ %add10.1, %for.inner ]
483 ; CHECK:   %sum.2 = phi i32 [ 0, %for.outer ], [ %add9.2, %for.inner ]
484 ; CHECK:   %j.2 = phi i32 [ 0, %for.outer ], [ %add10.2, %for.inner ]
485 ; CHECK:   %sum.3 = phi i32 [ 0, %for.outer ], [ %add9.3, %for.inner ]
486 ; CHECK:   %j.3 = phi i32 [ 0, %for.outer ], [ %add10.3, %for.inner ]
487 ; CHECK:   br i1 %exitcond.3, label %for.latch, label %for.inner
488 ; CHECK: for.end.loopexit.unr-lcssa.loopexit:
489 define void @test7(i32 %I, i32 %J, i32* noalias nocapture %A, i32* noalias nocapture readonly %B) #0 {
490 entry:
491   %cmp = icmp ne i32 %J, 0
492   %cmp128 = icmp ne i32 %I, 0
493   %or.cond = and i1 %cmp128, %cmp
494   br i1 %or.cond, label %for.preheader, label %for.end
496 for.preheader:
497   br label %for.outer
499 for.outer:
500   %i = phi i32 [ %add, %for.latch ], [ 0, %for.preheader ]
501   %arrayidx = getelementptr inbounds i32, i32* %A, i32 %i
502   store i32 0, i32* %arrayidx, align 4, !tbaa !5
503   %add = add nuw i32 %i, 1
504   %arrayidx2 = getelementptr inbounds i32, i32* %A, i32 %add
505   store i32 2, i32* %arrayidx2, align 4, !tbaa !5
506   br label %for.inner
508 for.latch:
509   store i32 %add9, i32* %arrayidx, align 4, !tbaa !5
510   %exitcond30 = icmp eq i32 %add, %I
511   br i1 %exitcond30, label %for.end, label %for.outer
513 for.inner:
514   %sum = phi i32 [ 0, %for.outer ], [ %add9, %for.inner ]
515   %j = phi i32 [ 0, %for.outer ], [ %add10, %for.inner ]
516   %arrayidx7 = getelementptr inbounds i32, i32* %B, i32 %j
517   %l1 = load i32, i32* %arrayidx7, align 4, !tbaa !5
518   %add9 = add i32 %l1, %sum
519   %add10 = add nuw i32 %j, 1
520   %exitcond = icmp eq i32 %add10, %J
521   br i1 %exitcond, label %for.latch, label %for.inner
523 for.end:
524   ret void
528 ; CHECK-LABEL: test8
529 ; Same as test7 with an extra outer loop nest
530 ; CHECK: for.outest:
531 ; CHECK:   br label %for.outer
532 ; CHECK: for.outer:
533 ; CHECK:   %i = phi i32 [ %add.3, %for.latch ], [ 0, %for.outest.new ]
534 ; CHECK:   %niter = phi i32 [ %unroll_iter, %for.outest.new ], [ %niter.nsub.3, %for.latch ]
535 ; CHECK:   br label %for.inner
536 ; CHECK: for.inner:
537 ; CHECK:   %sum = phi i32 [ 0, %for.outer ], [ %add9, %for.inner ]
538 ; CHECK:   %j = phi i32 [ 0, %for.outer ], [ %add10, %for.inner ]
539 ; CHECK:   %sum.1 = phi i32 [ 0, %for.outer ], [ %add9.1, %for.inner ]
540 ; CHECK:   %j.1 = phi i32 [ 0, %for.outer ], [ %add10.1, %for.inner ]
541 ; CHECK:   %sum.2 = phi i32 [ 0, %for.outer ], [ %add9.2, %for.inner ]
542 ; CHECK:   %j.2 = phi i32 [ 0, %for.outer ], [ %add10.2, %for.inner ]
543 ; CHECK:   %sum.3 = phi i32 [ 0, %for.outer ], [ %add9.3, %for.inner ]
544 ; CHECK:   %j.3 = phi i32 [ 0, %for.outer ], [ %add10.3, %for.inner ]
545 ; CHECK:   br i1 %exitcond.3, label %for.latch, label %for.inner
546 ; CHECK: for.latch:
547 ; CHECK:   %add9.lcssa = phi i32 [ %add9, %for.inner ]
548 ; CHECK:   %add9.lcssa.1 = phi i32 [ %add9.1, %for.inner ]
549 ; CHECK:   %add9.lcssa.2 = phi i32 [ %add9.2, %for.inner ]
550 ; CHECK:   %add9.lcssa.3 = phi i32 [ %add9.3, %for.inner ]
551 ; CHECK:   br i1 %niter.ncmp.3, label %for.cleanup.unr-lcssa.loopexit, label %for.outer
552 ; CHECK: for.cleanup.epilog-lcssa:
553 ; CHECK:   br label %for.cleanup
554 ; CHECK: for.cleanup:
555 ; CHECK:   br i1 %exitcond41, label %for.end.loopexit, label %for.outest
556 ; CHECK: for.end.loopexit:
557 ; CHECK:   br label %for.end
558 define void @test8(i32 %I, i32 %J, i32* noalias nocapture %A, i32* noalias nocapture readonly %B) #0 {
559 entry:
560   %cmp = icmp eq i32 %J, 0
561   %cmp336 = icmp eq i32 %I, 0
562   %or.cond = or i1 %cmp, %cmp336
563   br i1 %or.cond, label %for.end, label %for.preheader
565 for.preheader:
566   br label %for.outest
568 for.outest:
569   %x.038 = phi i32 [ %inc, %for.cleanup ], [ 0, %for.preheader ]
570   br label %for.outer
572 for.outer:
573   %i = phi i32 [ %add, %for.latch ], [ 0, %for.outest ]
574   %arrayidx = getelementptr inbounds i32, i32* %A, i32 %i
575   store i32 0, i32* %arrayidx, align 4, !tbaa !5
576   %add = add nuw i32 %i, 1
577   %arrayidx6 = getelementptr inbounds i32, i32* %A, i32 %add
578   store i32 2, i32* %arrayidx6, align 4, !tbaa !5
579   br label %for.inner
581 for.inner:
582   %sum = phi i32 [ 0, %for.outer ], [ %add9, %for.inner ]
583   %j = phi i32 [ 0, %for.outer ], [ %add10, %for.inner ]
584   %arrayidx11 = getelementptr inbounds i32, i32* %B, i32 %j
585   %l1 = load i32, i32* %arrayidx11, align 4, !tbaa !5
586   %add9 = add i32 %l1, %sum
587   %add10 = add nuw i32 %j, 1
588   %exitcond = icmp eq i32 %add10, %J
589   br i1 %exitcond, label %for.latch, label %for.inner
591 for.latch:
592   store i32 %add9, i32* %arrayidx, align 4, !tbaa !5
593   %exitcond39 = icmp eq i32 %add, %I
594   br i1 %exitcond39, label %for.cleanup, label %for.outer
596 for.cleanup:
597   %inc = add nuw nsw i32 %x.038, 1
598   %exitcond41 = icmp eq i32 %inc, 5
599   br i1 %exitcond41, label %for.end, label %for.outest
601 for.end:
602   ret void
606 ; CHECK-LABEL: test9
607 ; Same as test1 with tbaa, not noalias
608 ; CHECK: for.outer:
609 ; CHECK:   %i = phi i32 [ %add8.3, %for.latch ], [ 0, %for.outer.preheader.new ]
610 ; CHECK:   %niter = phi i32 [ %unroll_iter, %for.outer.preheader.new ], [ %niter.nsub.3, %for.latch ]
611 ; CHECK:   br label %for.inner
612 ; CHECK: for.inner:
613 ; CHECK:   %j = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ]
614 ; CHECK:   %sum = phi i32 [ 0, %for.outer ], [ %add, %for.inner ]
615 ; CHECK:   %j.1 = phi i32 [ 0, %for.outer ], [ %inc.1, %for.inner ]
616 ; CHECK:   %sum.1 = phi i32 [ 0, %for.outer ], [ %add.1, %for.inner ]
617 ; CHECK:   %j.2 = phi i32 [ 0, %for.outer ], [ %inc.2, %for.inner ]
618 ; CHECK:   %sum.2 = phi i32 [ 0, %for.outer ], [ %add.2, %for.inner ]
619 ; CHECK:   %j.3 = phi i32 [ 0, %for.outer ], [ %inc.3, %for.inner ]
620 ; CHECK:   %sum.3 = phi i32 [ 0, %for.outer ], [ %add.3, %for.inner ]
621 ; CHECK:   br i1 %exitcond.3, label %for.latch, label %for.inner
622 ; CHECK: for.latch:
623 ; CHECK:   %add.lcssa = phi i32 [ %add, %for.inner ]
624 ; CHECK:   %add.lcssa.1 = phi i32 [ %add.1, %for.inner ]
625 ; CHECK:   %add.lcssa.2 = phi i32 [ %add.2, %for.inner ]
626 ; CHECK:   %add.lcssa.3 = phi i32 [ %add.3, %for.inner ]
627 ; CHECK:   br i1 %niter.ncmp.3, label %for.end.loopexit.unr-lcssa.loopexit, label %for.outer
628 ; CHECK: for.end.loopexit.unr-lcssa.loopexit:
629 define void @test9(i32 %I, i32 %J, i32* nocapture %A, i16* nocapture readonly %B) #0 {
630 entry:
631   %cmp = icmp ne i32 %J, 0
632   %cmpJ = icmp ne i32 %I, 0
633   %or.cond = and i1 %cmp, %cmpJ
634   br i1 %or.cond, label %for.outer.preheader, label %for.end
636 for.outer.preheader:
637   br label %for.outer
639 for.outer:
640   %i = phi i32 [ %add8, %for.latch ], [ 0, %for.outer.preheader ]
641   br label %for.inner
643 for.inner:
644   %j = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ]
645   %sum = phi i32 [ 0, %for.outer ], [ %add, %for.inner ]
646   %arrayidx = getelementptr inbounds i16, i16* %B, i32 %j
647   %0 = load i16, i16* %arrayidx, align 4, !tbaa !9
648   %sext = sext i16 %0 to i32
649   %add = add i32 %sext, %sum
650   %inc = add nuw i32 %j, 1
651   %exitcond = icmp eq i32 %inc, %J
652   br i1 %exitcond, label %for.latch, label %for.inner
654 for.latch:
655   %add.lcssa = phi i32 [ %add, %for.inner ]
656   %arrayidx6 = getelementptr inbounds i32, i32* %A, i32 %i
657   store i32 %add.lcssa, i32* %arrayidx6, align 4, !tbaa !5
658   %add8 = add nuw i32 %i, 1
659   %exitcond25 = icmp eq i32 %add8, %I
660   br i1 %exitcond25, label %for.end.loopexit, label %for.outer
662 for.end.loopexit:
663   br label %for.end
665 for.end:
666   ret void
670 ; CHECK-LABEL: test10
671 ; Be careful not to incorrectly update the exit phi nodes
672 ; CHECK: %dec.lcssa.lcssa.ph.ph = phi i64 [ 0, %for.inc24 ]
673 %struct.a = type { i64 }
674 @g = common global %struct.a zeroinitializer, align 8
675 @c = common global [1 x i8] zeroinitializer, align 1
676 define signext i16 @test10(i32 %k) #0 {
677 entry:
678   %0 = load i8, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @c, i64 0, i64 0), align 1
679   %tobool9 = icmp eq i8 %0, 0
680   %tobool13 = icmp ne i32 %k, 0
681   br label %for.body
683 for.body:
684   %storemerge82 = phi i64 [ 0, %entry ], [ %inc25, %for.inc24 ]
685   br label %for.body2
687 for.body2:
688   %storemerge = phi i64 [ 4, %for.body ], [ %dec, %for.inc21 ]
689   br i1 %tobool9, label %for.body2.split, label %for.body2.split2
691 for.body2.split2:
692   br i1 %tobool13, label %for.inc21, label %for.inc21.if
694 for.body2.split:
695   br i1 %tobool13, label %for.inc21, label %for.inc21.then
697 for.inc21.if:
698   %storemerge.1 = phi i64 [ 0, %for.body2.split2 ]
699   br label %for.inc21
701 for.inc21.then:
702   %storemerge.2 = phi i64 [ 0, %for.body2.split ]
703   %storemerge.3 = phi i32 [ 0, %for.body2.split ]
704   br label %for.inc21
706 for.inc21:
707   %storemerge.4 = phi i64 [ %storemerge.1, %for.inc21.if ], [ %storemerge.2, %for.inc21.then ], [ 4, %for.body2.split2 ], [ 4, %for.body2.split ]
708   %storemerge.5 = phi i32 [ 0, %for.inc21.if ], [ %storemerge.3, %for.inc21.then ], [ 0, %for.body2.split2 ], [ 0, %for.body2.split ]
709   %dec = add nsw i64 %storemerge, -1
710   %tobool = icmp eq i64 %dec, 0
711   br i1 %tobool, label %for.inc24, label %for.body2
713 for.inc24:
714   %storemerge.4.lcssa = phi i64 [ %storemerge.4, %for.inc21 ]
715   %storemerge.5.lcssa = phi i32 [ %storemerge.5, %for.inc21 ]
716   %inc25 = add nuw nsw i64 %storemerge82, 1
717   %exitcond = icmp ne i64 %inc25, 5
718   br i1 %exitcond, label %for.body, label %for.end26
720 for.end26:
721   %dec.lcssa.lcssa = phi i64 [ 0, %for.inc24 ]
722   %storemerge.4.lcssa.lcssa = phi i64 [ %storemerge.4.lcssa, %for.inc24 ]
723   %storemerge.5.lcssa.lcssa = phi i32 [ %storemerge.5.lcssa, %for.inc24 ]
724   store i64 %dec.lcssa.lcssa, i64* getelementptr inbounds (%struct.a, %struct.a* @g, i64 0, i32 0), align 8
725   ret i16 0
729 !5 = !{!6, !6, i64 0}
730 !6 = !{!"int", !7, i64 0}
731 !7 = !{!"omnipotent char", !8, i64 0}
732 !8 = !{!"Simple C/C++ TBAA"}
733 !9 = !{!10, !10, i64 0}
734 !10 = !{!"short", !7, i64 0}