1; RUN: opt < %s -loop-reroll -S | FileCheck %s
2target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:32:64-v128:32:128-a0:0:32-n32-S32"
3target triple = "thumbv7-none-linux"
4
5;void foo(int *A, int *B, int m, int n) {
6;  for (int i = m; i < n; i+=4) {
7;    A[i+0] = B[i+0] * 4;
8;    A[i+1] = B[i+1] * 4;
9;    A[i+2] = B[i+2] * 4;
10;    A[i+3] = B[i+3] * 4;
11;  }
12;}
13define void @foo(i32* nocapture %A, i32* nocapture readonly %B, i32 %m, i32 %n) {
14entry:
15  %cmp34 = icmp slt i32 %m, %n
16  br i1 %cmp34, label %for.body, label %for.end
17
18for.body:                                         ; preds = %entry, %for.body
19  %i.035 = phi i32 [ %add18, %for.body ], [ %m, %entry ]
20  %arrayidx = getelementptr inbounds i32, i32* %B, i32 %i.035
21  %0 = load i32, i32* %arrayidx, align 4
22  %mul = shl nsw i32 %0, 2
23  %arrayidx2 = getelementptr inbounds i32, i32* %A, i32 %i.035
24  store i32 %mul, i32* %arrayidx2, align 4
25  %add3 = add nsw i32 %i.035, 1
26  %arrayidx4 = getelementptr inbounds i32, i32* %B, i32 %add3
27  %1 = load i32, i32* %arrayidx4, align 4
28  %mul5 = shl nsw i32 %1, 2
29  %arrayidx7 = getelementptr inbounds i32, i32* %A, i32 %add3
30  store i32 %mul5, i32* %arrayidx7, align 4
31  %add8 = add nsw i32 %i.035, 2
32  %arrayidx9 = getelementptr inbounds i32, i32* %B, i32 %add8
33  %2 = load i32, i32* %arrayidx9, align 4
34  %mul10 = shl nsw i32 %2, 2
35  %arrayidx12 = getelementptr inbounds i32, i32* %A, i32 %add8
36  store i32 %mul10, i32* %arrayidx12, align 4
37  %add13 = add nsw i32 %i.035, 3
38  %arrayidx14 = getelementptr inbounds i32, i32* %B, i32 %add13
39  %3 = load i32, i32* %arrayidx14, align 4
40  %mul15 = shl nsw i32 %3, 2
41  %arrayidx17 = getelementptr inbounds i32, i32* %A, i32 %add13
42  store i32 %mul15, i32* %arrayidx17, align 4
43  %add18 = add nsw i32 %i.035, 4
44  %cmp = icmp slt i32 %add18, %n
45  br i1 %cmp, label %for.body, label %for.end
46
47for.end:                                          ; preds = %for.body, %entry
48  ret void
49}
50; CHECK-LABEL: @foo
51; CHECK: for.body.preheader:
52; CHECK:   %0 = add i32 %n, -1
53; CHECK:   %1 = sub i32 %0, %m
54; CHECK:   %2 = lshr i32 %1, 2
55; CHECK:   %3 = shl nuw i32 %2, 2
56; CHECK:   %4 = add nuw nsw i32 %3, 3
57; CHECK:   br label %for.body
58
59; CHECK: for.body:
60; CHECK:   %indvar = phi i32 [ 0, %for.body.preheader ], [ %indvar.next, %for.body ]
61; CHECK:   %5 = add i32 %m, %indvar
62; CHECK:   %arrayidx = getelementptr inbounds i32, i32* %B, i32 %5
63; CHECK:   %6 = load i32, i32* %arrayidx, align 4
64; CHECK:   %mul = shl nsw i32 %6, 2
65; CHECK:   %arrayidx2 = getelementptr inbounds i32, i32* %A, i32 %5
66; CHECK:   store i32 %mul, i32* %arrayidx2, align 4
67; CHECK:   %indvar.next = add i32 %indvar, 1
68; CHECK:   %exitcond = icmp eq i32 %indvar, %4
69; CHECK:   br i1 %exitcond, label %for.end.loopexit, label %for.body
70
71;void daxpy_ur(int n,float da,float *dx,float *dy)
72;    {
73;    int m = n % 4;
74;    for (int i = m; i < n; i = i + 4)
75;        {
76;        dy[i]   = dy[i]   + da*dx[i];
77;        dy[i+1] = dy[i+1] + da*dx[i+1];
78;        dy[i+2] = dy[i+2] + da*dx[i+2];
79;        dy[i+3] = dy[i+3] + da*dx[i+3];
80;        }
81;    }
82define void @daxpy_ur(i32 %n, float %da, float* nocapture readonly %dx, float* nocapture %dy) {
83entry:
84  %rem = srem i32 %n, 4
85  %cmp55 = icmp slt i32 %rem, %n
86  br i1 %cmp55, label %for.body, label %for.end
87
88for.body:                                         ; preds = %entry, %for.body
89  %i.056 = phi i32 [ %add27, %for.body ], [ %rem, %entry ]
90  %arrayidx = getelementptr inbounds float, float* %dy, i32 %i.056
91  %0 = load float, float* %arrayidx, align 4
92  %arrayidx1 = getelementptr inbounds float, float* %dx, i32 %i.056
93  %1 = load float, float* %arrayidx1, align 4
94  %mul = fmul float %1, %da
95  %add = fadd float %0, %mul
96  store float %add, float* %arrayidx, align 4
97  %add3 = add nsw i32 %i.056, 1
98  %arrayidx4 = getelementptr inbounds float, float* %dy, i32 %add3
99  %2 = load float, float* %arrayidx4, align 4
100  %arrayidx6 = getelementptr inbounds float, float* %dx, i32 %add3
101  %3 = load float, float* %arrayidx6, align 4
102  %mul7 = fmul float %3, %da
103  %add8 = fadd float %2, %mul7
104  store float %add8, float* %arrayidx4, align 4
105  %add11 = add nsw i32 %i.056, 2
106  %arrayidx12 = getelementptr inbounds float, float* %dy, i32 %add11
107  %4 = load float, float* %arrayidx12, align 4
108  %arrayidx14 = getelementptr inbounds float, float* %dx, i32 %add11
109  %5 = load float, float* %arrayidx14, align 4
110  %mul15 = fmul float %5, %da
111  %add16 = fadd float %4, %mul15
112  store float %add16, float* %arrayidx12, align 4
113  %add19 = add nsw i32 %i.056, 3
114  %arrayidx20 = getelementptr inbounds float, float* %dy, i32 %add19
115  %6 = load float, float* %arrayidx20, align 4
116  %arrayidx22 = getelementptr inbounds float, float* %dx, i32 %add19
117  %7 = load float, float* %arrayidx22, align 4
118  %mul23 = fmul float %7, %da
119  %add24 = fadd float %6, %mul23
120  store float %add24, float* %arrayidx20, align 4
121  %add27 = add nsw i32 %i.056, 4
122  %cmp = icmp slt i32 %add27, %n
123  br i1 %cmp, label %for.body, label %for.end
124
125for.end:                                          ; preds = %for.body, %entry
126  ret void
127}
128
129; CHECK-LABEL: @daxpy_ur
130; CHECK: for.body.preheader:
131; CHECK:   %0 = add i32 %n, -1
132; CHECK:   %1 = sub i32 %0, %rem
133; CHECK:   %2 = lshr i32 %1, 2
134; CHECK:   %3 = shl nuw i32 %2, 2
135; CHECK:   %4 = add nuw nsw i32 %3, 3
136; CHECK:   br label %for.body
137
138; CHECK: for.body:
139; CHECK:   %indvar = phi i32 [ 0, %for.body.preheader ], [ %indvar.next, %for.body ]
140; CHECK:   %5 = add i32 %rem, %indvar
141; CHECK:   %arrayidx = getelementptr inbounds float, float* %dy, i32 %5
142; CHECK:   %6 = load float, float* %arrayidx, align 4
143; CHECK:   %arrayidx1 = getelementptr inbounds float, float* %dx, i32 %5
144; CHECK:   %7 = load float, float* %arrayidx1, align 4
145; CHECK:   %mul = fmul float %7, %da
146; CHECK:   %add = fadd float %6, %mul
147; CHECK:   store float %add, float* %arrayidx, align 4
148; CHECK:   %indvar.next = add i32 %indvar, 1
149; CHECK:   %exitcond = icmp eq i32 %indvar, %4
150; CHECK:   br i1 %exitcond, label %for.end.loopexit, label %for.body
151