From 5767d919569f7b4be51c0a13bff24f722625d9f3 Mon Sep 17 00:00:00 2001 From: Paul Redmond Date: Fri, 4 Jan 2013 22:10:16 +0000 Subject: [PATCH] Do not vectorize loops with subtraction reductions Since subtraction does not commute the loop vectorizer incorrectly vectorizes reductions such as x = A[i] - x. Disabling for now. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@171537 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/Vectorize/LoopVectorize.cpp | 1 - test/Transforms/LoopVectorize/gcc-examples.ll | 2 +- test/Transforms/LoopVectorize/reduction.ll | 50 +++++++++++++++++++ 3 files changed, 51 insertions(+), 2 deletions(-) diff --git a/lib/Transforms/Vectorize/LoopVectorize.cpp b/lib/Transforms/Vectorize/LoopVectorize.cpp index 4e508988e33..5e2d7971f84 100644 --- a/lib/Transforms/Vectorize/LoopVectorize.cpp +++ b/lib/Transforms/Vectorize/LoopVectorize.cpp @@ -1986,7 +1986,6 @@ LoopVectorizationLegality::isReductionInstr(Instruction *I, // possibly. return true; case Instruction::Add: - case Instruction::Sub: return Kind == IntegerAdd; case Instruction::Mul: return Kind == IntegerMult; diff --git a/test/Transforms/LoopVectorize/gcc-examples.ll b/test/Transforms/LoopVectorize/gcc-examples.ll index 652c2a0d025..e52a3f164a3 100644 --- a/test/Transforms/LoopVectorize/gcc-examples.ll +++ b/test/Transforms/LoopVectorize/gcc-examples.ll @@ -241,7 +241,7 @@ define void @example8(i32 %x) nounwind uwtable ssp { } ;CHECK: @example9 -;CHECK: phi <4 x i32> +;CHECK-NOT: phi <4 x i32> ;CHECK: ret i32 define i32 @example9() nounwind uwtable readonly ssp { br label %1 diff --git a/test/Transforms/LoopVectorize/reduction.ll b/test/Transforms/LoopVectorize/reduction.ll index bc1c0290dec..91fc9538772 100644 --- a/test/Transforms/LoopVectorize/reduction.ll +++ b/test/Transforms/LoopVectorize/reduction.ll @@ -270,3 +270,53 @@ for.end: ; preds = %for.body, %entry %result.0.lcssa = phi i32 [ 0, %entry ], [ %xor, %for.body ] ret i32 %result.0.lcssa } + +;CHECK: @reduction_sub_rhs +;CHECK-NOT: phi <4 x i32> +;CHECK-NOT: sub nsw <4 x i32> +;CHECK: ret i32 +define i32 @reduction_sub_rhs(i32 %n, i32* noalias nocapture %A) nounwind uwtable readonly { +entry: + %cmp3 = icmp sgt i32 %n, 0 + br i1 %cmp3, label %for.body, label %for.end + +for.body: ; preds = %entry, %for.body + %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ 0, %entry ] + %x.04 = phi i32 [ %sub, %for.body ], [ 0, %entry ] + %arrayidx = getelementptr inbounds i32* %A, i64 %indvars.iv + %0 = load i32* %arrayidx, align 4 + %sub = sub nsw i32 %x.04, %0 + %indvars.iv.next = add i64 %indvars.iv, 1 + %lftr.wideiv = trunc i64 %indvars.iv.next to i32 + %exitcond = icmp eq i32 %lftr.wideiv, %n + br i1 %exitcond, label %for.end, label %for.body + +for.end: ; preds = %for.body, %entry + %x.0.lcssa = phi i32 [ 0, %entry ], [ %sub, %for.body ] + ret i32 %x.0.lcssa +} + +;CHECK: @reduction_sub_lhs +;CHECK-NOT: phi <4 x i32> +;CHECK-NOT: sub nsw <4 x i32> +;CHECK: ret i32 +define i32 @reduction_sub_lhs(i32 %n, i32* noalias nocapture %A) nounwind uwtable readonly { +entry: + %cmp4 = icmp sgt i32 %n, 0 + br i1 %cmp4, label %for.body, label %for.end + +for.body: ; preds = %entry, %for.body + %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ 0, %entry ] + %x.05 = phi i32 [ %sub, %for.body ], [ 0, %entry ] + %arrayidx = getelementptr inbounds i32* %A, i64 %indvars.iv + %0 = load i32* %arrayidx, align 4 + %sub = sub nsw i32 %0, %x.05 + %indvars.iv.next = add i64 %indvars.iv, 1 + %lftr.wideiv = trunc i64 %indvars.iv.next to i32 + %exitcond = icmp eq i32 %lftr.wideiv, %n + br i1 %exitcond, label %for.end, label %for.body + +for.end: ; preds = %for.body, %entry + %x.0.lcssa = phi i32 [ 0, %entry ], [ %sub, %for.body ] + ret i32 %x.0.lcssa +}