diff --git a/lib/Transforms/Vectorize/LoopVectorize.cpp b/lib/Transforms/Vectorize/LoopVectorize.cpp index 491e9cc2480..ad4a6c7c419 100644 --- a/lib/Transforms/Vectorize/LoopVectorize.cpp +++ b/lib/Transforms/Vectorize/LoopVectorize.cpp @@ -216,7 +216,7 @@ private: /// This function adds 0, 1, 2 ... to each vector element, starting at zero. /// If Negate is set then negative numbers are added e.g. (0, -1, -2, ...). /// The sequence starts at StartIndex. - Value *getConsecutiveVector(Value* Val, unsigned StartIdx, bool Negate); + Value *getConsecutiveVector(Value* Val, int StartIdx, bool Negate); /// When we go over instructions in the basic block we rely on previous /// values within the current basic block or on loop invariant values. @@ -829,7 +829,7 @@ Value *InnerLoopVectorizer::getBroadcastInstrs(Value *V) { return Shuf; } -Value *InnerLoopVectorizer::getConsecutiveVector(Value* Val, unsigned StartIdx, +Value *InnerLoopVectorizer::getConsecutiveVector(Value* Val, int StartIdx, bool Negate) { assert(Val->getType()->isVectorTy() && "Must be a vector"); assert(Val->getType()->getScalarType()->isIntegerTy() && @@ -842,8 +842,8 @@ Value *InnerLoopVectorizer::getConsecutiveVector(Value* Val, unsigned StartIdx, // Create a vector of consecutive numbers from zero to VF. for (int i = 0; i < VLen; ++i) { - int Idx = Negate ? (-i): i; - Indices.push_back(ConstantInt::get(ITy, StartIdx + Idx)); + int64_t Idx = Negate ? (-i) : i; + Indices.push_back(ConstantInt::get(ITy, StartIdx + Idx, Negate)); } // Add the consecutive indices to the vector value. @@ -2072,7 +2072,8 @@ InnerLoopVectorizer::vectorizeBlockInLoop(LoopVectorizationLegality *Legal, // After broadcasting the induction variable we need to make the // vector consecutive by adding ... -3, -2, -1, 0. for (unsigned part = 0; part < UF; ++part) - Entry[part] = getConsecutiveVector(Broadcasted, -VF * part, true); + Entry[part] = getConsecutiveVector(Broadcasted, -(int)VF * part, + true); continue; } diff --git a/test/Transforms/LoopVectorize/reverse_induction.ll b/test/Transforms/LoopVectorize/reverse_induction.ll new file mode 100644 index 00000000000..f43f02bc313 --- /dev/null +++ b/test/Transforms/LoopVectorize/reverse_induction.ll @@ -0,0 +1,79 @@ +; RUN: opt < %s -loop-vectorize -force-vector-unroll=2 -force-vector-width=4 -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" + +; Make sure consecutive vector generates correct negative indices. +; PR15882 + +; CHECK: reverse_induction_i64 +; CHECK: add <4 x i64> %[[SPLAT:.*]], +; CHECK: add <4 x i64> %[[SPLAT]], + +define i32 @reverse_induction_i64(i64 %startval, i32 * %ptr) { +entry: + br label %for.body + +for.body: + %add.i7 = phi i64 [ %startval, %entry ], [ %add.i, %for.body ] + %i.06 = phi i32 [ 0, %entry ], [ %inc4, %for.body ] + %redux5 = phi i32 [ 0, %entry ], [ %inc.redux, %for.body ] + %add.i = add i64 %add.i7, -1 + %kind_.i = getelementptr inbounds i32* %ptr, i64 %add.i + %tmp.i1 = load i32* %kind_.i, align 4 + %inc.redux = add i32 %tmp.i1, %redux5 + %inc4 = add i32 %i.06, 1 + %exitcond = icmp ne i32 %inc4, 1024 + br i1 %exitcond, label %for.body, label %loopend + +loopend: + ret i32 %inc.redux +} + +; CHECK: reverse_induction_i128 +; CHECK: add <4 x i128> %[[SPLAT:.*]], +; CHECK: add <4 x i128> %[[SPLAT]], +define i32 @reverse_induction_i128(i128 %startval, i32 * %ptr) { +entry: + br label %for.body + +for.body: + %add.i7 = phi i128 [ %startval, %entry ], [ %add.i, %for.body ] + %i.06 = phi i32 [ 0, %entry ], [ %inc4, %for.body ] + %redux5 = phi i32 [ 0, %entry ], [ %inc.redux, %for.body ] + %add.i = add i128 %add.i7, -1 + %kind_.i = getelementptr inbounds i32* %ptr, i128 %add.i + %tmp.i1 = load i32* %kind_.i, align 4 + %inc.redux = add i32 %tmp.i1, %redux5 + %inc4 = add i32 %i.06, 1 + %exitcond = icmp ne i32 %inc4, 1024 + br i1 %exitcond, label %for.body, label %loopend + +loopend: + ret i32 %inc.redux +} + +; CHECK: reverse_induction_i16 +; CHECK: add <4 x i16> %[[SPLAT:.*]], +; CHECK: add <4 x i16> %[[SPLAT]], + +define i32 @reverse_induction_i16(i16 %startval, i32 * %ptr) { +entry: + br label %for.body + +for.body: + %add.i7 = phi i16 [ %startval, %entry ], [ %add.i, %for.body ] + %i.06 = phi i32 [ 0, %entry ], [ %inc4, %for.body ] + %redux5 = phi i32 [ 0, %entry ], [ %inc.redux, %for.body ] + %add.i = add i16 %add.i7, -1 + %kind_.i = getelementptr inbounds i32* %ptr, i16 %add.i + %tmp.i1 = load i32* %kind_.i, align 4 + %inc.redux = add i32 %tmp.i1, %redux5 + %inc4 = add i32 %i.06, 1 + %exitcond = icmp ne i32 %inc4, 1024 + br i1 %exitcond, label %for.body, label %loopend + +loopend: + ret i32 %inc.redux +} + +