ARM: correctly calculate the offset of FP in its push.

When we folded the DPR alignment gap into a push, we weren't noting the extra
distance from the beginning of the push to the FP, and so FP ended up pointing
at an incorrect offset.

The .cfi_def_cfa_offset directives are still wrong in this case, but I think
that can be improved by refactoring.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@222056 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Tim Northover 2014-11-14 22:45:31 +00:00
parent 9aa6fd59b3
commit d96893fd3d
2 changed files with 16 additions and 2 deletions

View File

@ -282,9 +282,15 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF) const {
// Prolog/epilog inserter assumes we correctly align DPRs on the stack, so our // Prolog/epilog inserter assumes we correctly align DPRs on the stack, so our
// .cfi_offset operations will reflect that. // .cfi_offset operations will reflect that.
unsigned adjustedGPRCS1Size = GPRCS1Size;
if (DPRGapSize) { if (DPRGapSize) {
assert(DPRGapSize == 4 && "unexpected alignment requirements for DPRs"); assert(DPRGapSize == 4 && "unexpected alignment requirements for DPRs");
if (!tryFoldSPUpdateIntoPushPop(STI, MF, LastPush, DPRGapSize)) if (tryFoldSPUpdateIntoPushPop(STI, MF, LastPush, DPRGapSize)) {
if (LastPush == GPRCS1Push) {
FramePtrOffsetInPush += DPRGapSize;
adjustedGPRCS1Size += DPRGapSize;
}
} else
emitSPUpdate(isARM, MBB, MBBI, dl, TII, -DPRGapSize, emitSPUpdate(isARM, MBB, MBBI, dl, TII, -DPRGapSize,
MachineInstr::FrameSetup); MachineInstr::FrameSetup);
} }
@ -354,7 +360,6 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF) const {
NumBytes = 0; NumBytes = 0;
} }
unsigned adjustedGPRCS1Size = GPRCS1Size;
if (NumBytes) { if (NumBytes) {
// Adjust SP after all the callee-save spills. // Adjust SP after all the callee-save spills.
if (tryFoldSPUpdateIntoPushPop(STI, MF, LastPush, NumBytes)) { if (tryFoldSPUpdateIntoPushPop(STI, MF, LastPush, NumBytes)) {

View File

@ -66,3 +66,12 @@ define void @test_nodpr_noalign(i8 %l, i8 %r) {
call void @bar() call void @bar()
ret void ret void
} }
define void @test_frame_pointer_offset() minsize "no-frame-pointer-elim"="true" {
; CHECK-LABEL: test_frame_pointer_offset:
; CHECK: push.w {r3, r4, r5, r6, r7, r8, r9, r10, r11, lr}
; CHECK: add r7, sp, #16
call void asm sideeffect "", "~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{d8}"()
call void @bar()
ret void
}