summaryrefslogtreecommitdiff
path: root/test/Transforms
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2014-05-11 18:24:26 +0000
committerDimitry Andric <dim@FreeBSD.org>2014-05-11 18:24:26 +0000
commit68bcb7db193e4bc81430063148253d30a791023e (patch)
tree9f9245264c66971905eab3af40b7fc82e38fc2ad /test/Transforms
parent512b84fc6c12bc496cef739e69bfaaf27e7ccc8e (diff)
Notes
Diffstat (limited to 'test/Transforms')
-rw-r--r--test/Transforms/InstCombine/vec_extract_var_elt.ll8
-rw-r--r--test/Transforms/LoopReroll/basic.ll10
-rw-r--r--test/Transforms/LoopReroll/nonconst_lb.ll152
-rw-r--r--test/Transforms/LoopReroll/reduction.ll4
-rw-r--r--test/Transforms/LoopStrengthReduce/X86/pr17473.ll67
-rw-r--r--test/Transforms/LoopStrengthReduce/pr18165.ll88
-rw-r--r--test/Transforms/LoopVectorize/multi-use-reduction-bug.ll42
7 files changed, 364 insertions, 7 deletions
diff --git a/test/Transforms/InstCombine/vec_extract_var_elt.ll b/test/Transforms/InstCombine/vec_extract_var_elt.ll
index 3c982873e288..f6f9e0134a16 100644
--- a/test/Transforms/InstCombine/vec_extract_var_elt.ll
+++ b/test/Transforms/InstCombine/vec_extract_var_elt.ll
@@ -16,3 +16,11 @@ define void @test (float %b, <8 x float> * %p) {
ret void
}
+; PR18600
+define i32 @test2(i32 %i) {
+ %e = extractelement <4 x i32> bitcast (<2 x i64> <i64 1, i64 2> to <4 x i32>), i32 %i
+ ret i32 %e
+
+; CHECK-LABEL: @test2
+; CHECK: extractelement
+}
diff --git a/test/Transforms/LoopReroll/basic.ll b/test/Transforms/LoopReroll/basic.ll
index 314a14947e3e..3bd6d7ae02e1 100644
--- a/test/Transforms/LoopReroll/basic.ll
+++ b/test/Transforms/LoopReroll/basic.ll
@@ -33,7 +33,7 @@ for.body: ; preds = %for.body, %entry
; CHECK: %indvar = phi i32 [ %indvar.next, %for.body ], [ 0, %entry ]
; CHECK: %call = tail call i32 @foo(i32 %indvar) #1
; CHECK: %indvar.next = add i32 %indvar, 1
-; CHECK: %exitcond1 = icmp eq i32 %indvar.next, 498
+; CHECK: %exitcond1 = icmp eq i32 %indvar, 497
; CHECK: br i1 %exitcond1, label %for.end, label %for.body
; CHECK: ret
@@ -83,7 +83,7 @@ for.body: ; preds = %entry, %for.body
; CHECK: %arrayidx = getelementptr inbounds i32* %x, i64 %indvar
; CHECK: store i32 %call, i32* %arrayidx, align 4
; CHECK: %indvar.next = add i64 %indvar, 1
-; CHECK: %exitcond = icmp eq i64 %indvar.next, 1500
+; CHECK: %exitcond = icmp eq i64 %indvar, 1499
; CHECK: br i1 %exitcond, label %for.end, label %for.body
; CHECK: ret
@@ -131,7 +131,7 @@ for.body: ; preds = %for.body, %entry
; CHECK: %arrayidx = getelementptr inbounds i32* %x, i64 %indvars.iv
; CHECK: store i32 %call, i32* %arrayidx, align 4
; CHECK: %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
-; CHECK: %exitcond1 = icmp eq i64 %indvars.iv.next, 1500
+; CHECK: %exitcond1 = icmp eq i64 %indvars.iv, 1499
; CHECK: br i1 %exitcond1, label %for.end, label %for.body
; CHECK: ret
@@ -213,7 +213,7 @@ for.body: ; preds = %entry, %for.body
; CHECK: %add = fadd float %1, %mul
; CHECK: store float %add, float* %arrayidx2, align 4
; CHECK: %indvar.next = add i64 %indvar, 1
-; CHECK: %exitcond = icmp eq i64 %indvar.next, 3200
+; CHECK: %exitcond = icmp eq i64 %indvar, 3199
; CHECK: br i1 %exitcond, label %for.end, label %for.body
; CHECK: ret
@@ -313,7 +313,7 @@ for.body: ; preds = %entry, %for.body
; CHECK: %add = fadd float %2, %mul
; CHECK: store float %add, float* %arrayidx4, align 4
; CHECK: %indvar.next = add i64 %indvar, 1
-; CHECK: %exitcond = icmp eq i64 %indvar.next, 3200
+; CHECK: %exitcond = icmp eq i64 %indvar, 3199
; CHECK: br i1 %exitcond, label %for.end, label %for.body
; CHECK: ret
diff --git a/test/Transforms/LoopReroll/nonconst_lb.ll b/test/Transforms/LoopReroll/nonconst_lb.ll
new file mode 100644
index 000000000000..a45469bd2393
--- /dev/null
+++ b/test/Transforms/LoopReroll/nonconst_lb.ll
@@ -0,0 +1,152 @@
+; RUN: opt < %s -loop-reroll -S | FileCheck %s
+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"
+target triple = "thumbv7-none-linux"
+
+;void foo(int *A, int *B, int m, int n) {
+; for (int i = m; i < n; i+=4) {
+; A[i+0] = B[i+0] * 4;
+; A[i+1] = B[i+1] * 4;
+; A[i+2] = B[i+2] * 4;
+; A[i+3] = B[i+3] * 4;
+; }
+;}
+define void @foo(i32* nocapture %A, i32* nocapture readonly %B, i32 %m, i32 %n) {
+entry:
+ %cmp34 = icmp slt i32 %m, %n
+ br i1 %cmp34, label %for.body, label %for.end
+
+for.body: ; preds = %entry, %for.body
+ %i.035 = phi i32 [ %add18, %for.body ], [ %m, %entry ]
+ %arrayidx = getelementptr inbounds i32* %B, i32 %i.035
+ %0 = load i32* %arrayidx, align 4
+ %mul = shl nsw i32 %0, 2
+ %arrayidx2 = getelementptr inbounds i32* %A, i32 %i.035
+ store i32 %mul, i32* %arrayidx2, align 4
+ %add3 = add nsw i32 %i.035, 1
+ %arrayidx4 = getelementptr inbounds i32* %B, i32 %add3
+ %1 = load i32* %arrayidx4, align 4
+ %mul5 = shl nsw i32 %1, 2
+ %arrayidx7 = getelementptr inbounds i32* %A, i32 %add3
+ store i32 %mul5, i32* %arrayidx7, align 4
+ %add8 = add nsw i32 %i.035, 2
+ %arrayidx9 = getelementptr inbounds i32* %B, i32 %add8
+ %2 = load i32* %arrayidx9, align 4
+ %mul10 = shl nsw i32 %2, 2
+ %arrayidx12 = getelementptr inbounds i32* %A, i32 %add8
+ store i32 %mul10, i32* %arrayidx12, align 4
+ %add13 = add nsw i32 %i.035, 3
+ %arrayidx14 = getelementptr inbounds i32* %B, i32 %add13
+ %3 = load i32* %arrayidx14, align 4
+ %mul15 = shl nsw i32 %3, 2
+ %arrayidx17 = getelementptr inbounds i32* %A, i32 %add13
+ store i32 %mul15, i32* %arrayidx17, align 4
+ %add18 = add nsw i32 %i.035, 4
+ %cmp = icmp slt i32 %add18, %n
+ br i1 %cmp, label %for.body, label %for.end
+
+for.end: ; preds = %for.body, %entry
+ ret void
+}
+; CHECK-LABEL: @foo
+; CHECK: for.body.preheader: ; preds = %entry
+; CHECK: %0 = add i32 %n, -1
+; CHECK: %1 = sub i32 %0, %m
+; CHECK: %2 = lshr i32 %1, 2
+; CHECK: %3 = mul i32 %2, 4
+; CHECK: %4 = add i32 %m, %3
+; CHECK: %5 = add i32 %4, 3
+; CHECK: br label %for.body
+
+; CHECK: for.body: ; preds = %for.body, %for.body.preheader
+; CHECK: %indvar = phi i32 [ %indvar.next, %for.body ], [ 0, %for.body.preheader ]
+; CHECK: %6 = add i32 %m, %indvar
+; CHECK: %arrayidx = getelementptr inbounds i32* %B, i32 %6
+; CHECK: %7 = load i32* %arrayidx, align 4
+; CHECK: %mul = shl nsw i32 %7, 2
+; CHECK: %arrayidx2 = getelementptr inbounds i32* %A, i32 %6
+; CHECK: store i32 %mul, i32* %arrayidx2, align 4
+; CHECK: %indvar.next = add i32 %indvar, 1
+; CHECK: %exitcond = icmp eq i32 %6, %5
+; CHECK: br i1 %exitcond, label %for.end, label %for.body
+
+;void daxpy_ur(int n,float da,float *dx,float *dy)
+; {
+; int m = n % 4;
+; for (int i = m; i < n; i = i + 4)
+; {
+; dy[i] = dy[i] + da*dx[i];
+; dy[i+1] = dy[i+1] + da*dx[i+1];
+; dy[i+2] = dy[i+2] + da*dx[i+2];
+; dy[i+3] = dy[i+3] + da*dx[i+3];
+; }
+; }
+define void @daxpy_ur(i32 %n, float %da, float* nocapture readonly %dx, float* nocapture %dy) {
+entry:
+ %rem = srem i32 %n, 4
+ %cmp55 = icmp slt i32 %rem, %n
+ br i1 %cmp55, label %for.body, label %for.end
+
+for.body: ; preds = %entry, %for.body
+ %i.056 = phi i32 [ %add27, %for.body ], [ %rem, %entry ]
+ %arrayidx = getelementptr inbounds float* %dy, i32 %i.056
+ %0 = load float* %arrayidx, align 4
+ %arrayidx1 = getelementptr inbounds float* %dx, i32 %i.056
+ %1 = load float* %arrayidx1, align 4
+ %mul = fmul float %1, %da
+ %add = fadd float %0, %mul
+ store float %add, float* %arrayidx, align 4
+ %add3 = add nsw i32 %i.056, 1
+ %arrayidx4 = getelementptr inbounds float* %dy, i32 %add3
+ %2 = load float* %arrayidx4, align 4
+ %arrayidx6 = getelementptr inbounds float* %dx, i32 %add3
+ %3 = load float* %arrayidx6, align 4
+ %mul7 = fmul float %3, %da
+ %add8 = fadd float %2, %mul7
+ store float %add8, float* %arrayidx4, align 4
+ %add11 = add nsw i32 %i.056, 2
+ %arrayidx12 = getelementptr inbounds float* %dy, i32 %add11
+ %4 = load float* %arrayidx12, align 4
+ %arrayidx14 = getelementptr inbounds float* %dx, i32 %add11
+ %5 = load float* %arrayidx14, align 4
+ %mul15 = fmul float %5, %da
+ %add16 = fadd float %4, %mul15
+ store float %add16, float* %arrayidx12, align 4
+ %add19 = add nsw i32 %i.056, 3
+ %arrayidx20 = getelementptr inbounds float* %dy, i32 %add19
+ %6 = load float* %arrayidx20, align 4
+ %arrayidx22 = getelementptr inbounds float* %dx, i32 %add19
+ %7 = load float* %arrayidx22, align 4
+ %mul23 = fmul float %7, %da
+ %add24 = fadd float %6, %mul23
+ store float %add24, float* %arrayidx20, align 4
+ %add27 = add nsw i32 %i.056, 4
+ %cmp = icmp slt i32 %add27, %n
+ br i1 %cmp, label %for.body, label %for.end
+
+for.end: ; preds = %for.body, %entry
+ ret void
+}
+
+; CHECK-LABEL: @daxpy_ur
+; CHECK: for.body.preheader:
+; CHECK: %0 = add i32 %n, -1
+; CHECK: %1 = sub i32 %0, %rem
+; CHECK: %2 = lshr i32 %1, 2
+; CHECK: %3 = mul i32 %2, 4
+; CHECK: %4 = add i32 %rem, %3
+; CHECK: %5 = add i32 %4, 3
+; CHECK: br label %for.body
+
+; CHECK: for.body:
+; CHECK: %indvar = phi i32 [ %indvar.next, %for.body ], [ 0, %for.body.preheader ]
+; CHECK: %6 = add i32 %rem, %indvar
+; CHECK: %arrayidx = getelementptr inbounds float* %dy, i32 %6
+; CHECK: %7 = load float* %arrayidx, align 4
+; CHECK: %arrayidx1 = getelementptr inbounds float* %dx, i32 %6
+; CHECK: %8 = load float* %arrayidx1, align 4
+; CHECK: %mul = fmul float %8, %da
+; CHECK: %add = fadd float %7, %mul
+; CHECK: store float %add, float* %arrayidx, align 4
+; CHECK: %indvar.next = add i32 %indvar, 1
+; CHECK: %exitcond = icmp eq i32 %6, %5
+; CHECK: br i1 %exitcond, label %for.end, label %for.body
diff --git a/test/Transforms/LoopReroll/reduction.ll b/test/Transforms/LoopReroll/reduction.ll
index aed7670b666d..c9991c723ec6 100644
--- a/test/Transforms/LoopReroll/reduction.ll
+++ b/test/Transforms/LoopReroll/reduction.ll
@@ -38,7 +38,7 @@ for.body: ; preds = %entry, %for.body
; CHECK: %0 = load i32* %arrayidx, align 4
; CHECK: %add = add nsw i32 %0, %r.029
; CHECK: %indvar.next = add i64 %indvar, 1
-; CHECK: %exitcond = icmp eq i64 %indvar.next, 400
+; CHECK: %exitcond = icmp eq i64 %indvar, 399
; CHECK: br i1 %exitcond, label %for.end, label %for.body
; CHECK: ret
@@ -83,7 +83,7 @@ for.body: ; preds = %entry, %for.body
; CHECK: %0 = load float* %arrayidx, align 4
; CHECK: %add = fadd float %0, %r.029
; CHECK: %indvar.next = add i64 %indvar, 1
-; CHECK: %exitcond = icmp eq i64 %indvar.next, 400
+; CHECK: %exitcond = icmp eq i64 %indvar, 399
; CHECK: br i1 %exitcond, label %for.end, label %for.body
; CHECK: ret
diff --git a/test/Transforms/LoopStrengthReduce/X86/pr17473.ll b/test/Transforms/LoopStrengthReduce/X86/pr17473.ll
new file mode 100644
index 000000000000..4204abc7ca22
--- /dev/null
+++ b/test/Transforms/LoopStrengthReduce/X86/pr17473.ll
@@ -0,0 +1,67 @@
+; RUN: opt < %s -loop-reduce -S | FileCheck %s
+
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128-n8:16:32-S128"
+target triple = "x86_64-apple-macosx10.9.0"
+
+; LSR shouldn't normalize IV if it can't be denormalized to the original
+; expression. In this testcase, the normalized expression was denormalized to
+; an expression different from the original, and we were losing sign extension.
+
+; CHECK: [[TMP:%[a-z]+]] = trunc i32 {{.*}} to i8
+; CHECK: {{%[a-z0-9]+}} = sext i8 [[TMP]] to i32
+
+@j = common global i32 0, align 4
+@c = common global i32 0, align 4
+@g = common global i32 0, align 4
+@h = common global i8 0, align 1
+@d = common global i32 0, align 4
+@i = common global i32 0, align 4
+@e = common global i32 0, align 4
+@.str = private unnamed_addr constant [4 x i8] c"%x\0A\00", align 1
+@a = common global i32 0, align 4
+@b = common global i16 0, align 2
+
+; Function Attrs: nounwind optsize ssp uwtable
+define i32 @main() #0 {
+entry:
+ store i8 0, i8* @h, align 1
+ %0 = load i32* @j, align 4
+ %tobool.i = icmp eq i32 %0, 0
+ %1 = load i32* @d, align 4
+ %cmp3 = icmp sgt i32 %1, -1
+ %.lobit = lshr i32 %1, 31
+ %.lobit.not = xor i32 %.lobit, 1
+ br label %for.body
+
+for.body: ; preds = %entry, %fn3.exit
+ %inc9 = phi i8 [ 0, %entry ], [ %inc, %fn3.exit ]
+ %conv = sext i8 %inc9 to i32
+ br i1 %tobool.i, label %fn3.exit, label %land.rhs.i
+
+land.rhs.i: ; preds = %for.body
+ store i32 0, i32* @c, align 4
+ br label %fn3.exit
+
+fn3.exit: ; preds = %for.body, %land.rhs.i
+ %inc = add i8 %inc9, 1
+ %cmp = icmp sgt i8 %inc, -1
+ br i1 %cmp, label %for.body, label %for.end
+
+for.end: ; preds = %fn3.exit
+ %.lobit.not. = select i1 %cmp3, i32 %.lobit.not, i32 0
+ store i32 %conv, i32* @g, align 4
+ store i32 %.lobit.not., i32* @i, align 4
+ store i8 %inc, i8* @h, align 1
+ %conv7 = sext i8 %inc to i32
+ %add = add nsw i32 %conv7, %conv
+ store i32 %add, i32* @e, align 4
+ %call = tail call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), i32 %add) #2
+ ret i32 0
+}
+
+; Function Attrs: nounwind optsize
+declare i32 @printf(i8* nocapture readonly, ...) #1
+
+attributes #0 = { nounwind optsize ssp uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #1 = { nounwind optsize "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #2 = { nounwind optsize }
diff --git a/test/Transforms/LoopStrengthReduce/pr18165.ll b/test/Transforms/LoopStrengthReduce/pr18165.ll
new file mode 100644
index 000000000000..89adef7bd49d
--- /dev/null
+++ b/test/Transforms/LoopStrengthReduce/pr18165.ll
@@ -0,0 +1,88 @@
+; RUN: opt < %s -loop-reduce -S | FileCheck %s
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128-n8:16:32-S128"
+target triple = "x86_64-apple-macosx10.9.0"
+
+; LSR shouldn't reuse IV if the resultant offset is not valid for the operand type.
+; CHECK-NOT: trunc i32 %.ph to i8
+
+%struct.anon = type { i32, i32, i32 }
+
+@c = global i32 1, align 4
+@.str = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1
+@b = common global i32 0, align 4
+@a = common global %struct.anon zeroinitializer, align 4
+@e = common global %struct.anon zeroinitializer, align 4
+@d = common global i32 0, align 4
+@f = common global i32 0, align 4
+@g = common global i32 0, align 4
+@h = common global i32 0, align 4
+
+; Function Attrs: nounwind optsize ssp uwtable
+define i32 @main() #0 {
+entry:
+ %0 = load i32* getelementptr inbounds (%struct.anon* @a, i64 0, i32 0), align 4, !tbaa !1
+ %tobool7.i = icmp eq i32 %0, 0
+ %.promoted.i = load i32* getelementptr inbounds (%struct.anon* @a, i64 0, i32 2), align 4, !tbaa !6
+ %f.promoted.i = load i32* @f, align 4, !tbaa !7
+ br label %for.body6.i.outer
+
+for.body6.i.outer: ; preds = %entry, %lor.end.i
+ %.ph = phi i32 [ %add.i, %lor.end.i ], [ 0, %entry ]
+ %or1512.i.ph = phi i32 [ %or15.i, %lor.end.i ], [ %f.promoted.i, %entry ]
+ %or1410.i.ph = phi i32 [ %or14.i, %lor.end.i ], [ %.promoted.i, %entry ]
+ %p.addr.16.i.ph = phi i8 [ %inc10.i, %lor.end.i ], [ -128, %entry ]
+ br i1 %tobool7.i, label %if.end9.i, label %lbl.loopexit.i
+
+lbl.loopexit.i: ; preds = %for.body6.i.outer, %lbl.loopexit.i
+ br label %lbl.loopexit.i
+
+if.end9.i: ; preds = %for.body6.i.outer
+ %inc10.i = add i8 %p.addr.16.i.ph, 1
+ %tobool12.i = icmp eq i8 %p.addr.16.i.ph, 0
+ br i1 %tobool12.i, label %lor.rhs.i, label %lor.end.i
+
+lor.rhs.i: ; preds = %if.end9.i
+ %1 = load i32* @b, align 4, !tbaa !7
+ %dec.i = add nsw i32 %1, -1
+ store i32 %dec.i, i32* @b, align 4, !tbaa !7
+ %tobool13.i = icmp ne i32 %1, 0
+ br label %lor.end.i
+
+lor.end.i: ; preds = %lor.rhs.i, %if.end9.i
+ %2 = phi i1 [ true, %if.end9.i ], [ %tobool13.i, %lor.rhs.i ]
+ %lor.ext.i = zext i1 %2 to i32
+ %or14.i = or i32 %lor.ext.i, %or1410.i.ph
+ %or15.i = or i32 %or14.i, %or1512.i.ph
+ %add.i = add nsw i32 %.ph, 2
+ %cmp.i = icmp slt i32 %add.i, 21
+ br i1 %cmp.i, label %for.body6.i.outer, label %fn1.exit
+
+fn1.exit: ; preds = %lor.end.i
+ store i32 0, i32* @g, align 4, !tbaa !7
+ store i32 %or14.i, i32* getelementptr inbounds (%struct.anon* @a, i64 0, i32 2), align 4, !tbaa !6
+ store i32 %or15.i, i32* @f, align 4, !tbaa !7
+ store i32 %add.i, i32* getelementptr inbounds (%struct.anon* @e, i64 0, i32 1), align 4, !tbaa !8
+ store i32 0, i32* @h, align 4, !tbaa !7
+ %3 = load i32* @b, align 4, !tbaa !7
+ %call1 = tail call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), i32 %3) #2
+ ret i32 0
+}
+
+; Function Attrs: nounwind optsize
+declare i32 @printf(i8* nocapture readonly, ...) #1
+
+attributes #0 = { nounwind optsize ssp uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #1 = { nounwind optsize "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #2 = { nounwind optsize }
+
+!llvm.ident = !{!0}
+
+!0 = metadata !{metadata !"clang version 3.5 "}
+!1 = metadata !{metadata !2, metadata !3, i64 0}
+!2 = metadata !{metadata !"", metadata !3, i64 0, metadata !3, i64 4, metadata !3, i64 8}
+!3 = metadata !{metadata !"int", metadata !4, i64 0}
+!4 = metadata !{metadata !"omnipotent char", metadata !5, i64 0}
+!5 = metadata !{metadata !"Simple C/C++ TBAA"}
+!6 = metadata !{metadata !2, metadata !3, i64 8}
+!7 = metadata !{metadata !3, metadata !3, i64 0}
+!8 = metadata !{metadata !2, metadata !3, i64 4}
diff --git a/test/Transforms/LoopVectorize/multi-use-reduction-bug.ll b/test/Transforms/LoopVectorize/multi-use-reduction-bug.ll
new file mode 100644
index 000000000000..5fc5ed55a99d
--- /dev/null
+++ b/test/Transforms/LoopVectorize/multi-use-reduction-bug.ll
@@ -0,0 +1,42 @@
+; RUN: opt -indvars -loop-vectorize -force-vector-width=2 -force-vector-unroll=1 -S < %s | FileCheck %s
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-apple-macosx10.9.0"
+
+; We must not vectorize this loop. %add55 is not reduction. Its value is used
+; multiple times.
+
+; PR18526
+
+; CHECK: multiple_use_of_value
+; CHECK-NOT: <2 x i32>
+
+define void @multiple_use_of_value() {
+entry:
+ %n = alloca i32, align 4
+ %k7 = alloca i32, align 4
+ %nf = alloca i32, align 4
+ %0 = load i32* %k7, align 4
+ %.neg1 = sub i32 0, %0
+ %n.promoted = load i32* %n, align 4
+ %nf.promoted = load i32* %nf, align 4
+ br label %for.body
+
+for.body:
+ %inc107 = phi i32 [ undef, %entry ], [ %inc10, %for.body ]
+ %inc6 = phi i32 [ %nf.promoted, %entry ], [ undef, %for.body ]
+ %add55 = phi i32 [ %n.promoted, %entry ], [ %add5, %for.body ]
+ %.neg2 = sub i32 0, %inc6
+ %add.neg = add i32 0, %add55
+ %add4.neg = add i32 %add.neg, %.neg1
+ %sub = add i32 %add4.neg, %.neg2
+ %add5 = add i32 %sub, %add55
+ %inc10 = add i32 %inc107, 1
+ %cmp = icmp ult i32 %inc10, 61
+ br i1 %cmp, label %for.body, label %for.end
+
+for.end:
+ %add5.lcssa = phi i32 [ %add5, %for.body ]
+ store i32 %add5.lcssa, i32* %n, align 4
+ ret void
+}