Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

R11 not preserved with PAC-M and AAPCS frame chain defect fix #81249

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 18 additions & 6 deletions llvm/lib/Target/ARM/ARMBaseRegisterInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,16 @@ static inline bool isSplitFPArea1Register(unsigned Reg,
switch (Reg) {
case R0: case R1: case R2: case R3:
case R4: case R5: case R6: case R7:
case R8: case R9: case R10: case R12:
case SP: case PC:
case R8:
case R9:
case SP:
case PC:
return true;
case R10:
case R12:
return !SplitFramePushPop;
case LR:
return SplitFramePushPop;
default:
return false;
}
Expand All @@ -91,10 +98,15 @@ static inline bool isSplitFPArea2Register(unsigned Reg,
using namespace ARM;

switch (Reg) {
case R11: case LR:
return true;
default:
return false;
case R10:
case R12:
return SplitFramePushPop;
case R11:
return true;
case LR:
return !SplitFramePushPop;
default:
return false;
}
}

Expand Down
22 changes: 22 additions & 0 deletions llvm/lib/Target/ARM/ARMSubtarget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,28 @@ bool ARMSubtarget::ignoreCSRForAllocationOrder(const MachineFunction &MF,

bool ARMSubtarget::splitFramePointerPush(const MachineFunction &MF) const {
const Function &F = MF.getFunction();
const std::vector<CalleeSavedInfo> CSI =
MF.getFrameInfo().getCalleeSavedInfo();

if (CSI.size() > 1 &&
MF.getInfo<ARMFunctionInfo>()->shouldSignReturnAddress()) {
bool r11InCSI = false;
bool lrInCSI = false;
unsigned long r11Idx = 0;
unsigned long lrIdx = 0;
for (unsigned long i = 0; i < CSI.size(); i++) {
if (CSI[i].getReg() == ARM::LR) {
lrIdx = i;
lrInCSI = true;
} else if (CSI[i].getReg() == ARM::R11) {
r11Idx = i;
r11InCSI = true;
}
}
if (lrIdx + 1 != r11Idx && r11InCSI && lrInCSI)
return true;
}

if (!MF.getTarget().getMCAsmInfo()->usesWindowsCFI() ||
!F.needsUnwindTableEntry())
return false;
Expand Down
3 changes: 2 additions & 1 deletion llvm/lib/Target/ARM/ARMSubtarget.h
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,8 @@ class ARMSubtarget : public ARMGenSubtargetInfo {
/// to lr. This is always required on Thumb1-only targets, as the push and
/// pop instructions can't access the high registers.
bool splitFramePushPop(const MachineFunction &MF) const {
if (MF.getInfo<ARMFunctionInfo>()->shouldSignReturnAddress())
if (MF.getInfo<ARMFunctionInfo>()->shouldSignReturnAddress() &&
!createAAPCSFrameChain())
return true;
return (getFramePointerReg() == ARM::R7 &&
MF.getTarget().Options.DisableFramePointerElim(MF)) ||
Expand Down
82 changes: 82 additions & 0 deletions llvm/test/CodeGen/Thumb2/pacbti-m-frame-chain.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
; RUN: llc -filetype asm -o - %s --frame-pointer=all -mattr=+aapcs-frame-chain -mattr=+aapcs-frame-chain-leaf -force-dwarf-frame-section | FileCheck %s
target triple = "thumbv8m.main-none-none-eabi"

; int f() {
; return 0;
; }
;
; int x(int, char *);
; int y(int n) {
; char a[n];
; return 1 + x(n, a);
; }

define hidden i32 @f() local_unnamed_addr {
entry:
ret i32 0;
}

define hidden i32 @x(i32 noundef %n) local_unnamed_addr {
entry:
%vla = alloca i8, i32 %n, align 1
%call = call i32 @y(i32 noundef %n, ptr noundef nonnull %vla)
%add = add nsw i32 %call, 1
ret i32 %add
}

declare dso_local i32 @y(i32 noundef, ptr noundef) local_unnamed_addr

; CHECK-LABEL: f:
; CHECK: pac r12, lr, sp
; CHECK-NEXT: .save {ra_auth_code}
; CHECK-NEXT: str r12, [sp, #-4]!
; CHECK-NEXT: .cfi_def_cfa_offset 4
; CHECK-NEXT: .cfi_offset lr, -4
; CHECK-NEXT: .cfi_offset r12, -8
; CHECK-NEXT: .cfi_offset r11, -12
; CHECK-NEXT: .save {r11, lr}
; CHECK-NEXT: push.w {r11, lr}
; CHECK-NEXT: .setfp r11, sp
; CHECK-NEXT: mov r11, sp
; CHECK-NEXT: .cfi_def_cfa r11, 12
; CHECK-NEXT: .pad #8
; CHECK-NEXT: sub sp, #8
; CHECK-NEXT: movs r0, #0
; CHECK-NEXT: pop.w {r11, lr}
; CHECK-NEXT: ldr r12, [sp], #4
; CHECK-NEXT: aut r12, lr, sp
; CHECK-NEXT: bx lr

; CHECK-LABEL: x:
; CHECK: pac r12, lr, sp
; CHECK-NEXT: .save {r4, r7, ra_auth_code}
; CHECK-NEXT: push.w {r4, r7, r12}
; CHECK-NEXT: .cfi_def_cfa_offset 12
; CHECK-NEXT: .cfi_offset lr, -4
; CHECK-NEXT: .cfi_offset r12, -8
; CHECK-NEXT: .cfi_offset r11, -12
; CHECK-NEXT: .cfi_offset r7, -16
; CHECK-NEXT: .cfi_offset r4, -20
; CHECK-NEXT: .save {r11, lr}
; CHECK-NEXT: push.w {r11, lr}
; CHECK-NEXT: .setfp r11, sp
; CHECK-NEXT: mov r11, sp
; CHECK-NEXT: .cfi_def_cfa_register r11
; CHECK-NEXT: .pad #12
; CHECK-NEXT: sub sp, #12
; CHECK-NEXT: adds r1, r0, #7
; CHECK-NEXT: bic r1, r1, #7
; CHECK-NEXT: sub.w r1, sp, r1
; CHECK-NEXT: mov sp, r1
; CHECK-NEXT: bl y
; CHECK-NEXT: sub.w r4, r11, #8
; CHECK-NEXT: adds r0, #1
; CHECK-NEXT: mov sp, r4
; CHECK-NEXT: pop.w {r11, lr}
; CHECK-NEXT: pop.w {r4, r7, r12}
; CHECK-NEXT: aut r12, lr, sp
; CHECK-NEXT: bx lr

!llvm.module.flags = !{!0}

!0 = !{i32 8, !"sign-return-address", i32 1}
Loading