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
4
5target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
6
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:    [[ADD8_EPIL_2:%.*]] = add nuw i32 [[ADD8_EPIL_1]], 1
145; CHECK-NEXT:    [[EPIL_ITER_SUB_2:%.*]] = sub i32 [[EPIL_ITER_SUB_1]], 1
146; CHECK-NEXT:    br label [[FOR_END_LOOPEXIT_EPILOG_LCSSA]]
147define void @test1(i32 %I, i32 %J, i32* noalias nocapture %A, i32* noalias nocapture readonly %B) #0 {
148entry:
149  %cmp = icmp ne i32 %J, 0
150  %cmpJ = icmp ne i32 %I, 0
151  %or.cond = and i1 %cmp, %cmpJ
152  br i1 %or.cond, label %for.outer.preheader, label %for.end
153
154for.outer.preheader:
155  br label %for.outer
156
157for.outer:
158  %i = phi i32 [ %add8, %for.latch ], [ 0, %for.outer.preheader ]
159  br label %for.inner
160
161for.inner:
162  %j = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ]
163  %sum = phi i32 [ 0, %for.outer ], [ %add, %for.inner ]
164  %arrayidx = getelementptr inbounds i32, i32* %B, i32 %j
165  %0 = load i32, i32* %arrayidx, align 4, !tbaa !5
166  %add = add i32 %0, %sum
167  %inc = add nuw i32 %j, 1
168  %exitcond = icmp eq i32 %inc, %J
169  br i1 %exitcond, label %for.latch, label %for.inner
170
171for.latch:
172  %add.lcssa = phi i32 [ %add, %for.inner ]
173  %arrayidx6 = getelementptr inbounds i32, i32* %A, i32 %i
174  store i32 %add.lcssa, i32* %arrayidx6, align 4, !tbaa !5
175  %add8 = add nuw i32 %i, 1
176  %exitcond25 = icmp eq i32 %add8, %I
177  br i1 %exitcond25, label %for.end.loopexit, label %for.outer
178
179for.end.loopexit:
180  br label %for.end
181
182for.end:
183  ret void
184}
185
186
187; CHECK-LABEL: test2
188; Tests for(i) { sum = A[i]; for(j) sum += B[j]; A[i] = sum; }
189; A[i] load/store dependency should not block unroll-and-jam
190; CHECK: for.outer:
191; CHECK:   %i = phi i32 [ %add9.3, %for.latch ], [ 0, %for.outer.preheader.new ]
192; CHECK:   %niter = phi i32 [ %unroll_iter, %for.outer.preheader.new ], [ %niter.nsub.3, %for.latch ]
193; CHECK:   br label %for.inner
194; CHECK: for.inner:
195; CHECK:   %j = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ]
196; CHECK:   %sum = phi i32 [ %2, %for.outer ], [ %add, %for.inner ]
197; CHECK:   %j.1 = phi i32 [ 0, %for.outer ], [ %inc.1, %for.inner ]
198; CHECK:   %sum.1 = phi i32 [ %3, %for.outer ], [ %add.1, %for.inner ]
199; CHECK:   %j.2 = phi i32 [ 0, %for.outer ], [ %inc.2, %for.inner ]
200; CHECK:   %sum.2 = phi i32 [ %4, %for.outer ], [ %add.2, %for.inner ]
201; CHECK:   %j.3 = phi i32 [ 0, %for.outer ], [ %inc.3, %for.inner ]
202; CHECK:   %sum.3 = phi i32 [ %5, %for.outer ], [ %add.3, %for.inner ]
203; CHECK:   br i1 %exitcond.3, label %for.latch, label %for.inner
204; CHECK: for.latch:
205; CHECK:   %add.lcssa = phi i32 [ %add, %for.inner ]
206; CHECK:   %add.lcssa.1 = phi i32 [ %add.1, %for.inner ]
207; CHECK:   %add.lcssa.2 = phi i32 [ %add.2, %for.inner ]
208; CHECK:   %add.lcssa.3 = phi i32 [ %add.3, %for.inner ]
209; CHECK:   br i1 %niter.ncmp.3, label %for.end10.loopexit.unr-lcssa.loopexit, label %for.outer
210; CHECK: for.end10.loopexit.unr-lcssa.loopexit:
211define void @test2(i32 %I, i32 %J, i32* noalias nocapture %A, i32* noalias nocapture readonly %B) #0 {
212entry:
213  %cmp = icmp ne i32 %J, 0
214  %cmp125 = icmp ne i32 %I, 0
215  %or.cond = and i1 %cmp, %cmp125
216  br i1 %or.cond, label %for.outer.preheader, label %for.end10
217
218for.outer.preheader:
219  br label %for.outer
220
221for.outer:
222  %i = phi i32 [ %add9, %for.latch ], [ 0, %for.outer.preheader ]
223  %arrayidx = getelementptr inbounds i32, i32* %A, i32 %i
224  %0 = load i32, i32* %arrayidx, align 4, !tbaa !5
225  br label %for.inner
226
227for.inner:
228  %j = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ]
229  %sum = phi i32 [ %0, %for.outer ], [ %add, %for.inner ]
230  %arrayidx6 = getelementptr inbounds i32, i32* %B, i32 %j
231  %1 = load i32, i32* %arrayidx6, align 4, !tbaa !5
232  %add = add i32 %1, %sum
233  %inc = add nuw i32 %j, 1
234  %exitcond = icmp eq i32 %inc, %J
235  br i1 %exitcond, label %for.latch, label %for.inner
236
237for.latch:
238  %add.lcssa = phi i32 [ %add, %for.inner ]
239  store i32 %add.lcssa, i32* %arrayidx, align 4, !tbaa !5
240  %add9 = add nuw i32 %i, 1
241  %exitcond28 = icmp eq i32 %add9, %I
242  br i1 %exitcond28, label %for.end10.loopexit, label %for.outer
243
244for.end10.loopexit:
245  br label %for.end10
246
247for.end10:
248  ret void
249}
250
251
252; CHECK-LABEL: test3
253; Tests Complete unroll-and-jam of the outer loop
254; CHECK: for.outer:
255; CHECK:   br label %for.inner
256; CHECK: for.inner:
257; CHECK:   %j = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ]
258; CHECK:   %sum = phi i32 [ 0, %for.outer ], [ %add, %for.inner ]
259; CHECK:   %j.1 = phi i32 [ 0, %for.outer ], [ %inc.1, %for.inner ]
260; CHECK:   %sum.1 = phi i32 [ 0, %for.outer ], [ %add.1, %for.inner ]
261; CHECK:   %j.2 = phi i32 [ 0, %for.outer ], [ %inc.2, %for.inner ]
262; CHECK:   %sum.2 = phi i32 [ 0, %for.outer ], [ %add.2, %for.inner ]
263; CHECK:   %j.3 = phi i32 [ 0, %for.outer ], [ %inc.3, %for.inner ]
264; CHECK:   %sum.3 = phi i32 [ 0, %for.outer ], [ %add.3, %for.inner ]
265; CHECK:   br i1 %exitcond.3, label %for.latch, label %for.inner
266; CHECK: for.latch:
267; CHECK:   %add.lcssa = phi i32 [ %add, %for.inner ]
268; CHECK:   %add.lcssa.1 = phi i32 [ %add.1, %for.inner ]
269; CHECK:   %add.lcssa.2 = phi i32 [ %add.2, %for.inner ]
270; CHECK:   %add.lcssa.3 = phi i32 [ %add.3, %for.inner ]
271; CHECK:   br label %for.end
272; CHECK: for.end:
273define void @test3(i32 %I, i32 %J, i32* noalias nocapture %A, i32* noalias nocapture readonly %B) #0 {
274entry:
275  %cmp = icmp eq i32 %J, 0
276  br i1 %cmp, label %for.end, label %for.preheader
277
278for.preheader:
279  br label %for.outer
280
281for.outer:
282  %i = phi i32 [ %add8, %for.latch ], [ 0, %for.preheader ]
283  br label %for.inner
284
285for.inner:
286  %j = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ]
287  %sum = phi i32 [ 0, %for.outer ], [ %add, %for.inner ]
288  %arrayidx = getelementptr inbounds i32, i32* %B, i32 %j
289  %0 = load i32, i32* %arrayidx, align 4, !tbaa !5
290  %sub = add i32 %sum, 10
291  %add = sub i32 %sub, %0
292  %inc = add nuw i32 %j, 1
293  %exitcond = icmp eq i32 %inc, %J
294  br i1 %exitcond, label %for.latch, label %for.inner
295
296for.latch:
297  %arrayidx6 = getelementptr inbounds i32, i32* %A, i32 %i
298  store i32 %add, i32* %arrayidx6, align 4, !tbaa !5
299  %add8 = add nuw nsw i32 %i, 1
300  %exitcond23 = icmp eq i32 %add8, 4
301  br i1 %exitcond23, label %for.end, label %for.outer
302
303for.end:
304  ret void
305}
306
307
308; CHECK-LABEL: test4
309; Tests Complete unroll-and-jam with a trip count of 1
310; CHECK: for.outer:
311; CHECK:   br label %for.inner
312; CHECK: for.inner:
313; CHECK:   %j = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ]
314; CHECK:   %sum = phi i32 [ 0, %for.outer ], [ %add, %for.inner ]
315; CHECK:   br i1 %exitcond, label %for.latch, label %for.inner
316; CHECK: for.latch:
317; CHECK:   %add.lcssa = phi i32 [ %add, %for.inner ]
318; CHECK:   br label %for.end
319; CHECK: for.end:
320define void @test4(i32 %I, i32 %J, i32* noalias nocapture %A, i32* noalias nocapture readonly %B) #0 {
321entry:
322  %cmp = icmp eq i32 %J, 0
323  br i1 %cmp, label %for.end, label %for.preheader
324
325for.preheader:
326  br label %for.outer
327
328for.outer:
329  %i = phi i32 [ %add8, %for.latch ], [ 0, %for.preheader ]
330  br label %for.inner
331
332for.inner:
333  %j = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ]
334  %sum = phi i32 [ 0, %for.outer ], [ %add, %for.inner ]
335  %arrayidx = getelementptr inbounds i32, i32* %B, i32 %j
336  %0 = load i32, i32* %arrayidx, align 4, !tbaa !5
337  %sub = add i32 %sum, 10
338  %add = sub i32 %sub, %0
339  %inc = add nuw i32 %j, 1
340  %exitcond = icmp eq i32 %inc, %J
341  br i1 %exitcond, label %for.latch, label %for.inner
342
343for.latch:
344  %arrayidx6 = getelementptr inbounds i32, i32* %A, i32 %i
345  store i32 %add, i32* %arrayidx6, align 4, !tbaa !5
346  %add8 = add nuw nsw i32 %i, 1
347  %exitcond23 = icmp eq i32 %add8, 1
348  br i1 %exitcond23, label %for.end, label %for.outer
349
350for.end:
351  ret void
352}
353
354
355; CHECK-LABEL: test5
356; Multiple SubLoopBlocks
357; CHECK: for.outer:
358; CHECK:   br label %for.inner
359; CHECK: for.inner:
360; CHECK:   %inc8.sink15 = phi i32 [ 0, %for.outer ], [ %inc8, %for.inc.1 ]
361; CHECK:   %inc8.sink15.1 = phi i32 [ 0, %for.outer ], [ %inc8.1, %for.inc.1 ]
362; CHECK:   br label %for.inner2
363; CHECK: for.inner2:
364; CHECK:   br i1 %tobool, label %for.cond4, label %for.inc
365; CHECK: for.cond4:
366; CHECK:   br i1 %tobool.1, label %for.cond4a, label %for.inc
367; CHECK: for.cond4a:
368; CHECK:   br label %for.inc
369; CHECK: for.inc:
370; CHECK:   br i1 %tobool.11, label %for.cond4.1, label %for.inc.1
371; CHECK: for.latch:
372; CHECK:   br label %for.end
373; CHECK: for.end:
374; CHECK:   ret i32 0
375; CHECK: for.cond4.1:
376; CHECK:   br i1 %tobool.1.1, label %for.cond4a.1, label %for.inc.1
377; CHECK: for.cond4a.1:
378; CHECK:   br label %for.inc.1
379; CHECK: for.inc.1:
380; CHECK:   br i1 %exitcond.1, label %for.latch, label %for.inner
381@a = hidden global [1 x i32] zeroinitializer, align 4
382define i32 @test5() #0 {
383entry:
384  br label %for.outer
385
386for.outer:
387  %.sink16 = phi i32 [ 0, %entry ], [ %add, %for.latch ]
388  br label %for.inner
389
390for.inner:
391  %inc8.sink15 = phi i32 [ 0, %for.outer ], [ %inc8, %for.inc ]
392  br label %for.inner2
393
394for.inner2:
395  %l1 = load i32, i32* getelementptr inbounds ([1 x i32], [1 x i32]* @a, i32 0, i32 0), align 4
396  %tobool = icmp eq i32 %l1, 0
397  br i1 %tobool, label %for.cond4, label %for.inc
398
399for.cond4:
400  %l0 = load i32, i32* getelementptr inbounds ([1 x i32], [1 x i32]* @a, i32 1, i32 0), align 4
401  %tobool.1 = icmp eq i32 %l0, 0
402  br i1 %tobool.1, label %for.cond4a, label %for.inc
403
404for.cond4a:
405  br label %for.inc
406
407for.inc:
408  %l2 = phi i32 [ 0, %for.inner2 ], [ 1, %for.cond4 ], [ 2, %for.cond4a ]
409  %inc8 = add nuw nsw i32 %inc8.sink15, 1
410  %exitcond = icmp eq i32 %inc8, 3
411  br i1 %exitcond, label %for.latch, label %for.inner
412
413for.latch:
414  %.lcssa = phi i32 [ %l2, %for.inc ]
415  %conv11 = and i32 %.sink16, 255
416  %add = add nuw nsw i32 %conv11, 4
417  %cmp = icmp eq i32 %add, 8
418  br i1 %cmp, label %for.end, label %for.outer
419
420for.end:
421  %.lcssa.lcssa = phi i32 [ %.lcssa, %for.latch ]
422  ret i32 0
423}
424
425
426; CHECK-LABEL: test6
427; Test odd uses of phi nodes
428; CHECK: for.outer:
429; CHECK:   br label %for.inner
430; CHECK: for.inner:
431; CHECK:   br i1 %exitcond.3, label %for.inner, label %for.latch
432; CHECK: for.latch:
433; CHECK:   br label %for.end
434; CHECK: for.end:
435; CHECK:   ret i32 0
436@f = hidden global i32 0, align 4
437define i32 @test6() #0 {
438entry:
439  %f.promoted10 = load i32, i32* @f, align 4, !tbaa !5
440  br label %for.outer
441
442for.outer:
443  %p0 = phi i32 [ %f.promoted10, %entry ], [ 2, %for.latch ]
444  %inc5.sink9 = phi i32 [ 2, %entry ], [ %inc5, %for.latch ]
445  br label %for.inner
446
447for.inner:
448  %p1 = phi i32 [ %p0, %for.outer ], [ 2, %for.inner ]
449  %inc.sink8 = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ]
450  %inc = add nuw nsw i32 %inc.sink8, 1
451  %exitcond = icmp ne i32 %inc, 7
452  br i1 %exitcond, label %for.inner, label %for.latch
453
454for.latch:
455  %.lcssa = phi i32 [ %p1, %for.inner ]
456  %inc5 = add nuw nsw i32 %inc5.sink9, 1
457  %exitcond11 = icmp ne i32 %inc5, 7
458  br i1 %exitcond11, label %for.outer, label %for.end
459
460for.end:
461  %.lcssa.lcssa = phi i32 [ %.lcssa, %for.latch ]
462  %inc.lcssa.lcssa = phi i32 [ 7, %for.latch ]
463  ret i32 0
464}
465
466
467; CHECK-LABEL: test7
468; Has a positive dependency between two stores. Still valid.
469; The negative dependecy is in unroll-and-jam-disabled.ll
470; CHECK: for.outer:
471; CHECK:   %i = phi i32 [ %add.3, %for.latch ], [ 0, %for.preheader.new ]
472; CHECK:   %niter = phi i32 [ %unroll_iter, %for.preheader.new ], [ %niter.nsub.3, %for.latch ]
473; CHECK:   br label %for.inner
474; CHECK: for.latch:
475; CHECK:   %add9.lcssa = phi i32 [ %add9, %for.inner ]
476; CHECK:   %add9.lcssa.1 = phi i32 [ %add9.1, %for.inner ]
477; CHECK:   %add9.lcssa.2 = phi i32 [ %add9.2, %for.inner ]
478; CHECK:   %add9.lcssa.3 = phi i32 [ %add9.3, %for.inner ]
479; CHECK:   br i1 %niter.ncmp.3, label %for.end.loopexit.unr-lcssa.loopexit, label %for.outer
480; CHECK: for.inner:
481; CHECK:   %sum = phi i32 [ 0, %for.outer ], [ %add9, %for.inner ]
482; CHECK:   %j = phi i32 [ 0, %for.outer ], [ %add10, %for.inner ]
483; CHECK:   %sum.1 = phi i32 [ 0, %for.outer ], [ %add9.1, %for.inner ]
484; CHECK:   %j.1 = phi i32 [ 0, %for.outer ], [ %add10.1, %for.inner ]
485; CHECK:   %sum.2 = phi i32 [ 0, %for.outer ], [ %add9.2, %for.inner ]
486; CHECK:   %j.2 = phi i32 [ 0, %for.outer ], [ %add10.2, %for.inner ]
487; CHECK:   %sum.3 = phi i32 [ 0, %for.outer ], [ %add9.3, %for.inner ]
488; CHECK:   %j.3 = phi i32 [ 0, %for.outer ], [ %add10.3, %for.inner ]
489; CHECK:   br i1 %exitcond.3, label %for.latch, label %for.inner
490; CHECK: for.end.loopexit.unr-lcssa.loopexit:
491define void @test7(i32 %I, i32 %J, i32* noalias nocapture %A, i32* noalias nocapture readonly %B) #0 {
492entry:
493  %cmp = icmp ne i32 %J, 0
494  %cmp128 = icmp ne i32 %I, 0
495  %or.cond = and i1 %cmp128, %cmp
496  br i1 %or.cond, label %for.preheader, label %for.end
497
498for.preheader:
499  br label %for.outer
500
501for.outer:
502  %i = phi i32 [ %add, %for.latch ], [ 0, %for.preheader ]
503  %arrayidx = getelementptr inbounds i32, i32* %A, i32 %i
504  store i32 0, i32* %arrayidx, align 4, !tbaa !5
505  %add = add nuw i32 %i, 1
506  %arrayidx2 = getelementptr inbounds i32, i32* %A, i32 %add
507  store i32 2, i32* %arrayidx2, align 4, !tbaa !5
508  br label %for.inner
509
510for.latch:
511  store i32 %add9, i32* %arrayidx, align 4, !tbaa !5
512  %exitcond30 = icmp eq i32 %add, %I
513  br i1 %exitcond30, label %for.end, label %for.outer
514
515for.inner:
516  %sum = phi i32 [ 0, %for.outer ], [ %add9, %for.inner ]
517  %j = phi i32 [ 0, %for.outer ], [ %add10, %for.inner ]
518  %arrayidx7 = getelementptr inbounds i32, i32* %B, i32 %j
519  %l1 = load i32, i32* %arrayidx7, align 4, !tbaa !5
520  %add9 = add i32 %l1, %sum
521  %add10 = add nuw i32 %j, 1
522  %exitcond = icmp eq i32 %add10, %J
523  br i1 %exitcond, label %for.latch, label %for.inner
524
525for.end:
526  ret void
527}
528
529
530; CHECK-LABEL: test8
531; Same as test7 with an extra outer loop nest
532; CHECK: for.outest:
533; CHECK:   br label %for.outer
534; CHECK: for.outer:
535; CHECK:   %i = phi i32 [ %add.3, %for.latch ], [ 0, %for.outest.new ]
536; CHECK:   %niter = phi i32 [ %unroll_iter, %for.outest.new ], [ %niter.nsub.3, %for.latch ]
537; CHECK:   br label %for.inner
538; CHECK: for.inner:
539; CHECK:   %sum = phi i32 [ 0, %for.outer ], [ %add9, %for.inner ]
540; CHECK:   %j = phi i32 [ 0, %for.outer ], [ %add10, %for.inner ]
541; CHECK:   %sum.1 = phi i32 [ 0, %for.outer ], [ %add9.1, %for.inner ]
542; CHECK:   %j.1 = phi i32 [ 0, %for.outer ], [ %add10.1, %for.inner ]
543; CHECK:   %sum.2 = phi i32 [ 0, %for.outer ], [ %add9.2, %for.inner ]
544; CHECK:   %j.2 = phi i32 [ 0, %for.outer ], [ %add10.2, %for.inner ]
545; CHECK:   %sum.3 = phi i32 [ 0, %for.outer ], [ %add9.3, %for.inner ]
546; CHECK:   %j.3 = phi i32 [ 0, %for.outer ], [ %add10.3, %for.inner ]
547; CHECK:   br i1 %exitcond.3, label %for.latch, label %for.inner
548; CHECK: for.latch:
549; CHECK:   %add9.lcssa = phi i32 [ %add9, %for.inner ]
550; CHECK:   %add9.lcssa.1 = phi i32 [ %add9.1, %for.inner ]
551; CHECK:   %add9.lcssa.2 = phi i32 [ %add9.2, %for.inner ]
552; CHECK:   %add9.lcssa.3 = phi i32 [ %add9.3, %for.inner ]
553; CHECK:   br i1 %niter.ncmp.3, label %for.cleanup.unr-lcssa.loopexit, label %for.outer
554; CHECK: for.cleanup.epilog-lcssa:
555; CHECK:   br label %for.cleanup
556; CHECK: for.cleanup:
557; CHECK:   br i1 %exitcond41, label %for.end.loopexit, label %for.outest
558; CHECK: for.end.loopexit:
559; CHECK:   br label %for.end
560define void @test8(i32 %I, i32 %J, i32* noalias nocapture %A, i32* noalias nocapture readonly %B) #0 {
561entry:
562  %cmp = icmp eq i32 %J, 0
563  %cmp336 = icmp eq i32 %I, 0
564  %or.cond = or i1 %cmp, %cmp336
565  br i1 %or.cond, label %for.end, label %for.preheader
566
567for.preheader:
568  br label %for.outest
569
570for.outest:
571  %x.038 = phi i32 [ %inc, %for.cleanup ], [ 0, %for.preheader ]
572  br label %for.outer
573
574for.outer:
575  %i = phi i32 [ %add, %for.latch ], [ 0, %for.outest ]
576  %arrayidx = getelementptr inbounds i32, i32* %A, i32 %i
577  store i32 0, i32* %arrayidx, align 4, !tbaa !5
578  %add = add nuw i32 %i, 1
579  %arrayidx6 = getelementptr inbounds i32, i32* %A, i32 %add
580  store i32 2, i32* %arrayidx6, align 4, !tbaa !5
581  br label %for.inner
582
583for.inner:
584  %sum = phi i32 [ 0, %for.outer ], [ %add9, %for.inner ]
585  %j = phi i32 [ 0, %for.outer ], [ %add10, %for.inner ]
586  %arrayidx11 = getelementptr inbounds i32, i32* %B, i32 %j
587  %l1 = load i32, i32* %arrayidx11, align 4, !tbaa !5
588  %add9 = add i32 %l1, %sum
589  %add10 = add nuw i32 %j, 1
590  %exitcond = icmp eq i32 %add10, %J
591  br i1 %exitcond, label %for.latch, label %for.inner
592
593for.latch:
594  store i32 %add9, i32* %arrayidx, align 4, !tbaa !5
595  %exitcond39 = icmp eq i32 %add, %I
596  br i1 %exitcond39, label %for.cleanup, label %for.outer
597
598for.cleanup:
599  %inc = add nuw nsw i32 %x.038, 1
600  %exitcond41 = icmp eq i32 %inc, 5
601  br i1 %exitcond41, label %for.end, label %for.outest
602
603for.end:
604  ret void
605}
606
607
608; CHECK-LABEL: test9
609; Same as test1 with tbaa, not noalias
610; CHECK: for.outer:
611; CHECK:   %i = phi i32 [ %add8.3, %for.latch ], [ 0, %for.outer.preheader.new ]
612; CHECK:   %niter = phi i32 [ %unroll_iter, %for.outer.preheader.new ], [ %niter.nsub.3, %for.latch ]
613; CHECK:   br label %for.inner
614; CHECK: for.inner:
615; CHECK:   %j = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ]
616; CHECK:   %sum = phi i32 [ 0, %for.outer ], [ %add, %for.inner ]
617; CHECK:   %j.1 = phi i32 [ 0, %for.outer ], [ %inc.1, %for.inner ]
618; CHECK:   %sum.1 = phi i32 [ 0, %for.outer ], [ %add.1, %for.inner ]
619; CHECK:   %j.2 = phi i32 [ 0, %for.outer ], [ %inc.2, %for.inner ]
620; CHECK:   %sum.2 = phi i32 [ 0, %for.outer ], [ %add.2, %for.inner ]
621; CHECK:   %j.3 = phi i32 [ 0, %for.outer ], [ %inc.3, %for.inner ]
622; CHECK:   %sum.3 = phi i32 [ 0, %for.outer ], [ %add.3, %for.inner ]
623; CHECK:   br i1 %exitcond.3, label %for.latch, label %for.inner
624; CHECK: for.latch:
625; CHECK:   %add.lcssa = phi i32 [ %add, %for.inner ]
626; CHECK:   %add.lcssa.1 = phi i32 [ %add.1, %for.inner ]
627; CHECK:   %add.lcssa.2 = phi i32 [ %add.2, %for.inner ]
628; CHECK:   %add.lcssa.3 = phi i32 [ %add.3, %for.inner ]
629; CHECK:   br i1 %niter.ncmp.3, label %for.end.loopexit.unr-lcssa.loopexit, label %for.outer
630; CHECK: for.end.loopexit.unr-lcssa.loopexit:
631define void @test9(i32 %I, i32 %J, i32* nocapture %A, i16* nocapture readonly %B) #0 {
632entry:
633  %cmp = icmp ne i32 %J, 0
634  %cmpJ = icmp ne i32 %I, 0
635  %or.cond = and i1 %cmp, %cmpJ
636  br i1 %or.cond, label %for.outer.preheader, label %for.end
637
638for.outer.preheader:
639  br label %for.outer
640
641for.outer:
642  %i = phi i32 [ %add8, %for.latch ], [ 0, %for.outer.preheader ]
643  br label %for.inner
644
645for.inner:
646  %j = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ]
647  %sum = phi i32 [ 0, %for.outer ], [ %add, %for.inner ]
648  %arrayidx = getelementptr inbounds i16, i16* %B, i32 %j
649  %0 = load i16, i16* %arrayidx, align 4, !tbaa !9
650  %sext = sext i16 %0 to i32
651  %add = add i32 %sext, %sum
652  %inc = add nuw i32 %j, 1
653  %exitcond = icmp eq i32 %inc, %J
654  br i1 %exitcond, label %for.latch, label %for.inner
655
656for.latch:
657  %add.lcssa = phi i32 [ %add, %for.inner ]
658  %arrayidx6 = getelementptr inbounds i32, i32* %A, i32 %i
659  store i32 %add.lcssa, i32* %arrayidx6, align 4, !tbaa !5
660  %add8 = add nuw i32 %i, 1
661  %exitcond25 = icmp eq i32 %add8, %I
662  br i1 %exitcond25, label %for.end.loopexit, label %for.outer
663
664for.end.loopexit:
665  br label %for.end
666
667for.end:
668  ret void
669}
670
671
672; CHECK-LABEL: test10
673; Be careful not to incorrectly update the exit phi nodes
674; CHECK: %dec.lcssa.lcssa.ph.ph = phi i64 [ 0, %for.inc24 ]
675%struct.a = type { i64 }
676@g = common global %struct.a zeroinitializer, align 8
677@c = common global [1 x i8] zeroinitializer, align 1
678define signext i16 @test10(i32 %k) #0 {
679entry:
680  %0 = load i8, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @c, i64 0, i64 0), align 1
681  %tobool9 = icmp eq i8 %0, 0
682  %tobool13 = icmp ne i32 %k, 0
683  br label %for.body
684
685for.body:
686  %storemerge82 = phi i64 [ 0, %entry ], [ %inc25, %for.inc24 ]
687  br label %for.body2
688
689for.body2:
690  %storemerge = phi i64 [ 4, %for.body ], [ %dec, %for.inc21 ]
691  br i1 %tobool9, label %for.body2.split, label %for.body2.split2
692
693for.body2.split2:
694  br i1 %tobool13, label %for.inc21, label %for.inc21.if
695
696for.body2.split:
697  br i1 %tobool13, label %for.inc21, label %for.inc21.then
698
699for.inc21.if:
700  %storemerge.1 = phi i64 [ 0, %for.body2.split2 ]
701  br label %for.inc21
702
703for.inc21.then:
704  %storemerge.2 = phi i64 [ 0, %for.body2.split ]
705  %storemerge.3 = phi i32 [ 0, %for.body2.split ]
706  br label %for.inc21
707
708for.inc21:
709  %storemerge.4 = phi i64 [ %storemerge.1, %for.inc21.if ], [ %storemerge.2, %for.inc21.then ], [ 4, %for.body2.split2 ], [ 4, %for.body2.split ]
710  %storemerge.5 = phi i32 [ 0, %for.inc21.if ], [ %storemerge.3, %for.inc21.then ], [ 0, %for.body2.split2 ], [ 0, %for.body2.split ]
711  %dec = add nsw i64 %storemerge, -1
712  %tobool = icmp eq i64 %dec, 0
713  br i1 %tobool, label %for.inc24, label %for.body2
714
715for.inc24:
716  %storemerge.4.lcssa = phi i64 [ %storemerge.4, %for.inc21 ]
717  %storemerge.5.lcssa = phi i32 [ %storemerge.5, %for.inc21 ]
718  %inc25 = add nuw nsw i64 %storemerge82, 1
719  %exitcond = icmp ne i64 %inc25, 5
720  br i1 %exitcond, label %for.body, label %for.end26
721
722for.end26:
723  %dec.lcssa.lcssa = phi i64 [ 0, %for.inc24 ]
724  %storemerge.4.lcssa.lcssa = phi i64 [ %storemerge.4.lcssa, %for.inc24 ]
725  %storemerge.5.lcssa.lcssa = phi i32 [ %storemerge.5.lcssa, %for.inc24 ]
726  store i64 %dec.lcssa.lcssa, i64* getelementptr inbounds (%struct.a, %struct.a* @g, i64 0, i32 0), align 8
727  ret i16 0
728}
729
730
731!5 = !{!6, !6, i64 0}
732!6 = !{!"int", !7, i64 0}
733!7 = !{!"omnipotent char", !8, i64 0}
734!8 = !{!"Simple C/C++ TBAA"}
735!9 = !{!10, !10, i64 0}
736!10 = !{!"short", !7, i64 0}
737