Index: include/llvm/Analysis/TargetTransformInfo.h =================================================================== --- include/llvm/Analysis/TargetTransformInfo.h +++ include/llvm/Analysis/TargetTransformInfo.h @@ -388,6 +388,10 @@ /// operations, shuffles, or casts. bool isFPVectorizationPotentiallyUnsafe() const; + /// \brief Indicate whether target allows misaligned memory accesses + bool allowsMisalignedMemoryAccesses(unsigned BitWidth, unsigned AddressSpace = 0, + unsigned Alignment = 1) const; + /// \brief Return hardware support for population count. PopcntSupportKind getPopcntSupport(unsigned IntTyWidthInBit) const; @@ -653,6 +657,9 @@ virtual bool enableAggressiveInterleaving(bool LoopHasReductions) = 0; virtual bool enableInterleavedAccessVectorization() = 0; virtual bool isFPVectorizationPotentiallyUnsafe() = 0; + virtual bool allowsMisalignedMemoryAccesses(unsigned BitWidth, + unsigned AddressSpace, + unsigned Alignment) = 0; virtual PopcntSupportKind getPopcntSupport(unsigned IntTyWidthInBit) = 0; virtual bool haveFastSqrt(Type *Ty) = 0; virtual int getFPOpCost(Type *Ty) = 0; @@ -820,6 +827,11 @@ bool isFPVectorizationPotentiallyUnsafe() override { return Impl.isFPVectorizationPotentiallyUnsafe(); } + bool allowsMisalignedMemoryAccesses(unsigned BitWidth, unsigned AddressSpace, + unsigned Alignment) override { + return Impl.allowsMisalignedMemoryAccesses(BitWidth, AddressSpace, + Alignment); + } PopcntSupportKind getPopcntSupport(unsigned IntTyWidthInBit) override { return Impl.getPopcntSupport(IntTyWidthInBit); } Index: include/llvm/Analysis/TargetTransformInfoImpl.h =================================================================== --- include/llvm/Analysis/TargetTransformInfoImpl.h +++ include/llvm/Analysis/TargetTransformInfoImpl.h @@ -244,6 +244,9 @@ bool isFPVectorizationPotentiallyUnsafe() { return false; } + bool allowsMisalignedMemoryAccesses(unsigned BitWidth, unsigned AddressSpace, + unsigned Alignment) { return false; } + TTI::PopcntSupportKind getPopcntSupport(unsigned IntTyWidthInBit) { return TTI::PSK_Software; } Index: include/llvm/CodeGen/BasicTTIImpl.h =================================================================== --- include/llvm/CodeGen/BasicTTIImpl.h +++ include/llvm/CodeGen/BasicTTIImpl.h @@ -105,6 +105,11 @@ /// \name Scalar TTI Implementations /// @{ + bool allowsMisalignedMemoryAccesses(unsigned BitWidth, unsigned AddressSpace, + unsigned Alignment) const { + MVT M = MVT::getIntegerVT(BitWidth); + return getTLI()->allowsMisalignedMemoryAccesses(M, AddressSpace, Alignment); + } bool hasBranchDivergence() { return false; } Index: lib/Analysis/TargetTransformInfo.cpp =================================================================== --- lib/Analysis/TargetTransformInfo.cpp +++ lib/Analysis/TargetTransformInfo.cpp @@ -181,6 +181,12 @@ return TTIImpl->isFPVectorizationPotentiallyUnsafe(); } +bool TargetTransformInfo::allowsMisalignedMemoryAccesses(unsigned BitWidth, + unsigned AddressSpace, + unsigned Alignment) const { + return TTIImpl->allowsMisalignedMemoryAccesses(BitWidth, AddressSpace, Alignment); +} + TargetTransformInfo::PopcntSupportKind TargetTransformInfo::getPopcntSupport(unsigned IntTyWidthInBit) const { return TTIImpl->getPopcntSupport(IntTyWidthInBit); Index: lib/Transforms/Vectorize/LoadStoreVectorizer.cpp =================================================================== --- lib/Transforms/Vectorize/LoadStoreVectorizer.cpp +++ lib/Transforms/Vectorize/LoadStoreVectorizer.cpp @@ -128,6 +128,9 @@ /// Vectorizes the store instructions in Chain. bool vectorizeStoreChain(ArrayRef Chain); + + /// Query target for allowed misaligned accesses + bool allowsMisaligned(unsigned SzInBytes, unsigned AddressSpace, unsigned Alignment); }; class LoadStoreVectorizer : public FunctionPass { @@ -155,14 +158,14 @@ } INITIALIZE_PASS_BEGIN(LoadStoreVectorizer, DEBUG_TYPE, - "Vectorize load and Store instructions", false, false); + "Vectorize load and Store instructions", false, false) INITIALIZE_PASS_DEPENDENCY(SCEVAAWrapperPass) INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass) INITIALIZE_PASS_DEPENDENCY(GlobalsAAWrapperPass) INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass) INITIALIZE_PASS_END(LoadStoreVectorizer, DEBUG_TYPE, - "Vectorize load and store instructions", false, false); + "Vectorize load and store instructions", false, false) char LoadStoreVectorizer::ID = 0; @@ -695,8 +698,9 @@ unsigned Alignment = getAlignment(S0); // If the store is going to be misaligned, don't vectorize it. - // TODO: Check TLI.allowsMisalignedMemoryAccess - if ((Alignment % SzInBytes) != 0 && (Alignment % TargetBaseAlign) != 0) { + // TODO: Remove TargetBaseAlign + if (allowsMisaligned(SzInBytes, AS, Alignment) == 0 && + (Alignment % SzInBytes) != 0 && (Alignment % TargetBaseAlign) != 0) { if (S0->getPointerAddressSpace() == 0) { // If we're storing to an object on the stack, we control its alignment, // so we can cheat and change it! @@ -823,8 +827,9 @@ unsigned Alignment = getAlignment(L0); // If the load is going to be misaligned, don't vectorize it. - // TODO: Check TLI.allowsMisalignedMemoryAccess and remove TargetBaseAlign. - if ((Alignment % SzInBytes) != 0 && (Alignment % TargetBaseAlign) != 0) { + // TODO: Remove TargetBaseAlign + if (allowsMisaligned(SzInBytes, AS, Alignment) == 0 && + (Alignment % SzInBytes) != 0 && (Alignment % TargetBaseAlign) != 0) { if (L0->getPointerAddressSpace() == 0) { // If we're loading from an object on the stack, we control its alignment, // so we can cheat and change it! @@ -917,3 +922,10 @@ NumScalarsVectorized += Chain.size(); return true; } + +bool Vectorizer::allowsMisaligned(unsigned SzInBytes, unsigned AddressSpace, + unsigned Alignment) { + return TTI.allowsMisalignedMemoryAccesses(SzInBytes*8, AddressSpace, + Alignment); +} +