diff options
author | Chandler Carruth <chandlerc@gmail.com> | 2012-10-15 10:24:40 +0000 |
---|---|---|
committer | Chandler Carruth <chandlerc@gmail.com> | 2012-10-15 10:24:40 +0000 |
commit | 94fc64c42fe27aa16dd5611eb3657ff0297801c8 (patch) | |
tree | ad6b5f27e03ea0c56e668476967d4ca145abdbe7 /lib/Transforms/Scalar | |
parent | bb1078ea1370fd0cc32f52b1b53f0b245ded42e7 (diff) | |
download | external_llvm-94fc64c42fe27aa16dd5611eb3657ff0297801c8.zip external_llvm-94fc64c42fe27aa16dd5611eb3657ff0297801c8.tar.gz external_llvm-94fc64c42fe27aa16dd5611eb3657ff0297801c8.tar.bz2 |
Follow-up fix to r165928: handle memset rewriting for widened integers,
and generally clean up the memset handling. It had rotted a bit as the
other rewriting logic got polished more.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@165930 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/Scalar')
-rw-r--r-- | lib/Transforms/Scalar/SROA.cpp | 55 |
1 files changed, 25 insertions, 30 deletions
diff --git a/lib/Transforms/Scalar/SROA.cpp b/lib/Transforms/Scalar/SROA.cpp index a2267d0..419756d 100644 --- a/lib/Transforms/Scalar/SROA.cpp +++ b/lib/Transforms/Scalar/SROA.cpp @@ -2591,10 +2591,11 @@ private: // If this doesn't map cleanly onto the alloca type, and that type isn't // a single value type, just emit a memset. - if (!VecTy && (BeginOffset != NewAllocaBeginOffset || - EndOffset != NewAllocaEndOffset || - !AllocaTy->isSingleValueType() || - !TD.isLegalInteger(TD.getTypeSizeInBits(ScalarTy)))) { + if (!VecTy && !IntTy && + (BeginOffset != NewAllocaBeginOffset || + EndOffset != NewAllocaEndOffset || + !AllocaTy->isSingleValueType() || + !TD.isLegalInteger(TD.getTypeSizeInBits(ScalarTy)))) { Type *SizeTy = II.getLength()->getType(); Constant *Size = ConstantInt::get(SizeTy, EndOffset - BeginOffset); CallInst *New @@ -2612,32 +2613,24 @@ private: // a sensible representation for the alloca type. This is essentially // splatting the byte to a sufficiently wide integer, bitcasting to the // desired scalar type, and splatting it across any desired vector type. + uint64_t Size = EndOffset - BeginOffset; Value *V = II.getValue(); IntegerType *VTy = cast<IntegerType>(V->getType()); - Type *IntTy = Type::getIntNTy(VTy->getContext(), - TD.getTypeSizeInBits(ScalarTy)); - if (TD.getTypeSizeInBits(ScalarTy) > VTy->getBitWidth()) - V = IRB.CreateMul(IRB.CreateZExt(V, IntTy, getName(".zext")), + Type *SplatIntTy = Type::getIntNTy(VTy->getContext(), Size*8); + if (Size*8 > VTy->getBitWidth()) + V = IRB.CreateMul(IRB.CreateZExt(V, SplatIntTy, getName(".zext")), ConstantExpr::getUDiv( - Constant::getAllOnesValue(IntTy), + Constant::getAllOnesValue(SplatIntTy), ConstantExpr::getZExt( Constant::getAllOnesValue(V->getType()), - IntTy)), + SplatIntTy)), getName(".isplat")); - if (V->getType() != ScalarTy) { - if (ScalarTy->isPointerTy()) - V = IRB.CreateIntToPtr(V, ScalarTy); - else if (ScalarTy->isPrimitiveType() || ScalarTy->isVectorTy()) - V = IRB.CreateBitCast(V, ScalarTy); - else if (ScalarTy->isIntegerTy()) - llvm_unreachable("Computed different integer types with equal widths"); - else - llvm_unreachable("Invalid scalar type"); - } // If this is an element-wide memset of a vectorizable alloca, insert it. if (VecTy && (BeginOffset > NewAllocaBeginOffset || EndOffset < NewAllocaEndOffset)) { + if (V->getType() != ScalarTy) + V = convertValue(TD, IRB, V, ScalarTy); StoreInst *Store = IRB.CreateAlignedStore( IRB.CreateInsertElement(IRB.CreateAlignedLoad(&NewAI, NewAI.getAlignment(), @@ -2650,18 +2643,20 @@ private: return true; } - // Splat to a vector if needed. - if (VectorType *VecTy = dyn_cast<VectorType>(AllocaTy)) { - VectorType *SplatSourceTy = VectorType::get(V->getType(), 1); - V = IRB.CreateShuffleVector( - IRB.CreateInsertElement(UndefValue::get(SplatSourceTy), V, - IRB.getInt32(0), getName(".vsplat.insert")), - UndefValue::get(SplatSourceTy), - ConstantVector::getSplat(VecTy->getNumElements(), IRB.getInt32(0)), - getName(".vsplat.shuffle")); - assert(V->getType() == VecTy); + // If this is a memset on an alloca where we can widen stores, insert the + // set integer. + if (IntTy && (BeginOffset > NewAllocaBeginOffset || + EndOffset < NewAllocaEndOffset)) { + assert(!II.isVolatile()); + StoreInst *Store = insertInteger(IRB, V, BeginOffset); + (void)Store; + DEBUG(dbgs() << " to: " << *Store << "\n"); + return true; } + if (V->getType() != AllocaTy) + V = convertValue(TD, IRB, V, AllocaTy); + Value *New = IRB.CreateAlignedStore(V, &NewAI, NewAI.getAlignment(), II.isVolatile()); (void)New; |