mirror of
https://github.com/RPCSX/llvm.git
synced 2024-12-04 10:04:33 +00:00
Add pseudo instructions to the XCore for (load|store|load address) of a
frame index. eliminateFrameIndex will replace these instructions with (LDWSP|STWSP|LDAWSP) or (LDW|STW|LDAWF) if a frame pointer is in use. This fixes PR 3324. Previously we used LDWSP, STWSP, LDAWSP before frame pointer elimination. However since they were marked as implicitly using SP they could not be rematerialised. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@62238 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
a8c78a9e89
commit
29cab5f0ee
@ -77,7 +77,7 @@ bool XCoreInstrInfo::isMoveInstr(const MachineInstr &MI,
|
||||
unsigned
|
||||
XCoreInstrInfo::isLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const{
|
||||
int Opcode = MI->getOpcode();
|
||||
if (Opcode == XCore::LDWSP_ru6 || Opcode == XCore::LDWSP_lru6)
|
||||
if (Opcode == XCore::LDWFI)
|
||||
{
|
||||
if ((MI->getOperand(1).isFI()) && // is a stack slot
|
||||
(MI->getOperand(2).isImm()) && // the imm is zero
|
||||
@ -99,19 +99,11 @@ unsigned
|
||||
XCoreInstrInfo::isStoreToStackSlot(const MachineInstr *MI,
|
||||
int &FrameIndex) const {
|
||||
int Opcode = MI->getOpcode();
|
||||
if (Opcode == XCore::STWSP_ru6 || Opcode == XCore::STWSP_lru6)
|
||||
if (Opcode == XCore::STWFI)
|
||||
{
|
||||
if ((MI->getOperand(1).isFI()) && // is a stack slot
|
||||
(MI->getOperand(2).isImm()) && // the imm is zero
|
||||
(isZeroImm(MI->getOperand(2))))
|
||||
{
|
||||
FrameIndex = MI->getOperand(1).getIndex();
|
||||
return MI->getOperand(0).getReg();
|
||||
}
|
||||
}
|
||||
else if (Opcode == XCore::STWSP_ru6_2 || Opcode == XCore::STWSP_lru6_2)
|
||||
{
|
||||
if (MI->getOperand(1).isFI())
|
||||
(isZeroImm(MI->getOperand(2))))
|
||||
{
|
||||
FrameIndex = MI->getOperand(1).getIndex();
|
||||
return MI->getOperand(0).getReg();
|
||||
@ -387,8 +379,8 @@ void XCoreInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
|
||||
unsigned SrcReg, bool isKill, int FrameIndex,
|
||||
const TargetRegisterClass *RC) const
|
||||
{
|
||||
BuildMI(MBB, I, get(XCore::STWSP_lru6)).addReg(SrcReg, false, false, isKill)
|
||||
.addFrameIndex(FrameIndex).addImm(0);
|
||||
BuildMI(MBB, I, get(XCore::STWFI)).addReg(SrcReg, false, false, isKill)
|
||||
.addFrameIndex(FrameIndex).addImm(0);
|
||||
}
|
||||
|
||||
void XCoreInstrInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg,
|
||||
@ -404,8 +396,8 @@ void XCoreInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
|
||||
unsigned DestReg, int FrameIndex,
|
||||
const TargetRegisterClass *RC) const
|
||||
{
|
||||
BuildMI(MBB, I, get(XCore::LDWSP_lru6), DestReg).addFrameIndex(FrameIndex)
|
||||
.addImm(0);
|
||||
BuildMI(MBB, I, get(XCore::LDWFI), DestReg).addFrameIndex(FrameIndex)
|
||||
.addImm(0);
|
||||
}
|
||||
|
||||
void XCoreInstrInfo::loadRegFromAddr(MachineFunction &MF, unsigned DestReg,
|
||||
|
@ -349,6 +349,18 @@ def ADJCALLSTACKUP : PseudoInstXCore<(outs), (ins i32imm:$amt1, i32imm:$amt2),
|
||||
[(callseq_end timm:$amt1, timm:$amt2)]>;
|
||||
}
|
||||
|
||||
def LDWFI : PseudoInstXCore<(outs GRRegs:$dst), (ins MEMii:$addr),
|
||||
"${:comment} LDWFI $dst, $addr",
|
||||
[(set GRRegs:$dst, (load ADDRspii:$addr))]>;
|
||||
|
||||
def LDAWFI : PseudoInstXCore<(outs GRRegs:$dst), (ins MEMii:$addr),
|
||||
"${:comment} LDAWFI $dst, $addr",
|
||||
[(set GRRegs:$dst, ADDRspii:$addr)]>;
|
||||
|
||||
def STWFI : PseudoInstXCore<(outs), (ins GRRegs:$src, MEMii:$addr),
|
||||
"${:comment} STWFI $src, $addr",
|
||||
[(store GRRegs:$src, ADDRspii:$addr)]>;
|
||||
|
||||
// SELECT_CC_* - Used to implement the SELECT_CC DAG operation. Expanded by the
|
||||
// scheduler into a branch sequence.
|
||||
let usesCustomDAGSchedInserter = 1 in {
|
||||
@ -543,51 +555,41 @@ let mayLoad = 1, isReMaterializable = 1 in
|
||||
defm LDWCP : FRU6_LRU6_cp<"ldw">;
|
||||
|
||||
let Uses = [SP] in {
|
||||
let mayStore=1 in
|
||||
let mayStore=1 in {
|
||||
def STWSP_ru6 : _FRU6<
|
||||
(outs), (ins GRRegs:$dst, MEMii:$b),
|
||||
"stw $dst, sp[$b]",
|
||||
[]>;
|
||||
(outs), (ins GRRegs:$val, i32imm:$index),
|
||||
"stw $val, sp[$index]",
|
||||
[(XCoreStwsp GRRegs:$val, immU6:$index)]>;
|
||||
|
||||
def STWSP_lru6 : _FLRU6<
|
||||
(outs), (ins GRRegs:$dst, MEMii:$b),
|
||||
"stw $dst, sp[$b]",
|
||||
[(store GRRegs:$dst, ADDRspii:$b)]>;
|
||||
(outs), (ins GRRegs:$val, i32imm:$index),
|
||||
"stw $val, sp[$index]",
|
||||
[(XCoreStwsp GRRegs:$val, immU16:$index)]>;
|
||||
}
|
||||
|
||||
let mayStore=1 in
|
||||
def STWSP_ru6_2 : _FRU6<
|
||||
(outs), (ins GRRegs:$dst, i32imm:$b),
|
||||
"stw $dst, sp[$b]",
|
||||
[]>;
|
||||
|
||||
def STWSP_lru6_2 : _FLRU6<
|
||||
(outs), (ins GRRegs:$dst, i32imm:$b),
|
||||
"stw $dst, sp[$b]",
|
||||
[(store GRRegs:$dst, ADDRspii:$b)]>;
|
||||
|
||||
let mayLoad=1 in
|
||||
let mayLoad=1 in {
|
||||
def LDWSP_ru6 : _FRU6<
|
||||
(outs GRRegs:$dst), (ins MEMii:$b),
|
||||
(outs GRRegs:$dst), (ins i32imm:$b),
|
||||
"ldw $dst, sp[$b]",
|
||||
[]>;
|
||||
|
||||
def LDWSP_lru6 : _FLRU6<
|
||||
(outs GRRegs:$dst), (ins MEMii:$b),
|
||||
(outs GRRegs:$dst), (ins i32imm:$b),
|
||||
"ldw $dst, sp[$b]",
|
||||
[(set GRRegs:$dst, (load ADDRspii:$b))]>;
|
||||
[]>;
|
||||
}
|
||||
|
||||
let neverHasSideEffects = 1 in
|
||||
let neverHasSideEffects = 1 in {
|
||||
def LDAWSP_ru6 : _FRU6<
|
||||
(outs GRRegs:$dst), (ins MEMii:$b),
|
||||
(outs GRRegs:$dst), (ins i32imm:$b),
|
||||
"ldaw $dst, sp[$b]",
|
||||
[]>;
|
||||
|
||||
def LDAWSP_lru6 : _FLRU6<
|
||||
(outs GRRegs:$dst), (ins MEMii:$b),
|
||||
(outs GRRegs:$dst), (ins i32imm:$b),
|
||||
"ldaw $dst, sp[$b]",
|
||||
[(set GRRegs: $dst, ADDRspii:$b)]>;
|
||||
[]>;
|
||||
|
||||
let neverHasSideEffects = 1 in {
|
||||
def LDAWSP_ru6_RRegs : _FRU6<
|
||||
(outs RRegs:$dst), (ins i32imm:$b),
|
||||
"ldaw $dst, sp[$b]",
|
||||
@ -808,10 +810,6 @@ def GETID_0R : _F0R<(outs), (ins),
|
||||
|
||||
def : Pat<(XCoreBranchLink tglobaladdr:$addr), (BL_lu10 tglobaladdr:$addr)>;
|
||||
def : Pat<(XCoreBranchLink texternalsym:$addr), (BL_lu10 texternalsym:$addr)>;
|
||||
def : Pat<(XCoreStwsp GRRegs:$val, immU6:$index),
|
||||
(STWSP_ru6_2 GRRegs:$val, immU6:$index)>;
|
||||
def : Pat<(XCoreStwsp GRRegs:$val, immU16:$index),
|
||||
(STWSP_lru6_2 GRRegs:$val, immU16:$index)>;
|
||||
|
||||
/// sext_inreg
|
||||
def : Pat<(sext_inreg GRRegs:$b, i1), (SEXT_rus GRRegs:$b, 1)>;
|
||||
|
@ -211,19 +211,18 @@ void XCoreRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
|
||||
|
||||
bool FP = hasFP(MF);
|
||||
|
||||
unsigned Reg = MI.getOperand(0).getReg();
|
||||
bool isKill = MI.getOpcode() == XCore::STWFI && MI.getOperand(0).isKill();
|
||||
|
||||
assert(XCore::GRRegsRegisterClass->contains(Reg) &&
|
||||
"Unexpected register operand");
|
||||
|
||||
MachineBasicBlock &MBB = *MI.getParent();
|
||||
|
||||
if (FP) {
|
||||
bool isUs = isImmUs(Offset);
|
||||
MachineBasicBlock &MBB = *MI.getParent();
|
||||
unsigned FramePtr = XCore::R10;
|
||||
unsigned Reg = MI.getOperand(0).getReg();
|
||||
bool isKill = MI.getOperand(0).isKill();
|
||||
|
||||
if (Reg == XCore::LR) {
|
||||
// The LR should have been save in the prologue.
|
||||
cerr << "saving LR to FP unimplemented\n";
|
||||
abort();
|
||||
}
|
||||
|
||||
MachineInstr *New = 0;
|
||||
if (!isUs) {
|
||||
if (!RS) {
|
||||
@ -234,18 +233,18 @@ void XCoreRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
|
||||
SPAdj);
|
||||
loadConstant(MBB, II, ScratchReg, Offset);
|
||||
switch (MI.getOpcode()) {
|
||||
case XCore::LDWSP_lru6:
|
||||
case XCore::LDWFI:
|
||||
New = BuildMI(MBB, II, TII.get(XCore::LDW_3r), Reg)
|
||||
.addReg(FramePtr)
|
||||
.addReg(ScratchReg, false, false, true);
|
||||
break;
|
||||
case XCore::STWSP_lru6:
|
||||
case XCore::STWFI:
|
||||
New = BuildMI(MBB, II, TII.get(XCore::STW_3r))
|
||||
.addReg(Reg, false, false, isKill)
|
||||
.addReg(FramePtr)
|
||||
.addReg(ScratchReg, false, false, true);
|
||||
break;
|
||||
case XCore::LDAWSP_lru6:
|
||||
case XCore::LDAWFI:
|
||||
New = BuildMI(MBB, II, TII.get(XCore::LDAWF_l3r), Reg)
|
||||
.addReg(FramePtr)
|
||||
.addReg(ScratchReg, false, false, true);
|
||||
@ -255,18 +254,18 @@ void XCoreRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
|
||||
}
|
||||
} else {
|
||||
switch (MI.getOpcode()) {
|
||||
case XCore::LDWSP_lru6:
|
||||
case XCore::LDWFI:
|
||||
New = BuildMI(MBB, II, TII.get(XCore::LDW_2rus), Reg)
|
||||
.addReg(FramePtr)
|
||||
.addImm(Offset);
|
||||
break;
|
||||
case XCore::STWSP_lru6:
|
||||
case XCore::STWFI:
|
||||
New = BuildMI(MBB, II, TII.get(XCore::STW_2rus))
|
||||
.addReg(Reg, false, false, isKill)
|
||||
.addReg(FramePtr)
|
||||
.addImm(Offset);
|
||||
break;
|
||||
case XCore::LDAWSP_lru6:
|
||||
case XCore::LDAWFI:
|
||||
New = BuildMI(MBB, II, TII.get(XCore::LDAWF_l2rus), Reg)
|
||||
.addReg(FramePtr)
|
||||
.addImm(Offset);
|
||||
@ -275,9 +274,6 @@ void XCoreRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
|
||||
assert(0 && "Unexpected Opcode\n");
|
||||
}
|
||||
}
|
||||
|
||||
// Erase old instruction.
|
||||
MBB.erase(II);
|
||||
} else {
|
||||
bool isU6 = isImmU6(Offset);
|
||||
if (!isU6 && !isImmU16(Offset)) {
|
||||
@ -286,25 +282,30 @@ void XCoreRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
|
||||
abort();
|
||||
}
|
||||
|
||||
int NewOpcode = MI.getOpcode();
|
||||
|
||||
switch (NewOpcode) {
|
||||
case XCore::LDWSP_lru6:
|
||||
switch (MI.getOpcode()) {
|
||||
int NewOpcode;
|
||||
case XCore::LDWFI:
|
||||
NewOpcode = (isU6) ? XCore::LDWSP_ru6 : XCore::LDWSP_lru6;
|
||||
BuildMI(MBB, II, TII.get(NewOpcode), Reg)
|
||||
.addImm(Offset);
|
||||
break;
|
||||
case XCore::STWSP_lru6:
|
||||
case XCore::STWFI:
|
||||
NewOpcode = (isU6) ? XCore::STWSP_ru6 : XCore::STWSP_lru6;
|
||||
BuildMI(MBB, II, TII.get(NewOpcode))
|
||||
.addReg(Reg, false, false, isKill)
|
||||
.addImm(Offset);
|
||||
break;
|
||||
case XCore::LDAWSP_lru6:
|
||||
case XCore::LDAWFI:
|
||||
NewOpcode = (isU6) ? XCore::LDAWSP_ru6 : XCore::LDAWSP_lru6;
|
||||
BuildMI(MBB, II, TII.get(NewOpcode), Reg)
|
||||
.addImm(Offset);
|
||||
break;
|
||||
default:
|
||||
assert(0 && "Unexpected Opcode\n");
|
||||
}
|
||||
|
||||
MI.setDesc(TII.get(NewOpcode));
|
||||
FrameOp.ChangeToImmediate(Offset);
|
||||
}
|
||||
// Erase old instruction.
|
||||
MBB.erase(II);
|
||||
}
|
||||
|
||||
void
|
||||
@ -372,8 +373,7 @@ storeToStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
|
||||
int Opcode = isU6 ? XCore::STWSP_ru6 : XCore::STWSP_lru6;
|
||||
BuildMI(MBB, I, TII.get(Opcode))
|
||||
.addReg(SrcReg)
|
||||
.addImm(Offset)
|
||||
.addImm(0);
|
||||
.addImm(Offset);
|
||||
}
|
||||
|
||||
void XCoreRegisterInfo::
|
||||
@ -388,8 +388,7 @@ loadFromStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
|
||||
}
|
||||
int Opcode = isU6 ? XCore::LDWSP_ru6 : XCore::LDWSP_lru6;
|
||||
BuildMI(MBB, I, TII.get(Opcode), DstReg)
|
||||
.addImm(Offset)
|
||||
.addImm(0);
|
||||
.addImm(Offset);
|
||||
}
|
||||
|
||||
void XCoreRegisterInfo::emitPrologue(MachineFunction &MF) const {
|
||||
|
18
test/CodeGen/XCore/2009-01-14-Remat-Crash.ll
Normal file
18
test/CodeGen/XCore/2009-01-14-Remat-Crash.ll
Normal file
@ -0,0 +1,18 @@
|
||||
; RUN: llvm-as < %s | llc -march=xcore > %t1.s
|
||||
; PR3324
|
||||
define double @f1(double %a, double %b, double %c, double %d, double %e, double %f, double %g) nounwind {
|
||||
entry:
|
||||
br i1 false, label %bb113, label %bb129
|
||||
|
||||
bb113: ; preds = %entry
|
||||
ret double 0.000000e+00
|
||||
|
||||
bb129: ; preds = %entry
|
||||
%tmp134 = sub double %b, %a ; <double> [#uses=1]
|
||||
%tmp136 = sub double %tmp134, %c ; <double> [#uses=1]
|
||||
%tmp138 = add double %tmp136, %d ; <double> [#uses=1]
|
||||
%tmp140 = sub double %tmp138, %e ; <double> [#uses=1]
|
||||
%tmp142 = add double %tmp140, %f ; <double> [#uses=1]
|
||||
%tmp.0 = mul double %tmp142, 0.000000e+00 ; <double> [#uses=1]
|
||||
ret double %tmp.0
|
||||
}
|
Loading…
Reference in New Issue
Block a user