Index: include/llvm/Analysis/TargetTransformInfo.h =================================================================== --- include/llvm/Analysis/TargetTransformInfo.h +++ include/llvm/Analysis/TargetTransformInfo.h @@ -388,6 +388,9 @@ /// operations, shuffles, or casts. bool isFPVectorizationPotentiallyUnsafe() const; + /// \brief Indicate whether target allows misaligned memory accesses + bool allowsMisalignedMemoryAccesses(unsigned BitWidth) const; + /// \brief Return hardware support for population count. PopcntSupportKind getPopcntSupport(unsigned IntTyWidthInBit) const; @@ -653,6 +656,7 @@ virtual bool enableAggressiveInterleaving(bool LoopHasReductions) = 0; virtual bool enableInterleavedAccessVectorization() = 0; virtual bool isFPVectorizationPotentiallyUnsafe() = 0; + virtual bool allowsMisalignedMemoryAccesses(unsigned BitWidth) = 0; virtual PopcntSupportKind getPopcntSupport(unsigned IntTyWidthInBit) = 0; virtual bool haveFastSqrt(Type *Ty) = 0; virtual int getFPOpCost(Type *Ty) = 0; @@ -820,6 +824,9 @@ bool isFPVectorizationPotentiallyUnsafe() override { return Impl.isFPVectorizationPotentiallyUnsafe(); } + bool allowsMisalignedMemoryAccesses(unsigned BitWidth) override { + return Impl.allowsMisalignedMemoryAccesses(BitWidth); + } 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,8 @@ bool isFPVectorizationPotentiallyUnsafe() { return false; } + bool allowsMisalignedMemoryAccesses(unsigned BitWidth) { 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,10 @@ /// \name Scalar TTI Implementations /// @{ + bool allowsMisalignedMemoryAccesses(unsigned BitWidth) const { + MVT M = MVT::getIntegerVT(BitWidth); + return getTLI()->allowsMisalignedMemoryAccesses(M); + } bool hasBranchDivergence() { return false; } Index: lib/Analysis/TargetTransformInfo.cpp =================================================================== --- lib/Analysis/TargetTransformInfo.cpp +++ lib/Analysis/TargetTransformInfo.cpp @@ -181,6 +181,10 @@ return TTIImpl->isFPVectorizationPotentiallyUnsafe(); } +bool TargetTransformInfo::allowsMisalignedMemoryAccesses(unsigned BitWidth) const { + return TTIImpl->allowsMisalignedMemoryAccesses(BitWidth); +} + 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); }; 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; @@ -694,8 +697,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) == 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! @@ -822,8 +826,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) == 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! @@ -916,3 +921,8 @@ NumScalarsVectorized += Chain.size(); return true; } + +bool Vectorizer::allowsMisaligned(unsigned SzInBytes) { + return TTI.allowsMisalignedMemoryAccesses(SzInBytes*8); +} +