From 9f3979fd782dc823cc0cdf38c69a14812e5254a8 Mon Sep 17 00:00:00 2001 From: David Majnemer Date: Sat, 27 Jun 2015 08:38:17 +0000 Subject: [PATCH] [LoopVectorize] Pointer indicies may be wider than the pointer If we are dealing with a pointer induction variable, isInductionPHI gives back a step value of Stride / size of pointer. However, we might be indexing with a legal type wider than the pointer width. Handle this by inserting casts where appropriate instead of crashing. This fixes PR23954. llvm-svn: 240877 --- llvm/lib/Transforms/Vectorize/LoopVectorize.cpp | 13 ++++++++++--- .../Transforms/LoopVectorize/X86/ptr-indvar-crash.ll | 20 ++++++++++++++++++++ 2 files changed, 30 insertions(+), 3 deletions(-) create mode 100644 llvm/test/Transforms/LoopVectorize/X86/ptr-indvar-crash.ll diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp index 49b07da..eff7c03 100644 --- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp +++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp @@ -850,6 +850,8 @@ public: return B.CreateAdd(StartValue, Index); case IK_PtrInduction: + assert(Index->getType() == StepValue->getType() && + "Index type does not match StepValue type"); if (StepValue->isMinusOne()) Index = B.CreateNeg(Index); else if (!StepValue->isOne()) @@ -2798,7 +2800,10 @@ void InnerLoopVectorizer::createEmptyLoop() { break; } case LoopVectorizationLegality::IK_PtrInduction: { - EndValue = II.transform(BypassBuilder, CountRoundDown); + Value *CRD = BypassBuilder.CreateSExtOrTrunc(CountRoundDown, + II.StepValue->getType(), + "cast.crd"); + EndValue = II.transform(BypassBuilder, CRD); EndValue->setName("ptr.ind.end"); break; } @@ -3448,12 +3453,14 @@ void InnerLoopVectorizer::widenPHIInstruction(Instruction *PN, // This is the normalized GEP that starts counting at zero. Value *NormalizedIdx = Builder.CreateSub(Induction, ExtendedIdx, "normalized.idx"); + NormalizedIdx = + Builder.CreateSExtOrTrunc(NormalizedIdx, II.StepValue->getType()); // This is the vector of results. Notice that we don't generate // vector geps because scalar geps result in better code. for (unsigned part = 0; part < UF; ++part) { if (VF == 1) { int EltIndex = part; - Constant *Idx = ConstantInt::get(Induction->getType(), EltIndex); + Constant *Idx = ConstantInt::get(NormalizedIdx->getType(), EltIndex); Value *GlobalIdx = Builder.CreateAdd(NormalizedIdx, Idx); Value *SclrGep = II.transform(Builder, GlobalIdx); SclrGep->setName("next.gep"); @@ -3464,7 +3471,7 @@ void InnerLoopVectorizer::widenPHIInstruction(Instruction *PN, Value *VecVal = UndefValue::get(VectorType::get(P->getType(), VF)); for (unsigned int i = 0; i < VF; ++i) { int EltIndex = i + part * VF; - Constant *Idx = ConstantInt::get(Induction->getType(), EltIndex); + Constant *Idx = ConstantInt::get(NormalizedIdx->getType(), EltIndex); Value *GlobalIdx = Builder.CreateAdd(NormalizedIdx, Idx); Value *SclrGep = II.transform(Builder, GlobalIdx); SclrGep->setName("next.gep"); diff --git a/llvm/test/Transforms/LoopVectorize/X86/ptr-indvar-crash.ll b/llvm/test/Transforms/LoopVectorize/X86/ptr-indvar-crash.ll new file mode 100644 index 0000000..56ea2f4 --- /dev/null +++ b/llvm/test/Transforms/LoopVectorize/X86/ptr-indvar-crash.ll @@ -0,0 +1,20 @@ +; RUN: opt -slp-vectorizer -S %s + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +define void @f(i128 %p1) { +entry: + br label %while.body + +while.body: + %p.05 = phi i8* [ %add.ptr, %while.body ], [ null, %entry ] + %p1.addr.04 = phi i128 [ %sub, %while.body ], [ %p1, %entry ] + %add.ptr = getelementptr inbounds i8, i8* %p.05, i32 2 + %sub = add nsw i128 %p1.addr.04, -2 + %tobool = icmp eq i128 %sub, 0 + br i1 %tobool, label %while.end, label %while.body + +while.end: + ret void +} -- 2.7.4