From 1c156dfdcba03b0bf49297ed2fc08a30de5ca31f Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Wed, 11 May 2016 14:53:07 +0000 Subject: [PATCH] [Hexagon] Use offsets relative to FP+8 in .cfi_offset instructions When generating .cfi_offset instructions, make sure that the offset is calculated with respect to the register used to define the CFA (which is currently always FP+8). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@269191 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Hexagon/HexagonFrameLowering.cpp | 24 +++++++++--- test/CodeGen/Hexagon/cfi-offset.ll | 43 +++++++++++++++++++++ 2 files changed, 62 insertions(+), 5 deletions(-) create mode 100644 test/CodeGen/Hexagon/cfi-offset.ll diff --git a/lib/Target/Hexagon/HexagonFrameLowering.cpp b/lib/Target/Hexagon/HexagonFrameLowering.cpp index 95b98160194..d91b79dae86 100644 --- a/lib/Target/Hexagon/HexagonFrameLowering.cpp +++ b/lib/Target/Hexagon/HexagonFrameLowering.cpp @@ -648,7 +648,7 @@ void HexagonFrameLowering::insertCFIInstructions(MachineFunction &MF) const { void HexagonFrameLowering::insertCFIInstructionsAt(MachineBasicBlock &MBB, MachineBasicBlock::iterator At) const { MachineFunction &MF = *MBB.getParent(); - MachineFrameInfo *MFI = MF.getFrameInfo(); + MachineFrameInfo &MFI = *MF.getFrameInfo(); MachineModuleInfo &MMI = MF.getMMI(); auto &HST = MF.getSubtarget(); auto &HII = *HST.getInstrInfo(); @@ -661,8 +661,9 @@ void HexagonFrameLowering::insertCFIInstructionsAt(MachineBasicBlock &MBB, const MCInstrDesc &CFID = HII.get(TargetOpcode::CFI_INSTRUCTION); MCSymbol *FrameLabel = MMI.getContext().createTempSymbol(); + bool HasFP = hasFP(MF); - if (hasFP(MF)) { + if (HasFP) { unsigned DwFPReg = HRI.getDwarfRegNum(HRI.getFrameRegister(), true); unsigned DwRAReg = HRI.getDwarfRegNum(HRI.getRARegister(), true); @@ -700,7 +701,7 @@ void HexagonFrameLowering::insertCFIInstructionsAt(MachineBasicBlock &MBB, Hexagon::NoRegister }; - const std::vector &CSI = MFI->getCalleeSavedInfo(); + const std::vector &CSI = MFI.getCalleeSavedInfo(); for (unsigned i = 0; RegsToMove[i] != Hexagon::NoRegister; ++i) { unsigned Reg = RegsToMove[i]; @@ -711,9 +712,22 @@ void HexagonFrameLowering::insertCFIInstructionsAt(MachineBasicBlock &MBB, if (F == CSI.end()) continue; + int64_t Offset; + if (HasFP) { + // If the function has a frame pointer (i.e. has an allocframe), + // then the CFA has been defined in terms of FP. Any offsets in + // the following CFI instructions have to be defined relative + // to FP, which points to the bottom of the stack frame. + // The function getFrameIndexReference can still choose to use SP + // for the offset calculation, so we cannot simply call it here. + // Instead, get the offset (relative to the FP) directly. + Offset = MFI.getObjectOffset(F->getFrameIdx()); + } else { + unsigned FrameReg; + Offset = getFrameIndexReference(MF, F->getFrameIdx(), FrameReg); + } // Subtract 8 to make room for R30 and R31, which are added above. - unsigned FrameReg; - int64_t Offset = getFrameIndexReference(MF, F->getFrameIdx(), FrameReg) - 8; + Offset -= 8; if (Reg < Hexagon::D0 || Reg > Hexagon::D15) { unsigned DwarfReg = HRI.getDwarfRegNum(Reg, true); diff --git a/test/CodeGen/Hexagon/cfi-offset.ll b/test/CodeGen/Hexagon/cfi-offset.ll new file mode 100644 index 00000000000..100034a0c6c --- /dev/null +++ b/test/CodeGen/Hexagon/cfi-offset.ll @@ -0,0 +1,43 @@ +; RUN: llc -march=hexagon < %s | FileCheck %s +; Check that all the offsets in the .cfi_offset instructions are negative. +; They are all based on R30+8 which points to the pair FP/LR stored by an +; allocframe. Since the stack grows towards negative addresses, anything +; in the current stack frame will have a negative offset with respect to +; R30+8. + +; CHECK: cfi_def_cfa r30 +; CHECK-NOT: .cfi_offset r{{[0-9]+}}, {{[^-]}} + +target triple = "hexagon" + +define i64 @_Z3fooxxx(i64 %x, i64 %y, i64 %z) #0 personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { +entry: + %call = invoke i64 @_Z3barxxx(i64 %x, i64 %y, i64 %z) + to label %try.cont unwind label %lpad + +lpad: ; preds = %entry + %0 = landingpad { i8*, i32 } + catch i8* null + %1 = extractvalue { i8*, i32 } %0, 0 + %2 = tail call i8* @__cxa_begin_catch(i8* %1) #1 + tail call void @__cxa_end_catch() + br label %try.cont + +try.cont: ; preds = %entry, %lpad + %a.0 = phi i64 [ 0, %lpad ], [ %call, %entry ] + %mul = mul nsw i64 %y, %x + %sub = sub i64 %mul, %z + %add = add nsw i64 %sub, %a.0 + ret i64 %add +} + +declare i64 @_Z3barxxx(i64, i64, i64) #0 + +declare i32 @__gxx_personality_v0(...) + +declare i8* @__cxa_begin_catch(i8*) + +declare void @__cxa_end_catch() + +attributes #0 = { "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="hexagonv60" "target-features"="-hvx,-hvx-double" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind }