LoopVectorizer: integer division is not a reduction operation

Don't classify idiv/udiv as a reduction operation. Integer division is lossy.
For example : (1 / 2) * 4 != 4/2.

Example:

int a[] = { 2, 5, 2, 2}
int x = 80;

for()
  x /= a[i];

Scalar:
  x /= 2 // = 40
  x /= 5 // = 8
  x /= 2 // = 4
  x /= 2 // = 2

Vectorized:

 <80, 1> / <2,5> //= <40,0>
 <40, 0> / <2,2> //= <20,0>

 20*0 = 0

radar://13640654

llvm-svn: 179381
This commit is contained in:
Arnold Schwaighofer 2013-04-12 15:15:19 +00:00
parent 755eb32a39
commit f9cea17f75
2 changed files with 24 additions and 2 deletions

View File

@ -2833,8 +2833,6 @@ LoopVectorizationLegality::isReductionInstr(Instruction *I,
case Instruction::Sub:
case Instruction::Add:
return Kind == RK_IntegerAdd;
case Instruction::SDiv:
case Instruction::UDiv:
case Instruction::Mul:
return Kind == RK_IntegerMult;
case Instruction::And:

View File

@ -0,0 +1,24 @@
; RUN: opt -loop-vectorize -force-vector-width=2 -force-vector-unroll=1 -S < %s | FileCheck %s
@a = common global [128 x i32] zeroinitializer, align 16
;; Must not vectorize division reduction. Division is lossy.
define i32 @g() {
entry:
br label %for.body
for.body:
; CHECK: @g
; CHECK-NOT: sdiv <2 x i32>
%indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
%r.05 = phi i32 [ 80, %entry ], [ %div, %for.body ]
%arrayidx = getelementptr inbounds [128 x i32]* @a, i64 0, i64 %indvars.iv
%0 = load i32* %arrayidx, align 4
%div = sdiv i32 %r.05, %0
%indvars.iv.next = add i64 %indvars.iv, 1
%lftr.wideiv = trunc i64 %indvars.iv.next to i32
%exitcond = icmp eq i32 %lftr.wideiv, 1024
br i1 %exitcond, label %for.end, label %for.body
for.end:
ret i32 %div
}