Index: lib/Target/PowerPC/PPCFrameLowering.cpp =================================================================== --- lib/Target/PowerPC/PPCFrameLowering.cpp +++ lib/Target/PowerPC/PPCFrameLowering.cpp @@ -505,7 +505,7 @@ MachineModuleInfo &MMI = MF.getMMI(); const MCRegisterInfo *MRI = MMI.getContext().getRegisterInfo(); DebugLoc dl; - bool needsFrameMoves = MMI.hasDebugInfo() || + bool needsCFI = MMI.hasDebugInfo() || MF.getFunction()->needsUnwindTableEntry(); bool isPIC = MF.getTarget().getRelocationModel() == Reloc::PIC_; @@ -726,17 +726,28 @@ .addReg(ScratchReg); } - // Add the "machine moves" for the instructions we generated above, but in - // reverse order. - if (needsFrameMoves) { - // Show update of SP. - assert(NegFrameSize); - unsigned CFIIndex = MMI.addFrameInst( - MCCFIInstruction::createDefCfaOffset(nullptr, NegFrameSize)); + // Add Call Frame Information for the instructions we generated above. + if (needsCFI) { + unsigned CFIIndex; + + if (HasBP) { + // Define CFA in terms of BP. Do this in preference to using FP/SP, + // because if the stack needed aligning then CFA won't be at a fixed + // offset from FP/SP. + unsigned Reg = MRI->getDwarfRegNum(BPReg, true); + CFIIndex = MMI.addFrameInst( + MCCFIInstruction::createDefCfaRegister(nullptr, Reg)); + } else { + // Adjust the definition of CFA to account for the change in SP. + assert(NegFrameSize); + CFIIndex = MMI.addFrameInst( + MCCFIInstruction::createDefCfaOffset(nullptr, NegFrameSize)); + } BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION)) .addCFIIndex(CFIIndex); if (HasFP) { + // Describe where FP was saved, at a fixed offset from CFA. unsigned Reg = MRI->getDwarfRegNum(FPReg, true); CFIIndex = MMI.addFrameInst( MCCFIInstruction::createOffset(nullptr, Reg, FPOffset)); @@ -745,6 +756,7 @@ } if (HasBP) { + // Describe where BP was saved, at a fixed offset from CFA. unsigned Reg = MRI->getDwarfRegNum(BPReg, true); CFIIndex = MMI.addFrameInst( MCCFIInstruction::createOffset(nullptr, Reg, BPOffset)); @@ -753,6 +765,7 @@ } if (MustSaveLR) { + // Describe where LR was saved, at a fixed offset from CFA. unsigned Reg = MRI->getDwarfRegNum(LRReg, true); CFIIndex = MMI.addFrameInst( MCCFIInstruction::createOffset(nullptr, Reg, LROffset)); @@ -767,8 +780,9 @@ .addReg(SPReg) .addReg(SPReg); - if (needsFrameMoves) { - // Mark effective beginning of when frame pointer is ready. + if (!HasBP && needsCFI) { + // Change the definition of CFA from SP+offset to FP+offset, because SP + // will change at every alloca. unsigned Reg = MRI->getDwarfRegNum(FPReg, true); unsigned CFIIndex = MMI.addFrameInst( MCCFIInstruction::createDefCfaRegister(nullptr, Reg)); @@ -778,8 +792,9 @@ } } - if (needsFrameMoves) { - // Add callee saved registers to move list. + if (needsCFI) { + // Describe where callee saved registers were saved, at fixed offsets from + // CFA. const std::vector &CSI = MFI->getCalleeSavedInfo(); for (unsigned I = 0, E = CSI.size(); I != E; ++I) { unsigned Reg = CSI[I].getReg(); Index: test/CodeGen/PowerPC/stack-realign.ll =================================================================== --- test/CodeGen/PowerPC/stack-realign.ll +++ test/CodeGen/PowerPC/stack-realign.ll @@ -37,6 +37,7 @@ ; CHECK-DAG: subfic 0, [[REG]], -160 ; CHECK: stdux 1, 1, 0 +; CHECK: .cfi_def_cfa_register r30 ; CHECK: .cfi_offset r30, -16 ; CHECK: .cfi_offset lr, 16 @@ -59,6 +60,7 @@ ; CHECK-FP-DAG: subfic 0, [[REG]], -160 ; CHECK-FP: stdux 1, 1, 0 +; CHECK-FP: .cfi_def_cfa_register r30 ; CHECK-FP: .cfi_offset r31, -8 ; CHECK-FP: .cfi_offset r30, -16 ; CHECK-FP: .cfi_offset lr, 16 @@ -120,6 +122,8 @@ ; CHECK-DAG: subfc 0, [[REG3]], [[REG2]] ; CHECK: stdux 1, 1, 0 +; CHECK: .cfi_def_cfa_register r30 + ; CHECK: blr ; CHECK-32-LABEL: @hoo @@ -178,6 +182,8 @@ ; CHECK-DAG: subfic 0, [[REG]], -192 ; CHECK: stdux 1, 1, 0 +; CHECK: .cfi_def_cfa_register r30 + ; CHECK: stfd 30, -16(30) ; CHECK: blr @@ -193,6 +199,8 @@ ; CHECK-FP-DAG: subfic 0, [[REG]], -192 ; CHECK-FP: stdux 1, 1, 0 +; CHECK-FP: .cfi_def_cfa_register r30 + ; CHECK-FP: stfd 30, -16(30) ; CHECK-FP: blr