Skip to content

Commit 913162b

Browse files
committed
[AArch64] Ensure the LR is preserved if we must call __arm_get_current_vg
Fixes #145635
1 parent 36a060a commit 913162b

File tree

2 files changed

+55
-0
lines changed

2 files changed

+55
-0
lines changed

llvm/lib/Target/AArch64/AArch64FrameLowering.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3955,6 +3955,10 @@ void AArch64FrameLowering::determineCalleeSaves(MachineFunction &MF,
39553955
// Save number of saved regs, so we can easily update CSStackSize later.
39563956
unsigned NumSavedRegs = SavedRegs.count();
39573957

3958+
// If we must call __arm_get_current_vg in the prologue preserve the LR.
3959+
if (requiresSaveVG(MF) && !Subtarget.hasSVE())
3960+
SavedRegs.set(AArch64::LR);
3961+
39583962
// The frame record needs to be created by saving the appropriate registers
39593963
uint64_t EstimatedStackSize = MFI.estimateStackSize(MF);
39603964
if (hasFP(MF) ||
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
2+
; RUN: llc -mtriple=aarch64-linux-gnu -mattr=+sme -O0 < %s | FileCheck %s
3+
4+
; Example of locally streaming function that (at -O0) must preserve the LR (X30)
5+
; before calling __arm_get_current_vg.
6+
define void @foo() "aarch64_pstate_sm_body" {
7+
; CHECK-LABEL: foo:
8+
; CHECK: // %bb.0:
9+
; CHECK-NEXT: stp d15, d14, [sp, #-96]! // 16-byte Folded Spill
10+
; CHECK-NEXT: .cfi_def_cfa_offset 96
11+
; CHECK-NEXT: stp d13, d12, [sp, #16] // 16-byte Folded Spill
12+
; CHECK-NEXT: stp d11, d10, [sp, #32] // 16-byte Folded Spill
13+
; CHECK-NEXT: stp d9, d8, [sp, #48] // 16-byte Folded Spill
14+
; CHECK-NEXT: stp x29, x30, [sp, #64] // 16-byte Folded Spill
15+
; CHECK-NEXT: rdsvl x9, #1
16+
; CHECK-NEXT: lsr x9, x9, #3
17+
; CHECK-NEXT: str x9, [sp, #80] // 8-byte Folded Spill
18+
; CHECK-NEXT: bl __arm_get_current_vg
19+
; CHECK-NEXT: str x0, [sp, #88] // 8-byte Folded Spill
20+
; CHECK-NEXT: .cfi_offset vg, -8
21+
; CHECK-NEXT: .cfi_offset w30, -24
22+
; CHECK-NEXT: .cfi_offset w29, -32
23+
; CHECK-NEXT: .cfi_offset b8, -40
24+
; CHECK-NEXT: .cfi_offset b9, -48
25+
; CHECK-NEXT: .cfi_offset b10, -56
26+
; CHECK-NEXT: .cfi_offset b11, -64
27+
; CHECK-NEXT: .cfi_offset b12, -72
28+
; CHECK-NEXT: .cfi_offset b13, -80
29+
; CHECK-NEXT: .cfi_offset b14, -88
30+
; CHECK-NEXT: .cfi_offset b15, -96
31+
; CHECK-NEXT: smstart sm
32+
; CHECK-NEXT: smstop sm
33+
; CHECK-NEXT: ldp x29, x30, [sp, #64] // 16-byte Folded Reload
34+
; CHECK-NEXT: ldp d9, d8, [sp, #48] // 16-byte Folded Reload
35+
; CHECK-NEXT: ldp d11, d10, [sp, #32] // 16-byte Folded Reload
36+
; CHECK-NEXT: ldp d13, d12, [sp, #16] // 16-byte Folded Reload
37+
; CHECK-NEXT: ldp d15, d14, [sp], #96 // 16-byte Folded Reload
38+
; CHECK-NEXT: .cfi_def_cfa_offset 0
39+
; CHECK-NEXT: .cfi_restore w30
40+
; CHECK-NEXT: .cfi_restore w29
41+
; CHECK-NEXT: .cfi_restore b8
42+
; CHECK-NEXT: .cfi_restore b9
43+
; CHECK-NEXT: .cfi_restore b10
44+
; CHECK-NEXT: .cfi_restore b11
45+
; CHECK-NEXT: .cfi_restore b12
46+
; CHECK-NEXT: .cfi_restore b13
47+
; CHECK-NEXT: .cfi_restore b14
48+
; CHECK-NEXT: .cfi_restore b15
49+
; CHECK-NEXT: ret
50+
ret void
51+
}

0 commit comments

Comments
 (0)