ARM: correctly calculate the offset of FP in its push.
authorTim Northover <tnorthover@apple.com>
Fri, 14 Nov 2014 22:45:31 +0000 (22:45 +0000)
committerTim Northover <tnorthover@apple.com>
Fri, 14 Nov 2014 22:45:31 +0000 (22:45 +0000)
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

lib/Target/ARM/ARMFrameLowering.cpp
test/CodeGen/ARM/dwarf-unwind.ll

index 6ebc3aa9dacc5fe57956329740d395942bc162f6..24098fabadc8fa77ffb857fe0ccc85a2a7b439ec 100644 (file)
@@ -282,9 +282,15 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF) const {
 
   // Prolog/epilog inserter assumes we correctly align DPRs on the stack, so our
   // .cfi_offset operations will reflect that.
+  unsigned adjustedGPRCS1Size = GPRCS1Size;
   if (DPRGapSize) {
     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,
                    MachineInstr::FrameSetup);
   }
@@ -354,7 +360,6 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF) const {
     NumBytes = 0;
   }
 
-  unsigned adjustedGPRCS1Size = GPRCS1Size;
   if (NumBytes) {
     // Adjust SP after all the callee-save spills.
     if (tryFoldSPUpdateIntoPushPop(STI, MF, LastPush, NumBytes)) {
index 58f486d76ab171e2637737786158db3de852333d..0359e4b623ea36baddf1b5a64c9fdc33dce59215 100644 (file)
@@ -66,3 +66,12 @@ define void @test_nodpr_noalign(i8 %l, i8 %r) {
   call void @bar()
   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
+}
\ No newline at end of file