1 ; RUN: opt < %s -loop-reroll -S | FileCheck %s
2 target 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"
3 target triple = "thumbv7-none-linux"
5 ;void foo(int *A, int *B, int m, int n) {
6 ; for (int i = m; i < n; i+=4) {
10 ; A[i+3] = B[i+3] * 4;
13 define void @foo(i32* nocapture %A, i32* nocapture readonly %B, i32 %m, i32 %n) {
15 %cmp34 = icmp slt i32 %m, %n
16 br i1 %cmp34, label %for.body, label %for.end
18 for.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
47 for.end: ; preds = %for.body, %entry
51 ; CHECK: for.body.preheader: ; preds = %entry
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 i32 %3, 3
57 ; CHECK: br label %for.body
59 ; CHECK: for.body: ; preds = %for.body, %for.body.preheader
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
71 ;void daxpy_ur(int n,float da,float *dx,float *dy)
74 ; for (int i = m; i < n; i = i + 4)
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];
82 define void @daxpy_ur(i32 %n, float %da, float* nocapture readonly %dx, float* nocapture %dy) {
85 %cmp55 = icmp slt i32 %rem, %n
86 br i1 %cmp55, label %for.body, label %for.end
88 for.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
125 for.end: ; preds = %for.body, %entry
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 i32 %3, 3
136 ; CHECK: br label %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