diff options
author | Chad Rosier <mcrosier@apple.com> | 2012-12-06 01:34:31 +0000 |
---|---|---|
committer | Chad Rosier <mcrosier@apple.com> | 2012-12-06 01:34:31 +0000 |
commit | c9758b13668013dea491a08b4f0c9256263927c2 (patch) | |
tree | 813ac800e09bb18d6b8ac41959f33e4fd83c25df /lib | |
parent | 8a7186dbc2df4879f511b2ae6f2bce25ad37d965 (diff) | |
download | external_llvm-c9758b13668013dea491a08b4f0c9256263927c2.zip external_llvm-c9758b13668013dea491a08b4f0c9256263927c2.tar.gz external_llvm-c9758b13668013dea491a08b4f0c9256263927c2.tar.bz2 |
[arm fast-isel] Make the fast-isel implementation of memcpy respect alignment.
rdar://12821569
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@169460 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Target/ARM/ARMFastISel.cpp | 33 |
1 files changed, 22 insertions, 11 deletions
diff --git a/lib/Target/ARM/ARMFastISel.cpp b/lib/Target/ARM/ARMFastISel.cpp index 23d372c..21bb147 100644 --- a/lib/Target/ARM/ARMFastISel.cpp +++ b/lib/Target/ARM/ARMFastISel.cpp @@ -186,7 +186,8 @@ class ARMFastISel : public FastISel { bool ARMComputeAddress(const Value *Obj, Address &Addr); void ARMSimplifyAddress(Address &Addr, EVT VT, bool useAM3); bool ARMIsMemCpySmall(uint64_t Len); - bool ARMTryEmitSmallMemCpy(Address Dest, Address Src, uint64_t Len); + bool ARMTryEmitSmallMemCpy(Address Dest, Address Src, uint64_t Len, + unsigned Alignment); unsigned ARMEmitIntExt(EVT SrcVT, unsigned SrcReg, EVT DestVT, bool isZExt); unsigned ARMMaterializeFP(const ConstantFP *CFP, EVT VT); unsigned ARMMaterializeInt(const Constant *C, EVT VT); @@ -2422,21 +2423,30 @@ bool ARMFastISel::ARMIsMemCpySmall(uint64_t Len) { } bool ARMFastISel::ARMTryEmitSmallMemCpy(Address Dest, Address Src, - uint64_t Len) { + uint64_t Len, unsigned Alignment) { // Make sure we don't bloat code by inlining very large memcpy's. if (!ARMIsMemCpySmall(Len)) return false; - // We don't care about alignment here since we just emit integer accesses. while (Len) { MVT VT; - if (Len >= 4) - VT = MVT::i32; - else if (Len >= 2) - VT = MVT::i16; - else { - assert(Len == 1); - VT = MVT::i8; + if (!Alignment || Alignment >= 4) { + if (Len >= 4) + VT = MVT::i32; + else if (Len >= 2) + VT = MVT::i16; + else { + assert (Len == 1 && "Expected a length of 1!"); + VT = MVT::i8; + } + } else { + // Bound based on alignment. + if (Len >= 2 && Alignment == 2) + VT = MVT::i16; + else { + assert (Alignment == 1 && "Expected an alignment of 1!"); + VT = MVT::i8; + } } bool RV; @@ -2515,7 +2525,8 @@ bool ARMFastISel::SelectIntrinsicCall(const IntrinsicInst &I) { if (!ARMComputeAddress(MTI.getRawDest(), Dest) || !ARMComputeAddress(MTI.getRawSource(), Src)) return false; - if (ARMTryEmitSmallMemCpy(Dest, Src, Len)) + unsigned Alignment = MTI.getAlignment(); + if (ARMTryEmitSmallMemCpy(Dest, Src, Len, Alignment)) return true; } } |