From 07a3c481c656c9cc1e0ace3d599eef1fa81e3cc6 Mon Sep 17 00:00:00 2001 From: Arnold Schwaighofer Date: Mon, 18 Nov 2013 13:14:32 +0000 Subject: [PATCH] LoopVectorizer: Extend the induction variable to a larger type In some case the loop exit count computation can overflow. Extend the type to prevent most of those cases. The problem is loops like: int main () { int a = 1; char b = 0; lbl: a &= 4; b--; if (b) goto lbl; return a; } The backedge count is 255. The induction variable type is i8. If we add one to 255 to get the exit count we overflow to zero. To work around this issue we extend the type of the induction variable to i32 in the case of i8 and i16. PR17532 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@195008 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/Vectorize/LoopVectorize.cpp | 6 ++++ test/Transforms/LoopVectorize/induction.ll | 42 ++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/lib/Transforms/Vectorize/LoopVectorize.cpp b/lib/Transforms/Vectorize/LoopVectorize.cpp index e624bb49f2a..79f80f37eea 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 2471c52ac24..50c3b6b6e79 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 + +;