1; RUN: opt -basic-aa -loop-unroll-and-jam -allow-unroll-and-jam -unroll-and-jam-count=4 < %s -S | FileCheck %s
2; RUN: opt -aa-pipeline=basic-aa -passes='loop-unroll-and-jam' -allow-unroll-and-jam -unroll-and-jam-count=4 < %s -S | FileCheck %s
3
4target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
5
6; CHECK-LABEL: fore_aft_less
7; CHECK: %j = phi
8; CHECK: %j.1 = phi
9; CHECK: %j.2 = phi
10; CHECK: %j.3 = phi
11define void @fore_aft_less(i32* noalias nocapture %A, i32 %N, i32* noalias nocapture readonly %B) {
12entry:
13  %cmp = icmp sgt i32 %N, 0
14  br i1 %cmp, label %for.outer, label %cleanup
15
16for.outer:
17  %i = phi i32 [ %add7, %for.latch ], [ 0, %entry ]
18  %arrayidx = getelementptr inbounds i32, i32* %A, i32 %i
19  store i32 1, i32* %arrayidx, align 4
20  br label %for.inner
21
22for.inner:
23  %j = phi i32 [ %add6, %for.inner ], [ 0, %for.outer ]
24  %sum = phi i32 [ %add, %for.inner ], [ 0, %for.outer ]
25  %arrayidx5 = getelementptr inbounds i32, i32* %B, i32 %j
26  %0 = load i32, i32* %arrayidx5, align 4
27  %mul = mul nsw i32 %0, %i
28  %add = add nsw i32 %mul, %sum
29  %add6 = add nuw nsw i32 %j, 1
30  %exitcond = icmp eq i32 %add6, %N
31  br i1 %exitcond, label %for.latch, label %for.inner
32
33for.latch:
34  %add7 = add nuw nsw i32 %i, 1
35  %add72 = add nuw nsw i32 %i, -1
36  %arrayidx8 = getelementptr inbounds i32, i32* %A, i32 %add72
37  store i32 %add, i32* %arrayidx8, align 4
38  %exitcond29 = icmp eq i32 %add7, %N
39  br i1 %exitcond29, label %cleanup, label %for.outer
40
41cleanup:
42  ret void
43}
44
45
46; CHECK-LABEL: fore_aft_eq
47; CHECK: %j = phi
48; CHECK: %j.1 = phi
49; CHECK: %j.2 = phi
50; CHECK: %j.3 = phi
51define void @fore_aft_eq(i32* noalias nocapture %A, i32 %N, i32* noalias nocapture readonly %B) {
52entry:
53  %cmp = icmp sgt i32 %N, 0
54  br i1 %cmp, label %for.outer, label %cleanup
55
56for.outer:
57  %i = phi i32 [ %add7, %for.latch ], [ 0, %entry ]
58  %arrayidx = getelementptr inbounds i32, i32* %A, i32 %i
59  store i32 1, i32* %arrayidx, align 4
60  br label %for.inner
61
62for.inner:
63  %j = phi i32 [ %add6, %for.inner ], [ 0, %for.outer ]
64  %sum = phi i32 [ %add, %for.inner ], [ 0, %for.outer ]
65  %arrayidx5 = getelementptr inbounds i32, i32* %B, i32 %j
66  %0 = load i32, i32* %arrayidx5, align 4
67  %mul = mul nsw i32 %0, %i
68  %add = add nsw i32 %mul, %sum
69  %add6 = add nuw nsw i32 %j, 1
70  %exitcond = icmp eq i32 %add6, %N
71  br i1 %exitcond, label %for.latch, label %for.inner
72
73for.latch:
74  %add7 = add nuw nsw i32 %i, 1
75  %add72 = add nuw nsw i32 %i, 0
76  %arrayidx8 = getelementptr inbounds i32, i32* %A, i32 %i
77  store i32 %add, i32* %arrayidx8, align 4
78  %exitcond29 = icmp eq i32 %add7, %N
79  br i1 %exitcond29, label %cleanup, label %for.outer
80
81cleanup:
82  ret void
83}
84
85
86; CHECK-LABEL: fore_aft_more
87; CHECK: %j = phi
88; CHECK-NOT: %j.1 = phi
89define void @fore_aft_more(i32* noalias nocapture %A, i32 %N, i32* noalias nocapture readonly %B) {
90entry:
91  %cmp = icmp sgt i32 %N, 0
92  br i1 %cmp, label %for.outer, label %cleanup
93
94for.outer:
95  %i = phi i32 [ %add7, %for.latch ], [ 0, %entry ]
96  %arrayidx = getelementptr inbounds i32, i32* %A, i32 %i
97  store i32 1, i32* %arrayidx, align 4
98  br label %for.inner
99
100for.inner:
101  %j = phi i32 [ %add6, %for.inner ], [ 0, %for.outer ]
102  %sum = phi i32 [ %add, %for.inner ], [ 0, %for.outer ]
103  %arrayidx5 = getelementptr inbounds i32, i32* %B, i32 %j
104  %0 = load i32, i32* %arrayidx5, align 4
105  %mul = mul nsw i32 %0, %i
106  %add = add nsw i32 %mul, %sum
107  %add6 = add nuw nsw i32 %j, 1
108  %exitcond = icmp eq i32 %add6, %N
109  br i1 %exitcond, label %for.latch, label %for.inner
110
111for.latch:
112  %add7 = add nuw nsw i32 %i, 1
113  %add72 = add nuw nsw i32 %i, 1
114  %arrayidx8 = getelementptr inbounds i32, i32* %A, i32 %add72
115  store i32 %add, i32* %arrayidx8, align 4
116  %exitcond29 = icmp eq i32 %add7, %N
117  br i1 %exitcond29, label %cleanup, label %for.outer
118
119cleanup:
120  ret void
121}
122
123
124; CHECK-LABEL: fore_sub_less
125; CHECK: %j = phi
126; CHECK: %j.1 = phi
127; CHECK: %j.2 = phi
128; CHECK: %j.3 = phi
129define void @fore_sub_less(i32* noalias nocapture %A, i32 %N, i32* noalias nocapture readonly %B) {
130entry:
131  %cmp = icmp sgt i32 %N, 0
132  br i1 %cmp, label %for.outer, label %cleanup
133
134for.outer:
135  %i = phi i32 [ %add7, %for.latch ], [ 0, %entry ]
136  %arrayidx = getelementptr inbounds i32, i32* %A, i32 %i
137  store i32 1, i32* %arrayidx, align 4
138  br label %for.inner
139
140for.inner:
141  %j = phi i32 [ %add6, %for.inner ], [ 0, %for.outer ]
142  %sum = phi i32 [ %add, %for.inner ], [ 0, %for.outer ]
143  %arrayidx5 = getelementptr inbounds i32, i32* %B, i32 %j
144  %0 = load i32, i32* %arrayidx5, align 4
145  %mul = mul nsw i32 %0, %i
146  %add = add nsw i32 %mul, %sum
147  %add72 = add nuw nsw i32 %i, -1
148  %arrayidx8 = getelementptr inbounds i32, i32* %A, i32 %add72
149  store i32 %add, i32* %arrayidx8, align 4
150  %add6 = add nuw nsw i32 %j, 1
151  %exitcond = icmp eq i32 %add6, %N
152  br i1 %exitcond, label %for.latch, label %for.inner
153
154for.latch:
155  %add7 = add nuw nsw i32 %i, 1
156  %exitcond29 = icmp eq i32 %add7, %N
157  br i1 %exitcond29, label %cleanup, label %for.outer
158
159cleanup:
160  ret void
161}
162
163
164; CHECK-LABEL: fore_sub_eq
165; CHECK: %j = phi
166; CHECK: %j.1 = phi
167; CHECK: %j.2 = phi
168; CHECK: %j.3 = phi
169define void @fore_sub_eq(i32* noalias nocapture %A, i32 %N, i32* noalias nocapture readonly %B) {
170entry:
171  %cmp = icmp sgt i32 %N, 0
172  br i1 %cmp, label %for.outer, label %cleanup
173
174for.outer:
175  %i = phi i32 [ %add7, %for.latch ], [ 0, %entry ]
176  %arrayidx = getelementptr inbounds i32, i32* %A, i32 %i
177  store i32 1, i32* %arrayidx, align 4
178  br label %for.inner
179
180for.inner:
181  %j = phi i32 [ %add6, %for.inner ], [ 0, %for.outer ]
182  %sum = phi i32 [ %add, %for.inner ], [ 0, %for.outer ]
183  %arrayidx5 = getelementptr inbounds i32, i32* %B, i32 %j
184  %0 = load i32, i32* %arrayidx5, align 4
185  %mul = mul nsw i32 %0, %i
186  %add = add nsw i32 %mul, %sum
187  %add72 = add nuw nsw i32 %i, 0
188  %arrayidx8 = getelementptr inbounds i32, i32* %A, i32 %add72
189  store i32 %add, i32* %arrayidx8, align 4
190  %add6 = add nuw nsw i32 %j, 1
191  %exitcond = icmp eq i32 %add6, %N
192  br i1 %exitcond, label %for.latch, label %for.inner
193
194for.latch:
195  %add7 = add nuw nsw i32 %i, 1
196  %exitcond29 = icmp eq i32 %add7, %N
197  br i1 %exitcond29, label %cleanup, label %for.outer
198
199cleanup:
200  ret void
201}
202
203
204; CHECK-LABEL: fore_sub_more
205; CHECK: %j = phi
206; CHECK-NOT: %j.1 = phi
207define void @fore_sub_more(i32* noalias nocapture %A, i32 %N, i32* noalias nocapture readonly %B) {
208entry:
209  %cmp = icmp sgt i32 %N, 0
210  br i1 %cmp, label %for.outer, label %cleanup
211
212for.outer:
213  %i = phi i32 [ %add7, %for.latch ], [ 0, %entry ]
214  %arrayidx = getelementptr inbounds i32, i32* %A, i32 %i
215  store i32 1, i32* %arrayidx, align 4
216  br label %for.inner
217
218for.inner:
219  %j = phi i32 [ %add6, %for.inner ], [ 0, %for.outer ]
220  %sum = phi i32 [ %add, %for.inner ], [ 0, %for.outer ]
221  %arrayidx5 = getelementptr inbounds i32, i32* %B, i32 %j
222  %0 = load i32, i32* %arrayidx5, align 4
223  %mul = mul nsw i32 %0, %i
224  %add = add nsw i32 %mul, %sum
225  %add72 = add nuw nsw i32 %i, 1
226  %arrayidx8 = getelementptr inbounds i32, i32* %A, i32 %add72
227  store i32 %add, i32* %arrayidx8, align 4
228  %add6 = add nuw nsw i32 %j, 1
229  %exitcond = icmp eq i32 %add6, %N
230  br i1 %exitcond, label %for.latch, label %for.inner
231
232for.latch:
233  %add7 = add nuw nsw i32 %i, 1
234  %exitcond29 = icmp eq i32 %add7, %N
235  br i1 %exitcond29, label %cleanup, label %for.outer
236
237cleanup:
238  ret void
239}
240
241
242; CHECK-LABEL: sub_aft_less
243; CHECK: %j = phi
244; CHECK: %j.1 = phi
245; CHECK: %j.2 = phi
246; CHECK: %j.3 = phi
247define void @sub_aft_less(i32* noalias nocapture %A, i32 %N, i32* noalias nocapture readonly %B) {
248entry:
249  %cmp = icmp sgt i32 %N, 0
250  br i1 %cmp, label %for.outer, label %cleanup
251
252for.outer:
253  %i = phi i32 [ %add7, %for.latch ], [ 0, %entry ]
254  br label %for.inner
255
256for.inner:
257  %j = phi i32 [ %add6, %for.inner ], [ 0, %for.outer ]
258  %sum = phi i32 [ %add, %for.inner ], [ 0, %for.outer ]
259  %arrayidx5 = getelementptr inbounds i32, i32* %B, i32 %j
260  %0 = load i32, i32* %arrayidx5, align 4
261  %mul = mul nsw i32 %0, %i
262  %add = add nsw i32 %mul, %sum
263  %add6 = add nuw nsw i32 %j, 1
264  %arrayidx = getelementptr inbounds i32, i32* %A, i32 %i
265  store i32 1, i32* %arrayidx, align 4
266  %exitcond = icmp eq i32 %add6, %N
267  br i1 %exitcond, label %for.latch, label %for.inner
268
269for.latch:
270  %add7 = add nuw nsw i32 %i, 1
271  %add72 = add nuw nsw i32 %i, -1
272  %arrayidx8 = getelementptr inbounds i32, i32* %A, i32 %add72
273  store i32 %add, i32* %arrayidx8, align 4
274  %exitcond29 = icmp eq i32 %add7, %N
275  br i1 %exitcond29, label %cleanup, label %for.outer
276
277cleanup:
278  ret void
279}
280
281
282; CHECK-LABEL: sub_aft_eq
283; CHECK: %j = phi
284; CHECK: %j.1 = phi
285; CHECK: %j.2 = phi
286; CHECK: %j.3 = phi
287define void @sub_aft_eq(i32* noalias nocapture %A, i32 %N, i32* noalias nocapture readonly %B) {
288entry:
289  %cmp = icmp sgt i32 %N, 0
290  br i1 %cmp, label %for.outer, label %cleanup
291
292for.outer:
293  %i = phi i32 [ %add7, %for.latch ], [ 0, %entry ]
294  br label %for.inner
295
296for.inner:
297  %j = phi i32 [ %add6, %for.inner ], [ 0, %for.outer ]
298  %sum = phi i32 [ %add, %for.inner ], [ 0, %for.outer ]
299  %arrayidx5 = getelementptr inbounds i32, i32* %B, i32 %j
300  %0 = load i32, i32* %arrayidx5, align 4
301  %mul = mul nsw i32 %0, %i
302  %add = add nsw i32 %mul, %sum
303  %add6 = add nuw nsw i32 %j, 1
304  %arrayidx = getelementptr inbounds i32, i32* %A, i32 %i
305  store i32 1, i32* %arrayidx, align 4
306  %exitcond = icmp eq i32 %add6, %N
307  br i1 %exitcond, label %for.latch, label %for.inner
308
309for.latch:
310  %add7 = add nuw nsw i32 %i, 1
311  %add72 = add nuw nsw i32 %i, 0
312  %arrayidx8 = getelementptr inbounds i32, i32* %A, i32 %i
313  store i32 %add, i32* %arrayidx8, align 4
314  %exitcond29 = icmp eq i32 %add7, %N
315  br i1 %exitcond29, label %cleanup, label %for.outer
316
317cleanup:
318  ret void
319}
320
321
322; CHECK-LABEL: sub_aft_more
323; CHECK: %j = phi
324; CHECK-NOT: %j.1 = phi
325define void @sub_aft_more(i32* noalias nocapture %A, i32 %N, i32* noalias nocapture readonly %B) {
326entry:
327  %cmp = icmp sgt i32 %N, 0
328  br i1 %cmp, label %for.outer, label %cleanup
329
330for.outer:
331  %i = phi i32 [ %add7, %for.latch ], [ 0, %entry ]
332  br label %for.inner
333
334for.inner:
335  %j = phi i32 [ %add6, %for.inner ], [ 0, %for.outer ]
336  %sum = phi i32 [ %add, %for.inner ], [ 0, %for.outer ]
337  %arrayidx5 = getelementptr inbounds i32, i32* %B, i32 %j
338  %0 = load i32, i32* %arrayidx5, align 4
339  %mul = mul nsw i32 %0, %i
340  %add = add nsw i32 %mul, %sum
341  %add6 = add nuw nsw i32 %j, 1
342  %arrayidx = getelementptr inbounds i32, i32* %A, i32 %i
343  store i32 1, i32* %arrayidx, align 4
344  %exitcond = icmp eq i32 %add6, %N
345  br i1 %exitcond, label %for.latch, label %for.inner
346
347for.latch:
348  %add7 = add nuw nsw i32 %i, 1
349  %add72 = add nuw nsw i32 %i, 1
350  %arrayidx8 = getelementptr inbounds i32, i32* %A, i32 %add72
351  store i32 %add, i32* %arrayidx8, align 4
352  %exitcond29 = icmp eq i32 %add7, %N
353  br i1 %exitcond29, label %cleanup, label %for.outer
354
355cleanup:
356  ret void
357}
358
359
360; CHECK-LABEL: sub_sub_less
361; CHECK: %j = phi
362; CHECK-NOT: %j.1 = phi
363define void @sub_sub_less(i32* noalias nocapture %A, i32 %N, i32* noalias nocapture readonly %B) {
364entry:
365  %cmp = icmp sgt i32 %N, 0
366  br i1 %cmp, label %for.outer, label %cleanup
367
368for.outer:
369  %i = phi i32 [ %add7, %for.latch ], [ 0, %entry ]
370  br label %for.inner
371
372for.inner:
373  %j = phi i32 [ %add6, %for.inner ], [ 0, %for.outer ]
374  %sum = phi i32 [ %add, %for.inner ], [ 0, %for.outer ]
375  %arrayidx5 = getelementptr inbounds i32, i32* %B, i32 %j
376  %0 = load i32, i32* %arrayidx5, align 4
377  %mul = mul nsw i32 %0, %i
378  %add = add nsw i32 %mul, %sum
379  %add6 = add nuw nsw i32 %j, 1
380  %arrayidx = getelementptr inbounds i32, i32* %A, i32 %i
381  store i32 1, i32* %arrayidx, align 4
382  %add72 = add nuw nsw i32 %i, -1
383  %arrayidx8 = getelementptr inbounds i32, i32* %A, i32 %add72
384  store i32 %add, i32* %arrayidx8, align 4
385  %exitcond = icmp eq i32 %add6, %N
386  br i1 %exitcond, label %for.latch, label %for.inner
387
388for.latch:
389  %add7 = add nuw nsw i32 %i, 1
390  %exitcond29 = icmp eq i32 %add7, %N
391  br i1 %exitcond29, label %cleanup, label %for.outer
392
393cleanup:
394  ret void
395}
396
397
398; CHECK-LABEL: sub_sub_eq
399; CHECK: %j = phi
400; CHECK: %j.1 = phi
401; CHECK: %j.2 = phi
402; CHECK: %j.3 = phi
403define void @sub_sub_eq(i32* noalias nocapture %A, i32 %N, i32* noalias nocapture readonly %B) {
404entry:
405  %cmp = icmp sgt i32 %N, 0
406  br i1 %cmp, label %for.outer, label %cleanup
407
408for.outer:
409  %i = phi i32 [ %add7, %for.latch ], [ 0, %entry ]
410  br label %for.inner
411
412for.inner:
413  %j = phi i32 [ %add6, %for.inner ], [ 0, %for.outer ]
414  %sum = phi i32 [ %add, %for.inner ], [ 0, %for.outer ]
415  %arrayidx5 = getelementptr inbounds i32, i32* %B, i32 %j
416  %0 = load i32, i32* %arrayidx5, align 4
417  %mul = mul nsw i32 %0, %i
418  %add = add nsw i32 %mul, %sum
419  %add6 = add nuw nsw i32 %j, 1
420  %arrayidx = getelementptr inbounds i32, i32* %A, i32 %i
421  store i32 1, i32* %arrayidx, align 4
422  %add72 = add nuw nsw i32 %i, 0
423  %arrayidx8 = getelementptr inbounds i32, i32* %A, i32 %add72
424  store i32 %add, i32* %arrayidx8, align 4
425  %exitcond = icmp eq i32 %add6, %N
426  br i1 %exitcond, label %for.latch, label %for.inner
427
428for.latch:
429  %add7 = add nuw nsw i32 %i, 1
430  %exitcond29 = icmp eq i32 %add7, %N
431  br i1 %exitcond29, label %cleanup, label %for.outer
432
433cleanup:
434  ret void
435}
436
437
438; CHECK-LABEL: sub_sub_more
439; CHECK: %j = phi
440; CHECK-NOT: %j.1 = phi
441define void @sub_sub_more(i32* noalias nocapture %A, i32 %N, i32* noalias nocapture readonly %B) {
442entry:
443  %cmp = icmp sgt i32 %N, 0
444  br i1 %cmp, label %for.outer, label %cleanup
445
446for.outer:
447  %i = phi i32 [ %add7, %for.latch ], [ 0, %entry ]
448  br label %for.inner
449
450for.inner:
451  %j = phi i32 [ %add6, %for.inner ], [ 0, %for.outer ]
452  %sum = phi i32 [ %add, %for.inner ], [ 0, %for.outer ]
453  %arrayidx5 = getelementptr inbounds i32, i32* %B, i32 %j
454  %0 = load i32, i32* %arrayidx5, align 4
455  %mul = mul nsw i32 %0, %i
456  %add = add nsw i32 %mul, %sum
457  %add6 = add nuw nsw i32 %j, 1
458  %arrayidx = getelementptr inbounds i32, i32* %A, i32 %i
459  store i32 1, i32* %arrayidx, align 4
460  %add72 = add nuw nsw i32 %i, 1
461  %arrayidx8 = getelementptr inbounds i32, i32* %A, i32 %add72
462  store i32 %add, i32* %arrayidx8, align 4
463  %exitcond = icmp eq i32 %add6, %N
464  br i1 %exitcond, label %for.latch, label %for.inner
465
466for.latch:
467  %add7 = add nuw nsw i32 %i, 1
468  %exitcond29 = icmp eq i32 %add7, %N
469  br i1 %exitcond29, label %cleanup, label %for.outer
470
471cleanup:
472  ret void
473}
474