Add workaround for Cortex-M3 errata 602117 by replacing ldrd x, y, [x] with ldm or ldr pairs.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@144123 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Evan Cheng 2011-11-08 21:21:09 +00:00
parent 66dc8ca04b
commit 3568a1051e
2 changed files with 21 additions and 14 deletions

View File

@ -62,6 +62,7 @@ namespace {
const TargetInstrInfo *TII; const TargetInstrInfo *TII;
const TargetRegisterInfo *TRI; const TargetRegisterInfo *TRI;
const ARMSubtarget *STI;
ARMFunctionInfo *AFI; ARMFunctionInfo *AFI;
RegScavenger *RS; RegScavenger *RS;
bool isThumb2; bool isThumb2;
@ -1071,11 +1072,17 @@ bool ARMLoadStoreOpt::FixInvalidRegPairOp(MachineBasicBlock &MBB,
unsigned Opcode = MI->getOpcode(); unsigned Opcode = MI->getOpcode();
if (Opcode == ARM::LDRD || Opcode == ARM::STRD || if (Opcode == ARM::LDRD || Opcode == ARM::STRD ||
Opcode == ARM::t2LDRDi8 || Opcode == ARM::t2STRDi8) { Opcode == ARM::t2LDRDi8 || Opcode == ARM::t2STRDi8) {
const MachineOperand &BaseOp = MI->getOperand(2);
unsigned BaseReg = BaseOp.getReg();
unsigned EvenReg = MI->getOperand(0).getReg(); unsigned EvenReg = MI->getOperand(0).getReg();
unsigned OddReg = MI->getOperand(1).getReg(); unsigned OddReg = MI->getOperand(1).getReg();
unsigned EvenRegNum = TRI->getDwarfRegNum(EvenReg, false); unsigned EvenRegNum = TRI->getDwarfRegNum(EvenReg, false);
unsigned OddRegNum = TRI->getDwarfRegNum(OddReg, false); unsigned OddRegNum = TRI->getDwarfRegNum(OddReg, false);
if ((EvenRegNum & 1) == 0 && (EvenRegNum + 1) == OddRegNum) // ARM errata 602117: LDRD with base in list may result in incorrect base
// register when interrupted or faulted.
bool Errata602117 = EvenReg == BaseReg && STI->getCPUString() == "cortex-m3";
if (!Errata602117 &&
((EvenRegNum & 1) == 0 && (EvenRegNum + 1) == OddRegNum))
return false; return false;
MachineBasicBlock::iterator NewBBI = MBBI; MachineBasicBlock::iterator NewBBI = MBBI;
@ -1087,8 +1094,6 @@ bool ARMLoadStoreOpt::FixInvalidRegPairOp(MachineBasicBlock &MBB,
bool OddDeadKill = isLd ? bool OddDeadKill = isLd ?
MI->getOperand(1).isDead() : MI->getOperand(1).isKill(); MI->getOperand(1).isDead() : MI->getOperand(1).isKill();
bool OddUndef = MI->getOperand(1).isUndef(); bool OddUndef = MI->getOperand(1).isUndef();
const MachineOperand &BaseOp = MI->getOperand(2);
unsigned BaseReg = BaseOp.getReg();
bool BaseKill = BaseOp.isKill(); bool BaseKill = BaseOp.isKill();
bool BaseUndef = BaseOp.isUndef(); bool BaseUndef = BaseOp.isUndef();
bool OffKill = isT2 ? false : MI->getOperand(3).isKill(); bool OffKill = isT2 ? false : MI->getOperand(3).isKill();
@ -1380,6 +1385,7 @@ bool ARMLoadStoreOpt::runOnMachineFunction(MachineFunction &Fn) {
AFI = Fn.getInfo<ARMFunctionInfo>(); AFI = Fn.getInfo<ARMFunctionInfo>();
TII = TM.getInstrInfo(); TII = TM.getInstrInfo();
TRI = TM.getRegisterInfo(); TRI = TM.getRegisterInfo();
STI = &TM.getSubtarget<ARMSubtarget>();
RS = new RegScavenger(); RS = new RegScavenger();
isThumb2 = AFI->isThumb2Function(); isThumb2 = AFI->isThumb2Function();

View File

@ -1,21 +1,22 @@
; RUN: llc < %s -mtriple=armv6-apple-darwin -regalloc=linearscan | FileCheck %s -check-prefix=V6 ; RUN: llc < %s -mtriple=thumbv7-apple-ios -mcpu=cortex-a8 -regalloc=fast | FileCheck %s -check-prefix=A8
; RUN: llc < %s -mtriple=armv5-apple-darwin -regalloc=linearscan | FileCheck %s -check-prefix=V5 ; RUN: llc < %s -mtriple=thumbv7-apple-ios -mcpu=cortex-m3 -regalloc=fast | FileCheck %s -check-prefix=M3
; RUN: llc < %s -mtriple=armv6-eabi -regalloc=linearscan | FileCheck %s -check-prefix=EABI ; rdar://6949835
; rdar://r6949835
; Magic ARM pair hints works best with linearscan. ; 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* @b = external global i64*
define i64 @t(i64 %a) nounwind readonly { define i64 @t(i64 %a) nounwind readonly {
entry: entry:
;V6: ldrd r2, r3, [r2] ; A8: t:
; A8: ldrd r2, r3, [r2]
;V5: ldr r{{[0-9]+}}, [r2] ; M3: t:
;V5: ldr r{{[0-9]+}}, [r2, #4] ; M3-NOT: ldrd
; M3: ldm.w r2, {r2, r3}
;EABI: ldr r{{[0-9]+}}, [r2]
;EABI: ldr r{{[0-9]+}}, [r2, #4]
%0 = load i64** @b, align 4 %0 = load i64** @b, align 4
%1 = load i64* %0, align 4 %1 = load i64* %0, align 4