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: ; 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; } 83define void @daxpy_ur(i32 %n, float %da, float* nocapture readonly %dx, float* nocapture %dy) { 84entry: 85 %rem = srem i32 %n, 4 86 %cmp55 = icmp slt i32 %rem, %n 87 br i1 %cmp55, label %for.body, label %for.end 88 89for.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 126for.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 153