Merge r261331: avoid out of bounds loads for interleaved access vectorization
[oota-llvm.git] / test / Transforms / LoopReroll / nonconst_lb.ll
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"
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 ;}
13 define void @foo(i32* nocapture %A, i32* nocapture readonly %B, i32 %m, i32 %n) {
14 entry:
15   %cmp34 = icmp slt i32 %m, %n
16   br i1 %cmp34, label %for.body, label %for.end
17
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
46
47 for.end:                                          ; preds = %for.body, %entry
48   ret void
49 }
50 ; CHECK-LABEL: @foo
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 i32 %2, 2
56 ; CHECK:   %4 = add i32 %m, %3
57 ; CHECK:   %5 = add i32 %4, 3
58 ; CHECK:   br label %for.body
59
60 ; CHECK: for.body:                                         ; preds = %for.body, %for.body.preheader
61 ; CHECK:   %indvar = phi i32 [ %indvar.next, %for.body ], [ 0, %for.body.preheader ]
62 ; CHECK:   %6 = add i32 %m, %indvar
63 ; CHECK:   %arrayidx = getelementptr inbounds i32, i32* %B, i32 %6
64 ; CHECK:   %7 = load i32, i32* %arrayidx, align 4
65 ; CHECK:   %mul = shl nsw i32 %7, 2
66 ; CHECK:   %arrayidx2 = getelementptr inbounds i32, i32* %A, i32 %6
67 ; CHECK:   store i32 %mul, i32* %arrayidx2, align 4
68 ; CHECK:   %indvar.next = add i32 %indvar, 1
69 ; CHECK:   %exitcond = icmp eq i32 %6, %5
70 ; CHECK:   br i1 %exitcond, label %for.end, label %for.body
71
72 ;void daxpy_ur(int n,float da,float *dx,float *dy)
73 ;    {
74 ;    int m = n % 4;
75 ;    for (int i = m; i < n; i = i + 4)
76 ;        {
77 ;        dy[i]   = dy[i]   + da*dx[i];
78 ;        dy[i+1] = dy[i+1] + da*dx[i+1];
79 ;        dy[i+2] = dy[i+2] + da*dx[i+2];
80 ;        dy[i+3] = dy[i+3] + da*dx[i+3];
81 ;        }
82 ;    }
83 define void @daxpy_ur(i32 %n, float %da, float* nocapture readonly %dx, float* nocapture %dy) {
84 entry:
85   %rem = srem i32 %n, 4
86   %cmp55 = icmp slt i32 %rem, %n
87   br i1 %cmp55, label %for.body, label %for.end
88
89 for.body:                                         ; preds = %entry, %for.body
90   %i.056 = phi i32 [ %add27, %for.body ], [ %rem, %entry ]
91   %arrayidx = getelementptr inbounds float, float* %dy, i32 %i.056
92   %0 = load float, float* %arrayidx, align 4
93   %arrayidx1 = getelementptr inbounds float, float* %dx, i32 %i.056
94   %1 = load float, float* %arrayidx1, align 4
95   %mul = fmul float %1, %da
96   %add = fadd float %0, %mul
97   store float %add, float* %arrayidx, align 4
98   %add3 = add nsw i32 %i.056, 1
99   %arrayidx4 = getelementptr inbounds float, float* %dy, i32 %add3
100   %2 = load float, float* %arrayidx4, align 4
101   %arrayidx6 = getelementptr inbounds float, float* %dx, i32 %add3
102   %3 = load float, float* %arrayidx6, align 4
103   %mul7 = fmul float %3, %da
104   %add8 = fadd float %2, %mul7
105   store float %add8, float* %arrayidx4, align 4
106   %add11 = add nsw i32 %i.056, 2
107   %arrayidx12 = getelementptr inbounds float, float* %dy, i32 %add11
108   %4 = load float, float* %arrayidx12, align 4
109   %arrayidx14 = getelementptr inbounds float, float* %dx, i32 %add11
110   %5 = load float, float* %arrayidx14, align 4
111   %mul15 = fmul float %5, %da
112   %add16 = fadd float %4, %mul15
113   store float %add16, float* %arrayidx12, align 4
114   %add19 = add nsw i32 %i.056, 3
115   %arrayidx20 = getelementptr inbounds float, float* %dy, i32 %add19
116   %6 = load float, float* %arrayidx20, align 4
117   %arrayidx22 = getelementptr inbounds float, float* %dx, i32 %add19
118   %7 = load float, float* %arrayidx22, align 4
119   %mul23 = fmul float %7, %da
120   %add24 = fadd float %6, %mul23
121   store float %add24, float* %arrayidx20, align 4
122   %add27 = add nsw i32 %i.056, 4
123   %cmp = icmp slt i32 %add27, %n
124   br i1 %cmp, label %for.body, label %for.end
125
126 for.end:                                          ; preds = %for.body, %entry
127   ret void
128 }
129
130 ; CHECK-LABEL: @daxpy_ur
131 ; CHECK: for.body.preheader:
132 ; CHECK:   %0 = add i32 %n, -1
133 ; CHECK:   %1 = sub i32 %0, %rem
134 ; CHECK:   %2 = lshr i32 %1, 2
135 ; CHECK:   %3 = shl i32 %2, 2
136 ; CHECK:   %4 = add i32 %rem, %3
137 ; CHECK:   %5 = add i32 %4, 3
138 ; CHECK:   br label %for.body
139
140 ; CHECK: for.body:
141 ; CHECK:   %indvar = phi i32 [ %indvar.next, %for.body ], [ 0, %for.body.preheader ]
142 ; CHECK:   %6 = add i32 %rem, %indvar
143 ; CHECK:   %arrayidx = getelementptr inbounds float, float* %dy, i32 %6
144 ; CHECK:   %7 = load float, float* %arrayidx, align 4
145 ; CHECK:   %arrayidx1 = getelementptr inbounds float, float* %dx, i32 %6
146 ; CHECK:   %8 = load float, float* %arrayidx1, align 4
147 ; CHECK:   %mul = fmul float %8, %da
148 ; CHECK:   %add = fadd float %7, %mul
149 ; CHECK:   store float %add, float* %arrayidx, align 4
150 ; CHECK:   %indvar.next = add i32 %indvar, 1
151 ; CHECK:   %exitcond = icmp eq i32 %6, %5
152 ; CHECK:   br i1 %exitcond, label %for.end, label %for.body