mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-09-23 17:28:54 +00:00
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:
@@ -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.
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
Reference in New Issue
Block a user