summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorKrzysztof Parzyszek <kparzysz@codeaurora.org>2016-08-02 18:34:31 +0000
committerKrzysztof Parzyszek <kparzysz@codeaurora.org>2016-08-02 18:34:31 +0000
commita4e94ebbb2e2d3f220dca37a09a409a5c98f12d4 (patch)
tree4eb3b3d378274da5c0da06c30e3abec15ecc321f /lib
parentc37e7b92f8f38665202f28706203aa757ce922cd (diff)
[Hexagon] Improvements to address mode checks in TargetLowering
- Implement getOptimalMemOpType. - Check BaseOffset in isLegalAddressingMode. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@277494 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Target/Hexagon/HexagonISelLowering.cpp37
-rw-r--r--lib/Target/Hexagon/HexagonISelLowering.h4
2 files changed, 39 insertions, 2 deletions
diff --git a/lib/Target/Hexagon/HexagonISelLowering.cpp b/lib/Target/Hexagon/HexagonISelLowering.cpp
index 0f614ddf58a..692e13af789 100644
--- a/lib/Target/Hexagon/HexagonISelLowering.cpp
+++ b/lib/Target/Hexagon/HexagonISelLowering.cpp
@@ -3055,8 +3055,12 @@ bool HexagonTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT) const {
bool HexagonTargetLowering::isLegalAddressingMode(const DataLayout &DL,
const AddrMode &AM, Type *Ty,
unsigned AS) const {
- // Allows a signed-extended 11-bit immediate field.
- if (AM.BaseOffs <= -(1LL << 13) || AM.BaseOffs >= (1LL << 13)-1)
+ unsigned A = DL.getABITypeAlignment(Ty);
+ // The base offset must be a multiple of the alignment.
+ if ((AM.BaseOffs % A) != 0)
+ return false;
+ // The shifted offset must fit in 11 bits.
+ if (!isInt<11>(AM.BaseOffs >> Log2_32(A)))
return false;
// No global is ever allowed as a base.
@@ -3139,6 +3143,35 @@ bool HexagonTargetLowering::IsEligibleForTailCallOptimization(
return true;
}
+/// Returns the target specific optimal type for load and store operations as
+/// a result of memset, memcpy, and memmove lowering.
+///
+/// If DstAlign is zero that means it's safe to destination alignment can
+/// satisfy any constraint. Similarly if SrcAlign is zero it means there isn't
+/// a need to check it against alignment requirement, probably because the
+/// source does not need to be loaded. If 'IsMemset' is true, that means it's
+/// expanding a memset. If 'ZeroMemset' is true, that means it's a memset of
+/// zero. 'MemcpyStrSrc' indicates whether the memcpy source is constant so it
+/// does not need to be loaded. It returns EVT::Other if the type should be
+/// determined using generic target-independent logic.
+EVT HexagonTargetLowering::getOptimalMemOpType(uint64_t Size,
+ unsigned DstAlign, unsigned SrcAlign, bool IsMemset, bool ZeroMemset,
+ bool MemcpyStrSrc, MachineFunction &MF) const {
+
+ auto Aligned = [](unsigned GivenA, unsigned MinA) -> bool {
+ return (GivenA % MinA) == 0;
+ };
+
+ if (Size >= 8 && Aligned(DstAlign, 8) && (IsMemset || Aligned(SrcAlign, 8)))
+ return MVT::i64;
+ if (Size >= 4 && Aligned(DstAlign, 4) && (IsMemset || Aligned(SrcAlign, 4)))
+ return MVT::i32;
+ if (Size >= 2 && Aligned(DstAlign, 2) && (IsMemset || Aligned(SrcAlign, 2)))
+ return MVT::i16;
+
+ return MVT::Other;
+}
+
// Return true when the given node fits in a positive half word.
bool llvm::isPositiveHalfWord(SDNode *N) {
ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N);
diff --git a/lib/Target/Hexagon/HexagonISelLowering.h b/lib/Target/Hexagon/HexagonISelLowering.h
index 5291a8737e2..e940a37076b 100644
--- a/lib/Target/Hexagon/HexagonISelLowering.h
+++ b/lib/Target/Hexagon/HexagonISelLowering.h
@@ -247,6 +247,10 @@ bool isPositiveHalfWord(SDNode *N);
/// the immediate into a register.
bool isLegalICmpImmediate(int64_t Imm) const override;
+ EVT getOptimalMemOpType(uint64_t Size, unsigned DstAlign,
+ unsigned SrcAlign, bool IsMemset, bool ZeroMemset, bool MemcpyStrSrc,
+ MachineFunction &MF) const override;
+
bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AddrSpace,
unsigned Align, bool *Fast) const override;