[PATCH] D70800: Fix AArch64 AAPCS frame record chain
Logan Chien via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Wed Nov 27 23:58:20 PST 2019
logan created this revision.
logan added reviewers: efriedma, sdesmalen, t.p.northover.
Herald added subscribers: llvm-commits, hiraditya, kristof.beyls.
Herald added a project: LLVM.
After the commit r368987 (rG643adb55769e <https://reviews.llvm.org/rG643adb55769ecb12e0377dab60de50def15d2cea>) was landed, the frame record (FP and LR register) may be placed in the middle of a stack frame if a function has both callee-saved general-purpose registers and floating point registers. This will break the stack unwinders that simply walk through the frame records (based on the guarantee from AAPCS64 "The Frame Pointer" section). This commit fixes the problem by adding the frame record offset.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D70800
Files:
llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h
llvm/test/CodeGen/AArch64/framelayout-frame-record.ll
Index: llvm/test/CodeGen/AArch64/framelayout-frame-record.ll
===================================================================
--- /dev/null
+++ llvm/test/CodeGen/AArch64/framelayout-frame-record.ll
@@ -0,0 +1,19 @@
+; RUN: llc < %s -mtriple=aarch64--linux-gnu | FileCheck %s
+
+target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
+target triple = "aarch64--linux-gnu"
+
+declare void @escape.i64(i64)
+declare void @escape.double(double)
+
+define void @test_frame_record_offset(i64 %a, i64 %b, double %c, double %d) "no-frame-pointer-elim"="true" {
+; CHECK-LABEL: test_frame_record_offset:
+; CHECK: stp x29, x30, [sp, #[[OFFSET:[0-9]+]]]
+; CHECK: add x29, sp, #[[OFFSET]]
+
+ call void @escape.i64(i64 %a)
+ call void @escape.i64(i64 %b)
+ call void @escape.double(double %c)
+ call void @escape.double(double %d)
+ ret void
+}
Index: llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h
===================================================================
--- llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h
+++ llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h
@@ -126,6 +126,10 @@
// stack slot.
unsigned TaggedBasePointerOffset = 0;
+ // Offset from SP-at-entry to frame record (i.e. the spilled frame pointer
+ // and link address).
+ int FrameRecordOffset = 0;
+
public:
AArch64FunctionInfo() = default;
@@ -325,6 +329,13 @@
TaggedBasePointerOffset = Offset;
}
+ int getFrameRecordOffset() const {
+ return FrameRecordOffset;
+ }
+ void setFrameRecordOffset(int Offset) {
+ FrameRecordOffset = Offset;
+ }
+
private:
// Hold the lists of LOHs.
MILOHContainer LOHContainerSet;
Index: llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
===================================================================
--- llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
+++ llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
@@ -1019,7 +1019,8 @@
if (HasFP) {
// Only set up FP if we actually need to.
- int FPOffset = isTargetDarwin(MF) ? (AFI->getCalleeSavedStackSize() - 16) : 0;
+ int FPOffset = isTargetDarwin(MF) ? (AFI->getCalleeSavedStackSize() - 16)
+ : AFI->getFrameRecordOffset();
if (CombineSPBump)
FPOffset += AFI->getLocalStackSize();
@@ -1615,7 +1616,8 @@
// be able to save any instructions.
if (!IsFunclet && (MFI.hasVarSizedObjects() || AFI->isStackRealigned())) {
int64_t OffsetToFrameRecord =
- isTargetDarwin(MF) ? (-(int64_t)AFI->getCalleeSavedStackSize() + 16) : 0;
+ isTargetDarwin(MF) ? (-(int64_t)AFI->getCalleeSavedStackSize() + 16)
+ : -AFI->getFrameRecordOffset();;
emitFrameOffset(MBB, LastPopI, DL, AArch64::SP, AArch64::FP,
{OffsetToFrameRecord, MVT::i8},
TII, MachineInstr::FrameDestroy, false, NeedsWinCFI);
@@ -2282,6 +2284,13 @@
std::swap(Reg1, Reg2);
std::swap(FrameIdxReg1, FrameIdxReg2);
}
+ if (RPI.Type == RegPairInfo::GPR) {
+ AArch64FunctionInfo *AFI = MF.getInfo<AArch64FunctionInfo>();
+ if (Reg1 == AArch64::FP)
+ AFI->setFrameRecordOffset((RPI.Offset + 1) * Size);
+ if (RPI.isPaired() && Reg2 == AArch64::FP)
+ AFI->setFrameRecordOffset(RPI.Offset * Size);
+ }
MachineInstrBuilder MIB = BuildMI(MBB, MI, DL, TII.get(LdrOpc));
if (RPI.isPaired()) {
MIB.addReg(Reg2, getDefRegState(true));
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D70800.231355.patch
Type: text/x-patch
Size: 3445 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20191128/1a594254/attachment.bin>
More information about the llvm-commits
mailing list