ARMLoadStoreOptimizer: Fix errata 602117 handling and make testcase actually test for it

This fixes PR23912

Differential Revision: http://reviews.llvm.org/D10620

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@240582 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Matthias Braun
2015-06-24 20:03:27 +00:00
parent a3af347f38
commit 7d46df3626
3 changed files with 129 additions and 123 deletions

View File

@@ -1464,18 +1464,25 @@ bool ARMLoadStoreOpt::FixInvalidRegPairOp(MachineBasicBlock &MBB,
MachineBasicBlock::iterator &MBBI) {
MachineInstr *MI = &*MBBI;
unsigned Opcode = MI->getOpcode();
if (Opcode == ARM::LDRD || Opcode == ARM::STRD) {
if (Opcode != ARM::LDRD && Opcode != ARM::STRD && Opcode != ARM::t2LDRDi8)
return false;
const MachineOperand &BaseOp = MI->getOperand(2);
unsigned BaseReg = BaseOp.getReg();
unsigned EvenReg = MI->getOperand(0).getReg();
unsigned OddReg = MI->getOperand(1).getReg();
unsigned EvenRegNum = TRI->getDwarfRegNum(EvenReg, false);
unsigned OddRegNum = TRI->getDwarfRegNum(OddReg, false);
// ARM errata 602117: LDRD with base in list may result in incorrect base
// register when interrupted or faulted.
bool Errata602117 = EvenReg == BaseReg && STI->isCortexM3();
if (!Errata602117 &&
((EvenRegNum & 1) == 0 && (EvenRegNum + 1) == OddRegNum))
bool Errata602117 = EvenReg == BaseReg &&
(Opcode == ARM::LDRD || Opcode == ARM::t2LDRDi8) && STI->isCortexM3();
// ARM LDRD/STRD needs consecutive registers.
bool NonConsecutiveRegs = (Opcode == ARM::LDRD || Opcode == ARM::STRD) &&
(EvenRegNum % 2 != 0 || EvenRegNum + 1 != OddRegNum);
if (!Errata602117 && !NonConsecutiveRegs)
return false;
MachineBasicBlock::iterator NewBBI = MBBI;
@@ -1576,8 +1583,6 @@ bool ARMLoadStoreOpt::FixInvalidRegPairOp(MachineBasicBlock &MBB,
MBBI = NewBBI;
return true;
}
return false;
}
/// An optimization pass to turn multiple LDR / STR ops of the same base and
/// incrementing offset into LDM / STM ops.

View File

@@ -6,23 +6,24 @@
; Magic ARM pair hints works best with linearscan / fast.
; Cortex-M3 errata 602117: LDRD with base in list may result in incorrect base
; register when interrupted or faulted.
@b = external global i64*
define i64 @t(i64 %a) nounwind readonly {
entry:
; A8-LABEL: t:
; A8: ldrd r2, r3, [r2]
; We use the following two to force values into specific registers.
declare i64* @get_ptr()
declare void @use_i64(i64 %v)
; M3-LABEL: t:
; M3-NOT: ldrd
%0 = load i64*, i64** @b, align 4
%1 = load i64, i64* %0, align 4
%2 = mul i64 %1, %a
ret i64 %2
define void @test_ldrd(i64 %a) nounwind readonly {
; CHECK-LABEL: test_ldrd:
; CHECK: bl{{x?}} _get_ptr
; A8: ldrd r0, r1, [r0]
; Cortex-M3 errata 602117: LDRD with base in list may result in incorrect base
; register when interrupted or faulted.
; M3-NOT: ldrd r[[REGNUM:[0-9]+]], {{r[0-9]+}}, [r[[REGNUM]]]
; CHECK: bl{{x?}} _use_i64
%ptr = call i64* @get_ptr()
%v = load i64, i64* %ptr, align 8
call void @use_i64(i64 %v)
ret void
}
; rdar://10435045 mixed LDRi8/LDRi12

View File

@@ -109,7 +109,7 @@ entry:
define double @load_d(double* %a) {
entry:
; CHECK-LABEL: load_d:
; NONE: ldrd r0, r1, [r0]
; NONE: ldm r0, {r0, r1}
; HARD: vldr d0, [r0]
%0 = load double, double* %a, align 8
ret double %0