summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDaniel Sanders <daniel.sanders@imgtec.com>2013-12-09 12:47:12 +0000
committerDaniel Sanders <daniel.sanders@imgtec.com>2013-12-09 12:47:12 +0000
commit68138dc9a89cda52bdc7d27bbebec194809e93cf (patch)
tree6bc7e74e05815966ac88f6a1cf655389d03c3280 /lib
parent897268d931a84872d88ad05b18027b6b9723e03e (diff)
downloadllvm-68138dc9a89cda52bdc7d27bbebec194809e93cf.tar.gz
llvm-68138dc9a89cda52bdc7d27bbebec194809e93cf.tar.bz2
llvm-68138dc9a89cda52bdc7d27bbebec194809e93cf.tar.xz
[mips][msa] Fix invalid generated code when lowering FrameIndex involving unaligned offsets.
Summary: The MSA ld.[bhwd] and st.[bhwd] instructions scale the immediate by the element size before use as an offset. The offset must therefore be a multiple of the element size to be valid in these instructions. However, an unaligned base address is valid in MSA. This commit causes the compiler to emit valid code when the calculated offset is not a multiple of the element size by accounting for the offset using addiu and using a zero offset in the load/store. Depends on D2338 Reviewers: matheusalmeida Reviewed By: matheusalmeida Differential Revision: http://llvm-reviews.chandlerc.com/D2339 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@196777 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Target/Mips/MipsSERegisterInfo.cpp23
1 files changed, 21 insertions, 2 deletions
diff --git a/lib/Target/Mips/MipsSERegisterInfo.cpp b/lib/Target/Mips/MipsSERegisterInfo.cpp
index cf408a1c09..fcf6d0b06c 100644
--- a/lib/Target/Mips/MipsSERegisterInfo.cpp
+++ b/lib/Target/Mips/MipsSERegisterInfo.cpp
@@ -84,6 +84,23 @@ static inline unsigned getLoadStoreOffsetSizeInBits(const unsigned Opcode) {
}
}
+/// Get the scale factor applied to the immediate in the given load/store.
+static inline unsigned getLoadStoreOffsetAlign(const unsigned Opcode) {
+ switch (Opcode) {
+ case Mips::LD_H:
+ case Mips::ST_H:
+ return 2;
+ case Mips::LD_W:
+ case Mips::ST_W:
+ return 4;
+ case Mips::LD_D:
+ case Mips::ST_D:
+ return 8;
+ default:
+ return 1;
+ }
+}
+
void MipsSERegisterInfo::eliminateFI(MachineBasicBlock::iterator II,
unsigned OpNo, int FrameIndex,
uint64_t StackSize,
@@ -138,9 +155,11 @@ void MipsSERegisterInfo::eliminateFI(MachineBasicBlock::iterator II,
// For MSA instructions, this is a 10-bit signed immediate (scaled by
// element size), otherwise it is a 16-bit signed immediate.
unsigned OffsetBitSize = getLoadStoreOffsetSizeInBits(MI.getOpcode());
+ unsigned OffsetAlign = getLoadStoreOffsetAlign(MI.getOpcode());
- if (OffsetBitSize < 16 && !isIntN(OffsetBitSize, Offset) &&
- isInt<16>(Offset)) {
+ if (OffsetBitSize < 16 && isInt<16>(Offset) &&
+ (!isIntN(OffsetBitSize, Offset) ||
+ OffsetToAlignment(Offset, OffsetAlign) != 0)) {
// If we have an offset that needs to fit into a signed n-bit immediate
// (where n < 16) and doesn't, but does fit into 16-bits then use an ADDiu
MachineBasicBlock &MBB = *MI.getParent();