diff options
-rw-r--r-- | lib/Transforms/Vectorize/LoopVectorize.cpp | 6 | ||||
-rw-r--r-- | test/Transforms/LoopVectorize/induction.ll | 42 |
2 files changed, 48 insertions, 0 deletions
diff --git a/lib/Transforms/Vectorize/LoopVectorize.cpp b/lib/Transforms/Vectorize/LoopVectorize.cpp index e624bb49f2..79f80f37ee 100644 --- a/lib/Transforms/Vectorize/LoopVectorize.cpp +++ b/lib/Transforms/Vectorize/LoopVectorize.cpp @@ -1537,6 +1537,7 @@ InnerLoopVectorizer::createEmptyLoop(LoopVectorizationLegality *Legal) { const SCEV *ExitCount = SE->getBackedgeTakenCount(OrigLoop); assert(ExitCount != SE->getCouldNotCompute() && "Invalid loop count"); + ExitCount = SE->getNoopOrZeroExtend(ExitCount, IdxTy); // Get the total trip count from the count by adding 1. ExitCount = SE->getAddExpr(ExitCount, SE->getConstant(ExitCount->getType(), 1)); @@ -2888,6 +2889,11 @@ static Type *convertPointerToIntegerType(DataLayout &DL, Type *Ty) { if (Ty->isPointerTy()) return DL.getIntPtrType(Ty); + // It is possible that char's or short's overflow when we ask for the loop's + // trip count, work around this by changing the type size. + if (Ty->getScalarSizeInBits() < 32) + return Type::getInt32Ty(Ty->getContext()); + return Ty; } diff --git a/test/Transforms/LoopVectorize/induction.ll b/test/Transforms/LoopVectorize/induction.ll index 2471c52ac2..50c3b6b6e7 100644 --- a/test/Transforms/LoopVectorize/induction.ll +++ b/test/Transforms/LoopVectorize/induction.ll @@ -66,3 +66,45 @@ for.body: loopexit: ret void } + + +; Make sure that the loop exit count computation does not overflow for i8 and +; i16. The exit count of these loops is i8/i16 max + 1. If we don't cast the +; induction variable to a bigger type the exit count computation will overflow +; to 0. +; PR17532 + +; CHECK-LABEL: i8_loop +; CHECK; icmp eq i32 {{.*}}, 256 +define i32 @i8_loop() nounwind readnone ssp uwtable { + br label %1 + +; <label>:1 ; preds = %1, %0 + %a.0 = phi i32 [ 1, %0 ], [ %2, %1 ] + %b.0 = phi i8 [ 0, %0 ], [ %3, %1 ] + %2 = and i32 %a.0, 4 + %3 = add i8 %b.0, -1 + %4 = icmp eq i8 %3, 0 + br i1 %4, label %5, label %1 + +; <label>:5 ; preds = %1 + ret i32 %2 +} + +; CHECK-LABEL: i16_loop +; CHECK; icmp eq i32 {{.*}}, 65536 + +define i32 @i16_loop() nounwind readnone ssp uwtable { + br label %1 + +; <label>:1 ; preds = %1, %0 + %a.0 = phi i32 [ 1, %0 ], [ %2, %1 ] + %b.0 = phi i16 [ 0, %0 ], [ %3, %1 ] + %2 = and i32 %a.0, 4 + %3 = add i16 %b.0, -1 + %4 = icmp eq i16 %3, 0 + br i1 %4, label %5, label %1 + +; <label>:5 ; preds = %1 + ret i32 %2 +} |