mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-25 13:24:46 +00:00
PPC: Allocate RS spill slot for unaligned i64 load/store
This fixes another bug found by llvm-stress! If we happen to be doing an i64 load or store into a stack slot that has less than a 4-byte alignment, then the frame-index elimination may need to use an indexed load or store instruction (because the offset may not be a multiple of 4, a requirement of the STD/LD instructions). The extra register needed to hold the offset comes from the register scavenger, and it is possible that the scavenger will need to use an emergency spill slot. As a result, we need to make sure that a spill slot is allocated when doing an i64 load/store into a less-than-4-byte-aligned stack slot. Because test cases for things like this tend to be fairly fragile, I've concatenated a few small bugpoint-reduced test cases together to form the regression test. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@185907 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -1030,6 +1030,35 @@ bool PPCTargetLowering::SelectAddressRegReg(SDValue N, SDValue &Base,
|
||||
return false;
|
||||
}
|
||||
|
||||
// If we happen to be doing an i64 load or store into a stack slot that has
|
||||
// less than a 4-byte alignment, then the frame-index elimination may need to
|
||||
// use an indexed load or store instruction (because the offset may not be a
|
||||
// multiple of 4). The extra register needed to hold the offset comes from the
|
||||
// register scavenger, and it is possible that the scavenger will need to use
|
||||
// an emergency spill slot. As a result, we need to make sure that a spill slot
|
||||
// is allocated when doing an i64 load/store into a less-than-4-byte-aligned
|
||||
// stack slot.
|
||||
static void fixupFuncForFI(SelectionDAG &DAG, int FrameIdx, EVT VT) {
|
||||
// FIXME: This does not handle the LWA case.
|
||||
if (VT != MVT::i64)
|
||||
return;
|
||||
|
||||
// This should not be needed for negative FIs, which come from argument
|
||||
// lowering, because the ABI should guarentee the necessary alignment.
|
||||
if (FrameIdx < 0)
|
||||
return;
|
||||
|
||||
MachineFunction &MF = DAG.getMachineFunction();
|
||||
MachineFrameInfo *MFI = MF.getFrameInfo();
|
||||
|
||||
unsigned Align = MFI->getObjectAlignment(FrameIdx);
|
||||
if (Align >= 4)
|
||||
return;
|
||||
|
||||
PPCFunctionInfo *FuncInfo = MF.getInfo<PPCFunctionInfo>();
|
||||
FuncInfo->setHasNonRISpills();
|
||||
}
|
||||
|
||||
/// Returns true if the address N can be represented by a base register plus
|
||||
/// a signed 16-bit displacement [r+imm], and if it is not better
|
||||
/// represented as reg+reg. If Aligned is true, only accept displacements
|
||||
@@ -1051,6 +1080,7 @@ bool PPCTargetLowering::SelectAddressRegImm(SDValue N, SDValue &Disp,
|
||||
Disp = DAG.getTargetConstant(imm, N.getValueType());
|
||||
if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(N.getOperand(0))) {
|
||||
Base = DAG.getTargetFrameIndex(FI->getIndex(), N.getValueType());
|
||||
fixupFuncForFI(DAG, FI->getIndex(), N.getValueType());
|
||||
} else {
|
||||
Base = N.getOperand(0);
|
||||
}
|
||||
@@ -1115,9 +1145,10 @@ bool PPCTargetLowering::SelectAddressRegImm(SDValue N, SDValue &Disp,
|
||||
}
|
||||
|
||||
Disp = DAG.getTargetConstant(0, getPointerTy());
|
||||
if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(N))
|
||||
if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(N)) {
|
||||
Base = DAG.getTargetFrameIndex(FI->getIndex(), N.getValueType());
|
||||
else
|
||||
fixupFuncForFI(DAG, FI->getIndex(), N.getValueType());
|
||||
} else
|
||||
Base = N;
|
||||
return true; // [r+0]
|
||||
}
|
||||
|
Reference in New Issue
Block a user