Skip to content

Commit e257ab8

Browse files
author
git apple-llvm automerger
committed
Merge commit 'a74c7d877637' from llvm.org/main into next
2 parents 608a5ec + a74c7d8 commit e257ab8

File tree

10 files changed

+131
-50
lines changed

10 files changed

+131
-50
lines changed

clang/lib/Driver/ToolChains/CommonArgs.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,13 @@ static bool mustUseNonLeafFramePointerForTarget(const llvm::Triple &Triple) {
174174
// even if new frame records are not created.
175175
static bool mustMaintainValidFrameChain(const llvm::opt::ArgList &Args,
176176
const llvm::Triple &Triple) {
177-
if (Triple.isARM() || Triple.isThumb()) {
177+
switch (Triple.getArch()) {
178+
default:
179+
return false;
180+
case llvm::Triple::arm:
181+
case llvm::Triple::armeb:
182+
case llvm::Triple::thumb:
183+
case llvm::Triple::thumbeb:
178184
// For 32-bit Arm, the -mframe-chain=aapcs and -mframe-chain=aapcs+leaf
179185
// options require the frame pointer register to be reserved (or point to a
180186
// new AAPCS-compilant frame record), even with -fno-omit-frame-pointer.
@@ -183,8 +189,13 @@ static bool mustMaintainValidFrameChain(const llvm::opt::ArgList &Args,
183189
return V != "none";
184190
}
185191
return false;
192+
193+
case llvm::Triple::aarch64:
194+
// Arm64 Windows requires that the frame chain is valid, as there is no
195+
// way to indicate during a stack walk that a frame has used the frame
196+
// pointer as a general purpose register.
197+
return Triple.isOSWindows();
186198
}
187-
return false;
188199
}
189200

190201
// True if a target-specific option causes -fno-omit-frame-pointer to also

clang/test/Driver/frame-pointer-elim.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
// KEEP-NON-LEAF: "-mframe-pointer=non-leaf"
55
// KEEP-NONE-NOT: warning: argument unused
66
// KEEP-NONE: "-mframe-pointer=none"
7+
// KEEP-RESERVED-NOT: warning: argument unused
8+
// KEEP-RESERVED: "-mframe-pointer=reserved"
79

810
// On Linux x86, omit frame pointer when optimization is enabled.
911
// RUN: %clang -### --target=i386-linux -S -fomit-frame-pointer %s 2>&1 | \
@@ -215,5 +217,9 @@
215217
// RUN: %clang -### --target=aarch64-none-elf -S -O1 -fno-omit-frame-pointer %s 2>&1 | \
216218
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s
217219

220+
// AArch64 Windows requires that the frame pointer be reserved
221+
// RUN: %clang -### --target=aarch64-pc-windows-msvc -S -fomit-frame-pointer %s 2>&1 | \
222+
// RUN: FileCheck --check-prefix=KEEP-RESERVED %s
223+
218224
void f0() {}
219225
void f1() { f0(); }

llvm/lib/Target/AArch64/AArch64FrameLowering.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -534,6 +534,27 @@ bool AArch64FrameLowering::hasFPImpl(const MachineFunction &MF) const {
534534
return false;
535535
}
536536

537+
/// Should the Frame Pointer be reserved for the current function?
538+
bool AArch64FrameLowering::isFPReserved(const MachineFunction &MF) const {
539+
const TargetMachine &TM = MF.getTarget();
540+
const Triple &TT = TM.getTargetTriple();
541+
542+
// These OSes require the frame chain is valid, even if the current frame does
543+
// not use a frame pointer.
544+
if (TT.isOSDarwin() || TT.isOSWindows())
545+
return true;
546+
547+
// If the function has a frame pointer, it is reserved.
548+
if (hasFP(MF))
549+
return true;
550+
551+
// Frontend has requested to preserve the frame pointer.
552+
if (TM.Options.FramePointerIsReserved(MF))
553+
return true;
554+
555+
return false;
556+
}
557+
537558
/// hasReservedCallFrame - Under normal circumstances, when a frame pointer is
538559
/// not required, we reserve argument space for call sites in the function
539560
/// immediately on entry to the current function. This eliminates the need for

llvm/lib/Target/AArch64/AArch64FrameLowering.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,8 @@ class AArch64FrameLowering : public TargetFrameLowering {
126126
orderFrameObjects(const MachineFunction &MF,
127127
SmallVectorImpl<int> &ObjectsToAllocate) const override;
128128

129+
bool isFPReserved(const MachineFunction &MF) const;
130+
129131
protected:
130132
bool hasFPImpl(const MachineFunction &MF) const override;
131133

llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -441,7 +441,7 @@ AArch64RegisterInfo::getStrictlyReservedRegs(const MachineFunction &MF) const {
441441
markSuperRegs(Reserved, AArch64::WSP);
442442
markSuperRegs(Reserved, AArch64::WZR);
443443

444-
if (TFI->hasFP(MF) || TT.isOSDarwin())
444+
if (TFI->isFPReserved(MF))
445445
markSuperRegs(Reserved, AArch64::W29);
446446

447447
if (MF.getSubtarget<AArch64Subtarget>().isWindowsArm64EC()) {

llvm/test/CodeGen/AArch64/regress-w29-reserved-with-fp.ll

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,26 @@
1-
; RUN: llc -mtriple=aarch64-none-linux-gnu -frame-pointer=all < %s | FileCheck %s
1+
; RUN: llc -mtriple=aarch64-none-linux-gnu -frame-pointer=none < %s | \
2+
; RUN: FileCheck %s --check-prefixes=CHECK,NONE
3+
; RUN: llc -mtriple=aarch64-none-linux-gnu -frame-pointer=reserved < %s | \
4+
; RUN: FileCheck %s --check-prefixes=CHECK,RESERVED
5+
; RUN: llc -mtriple=aarch64-none-linux-gnu -frame-pointer=all < %s | \
6+
; RUN: FileCheck %s --check-prefixes=CHECK,ALL
7+
8+
; By default, Darwin and Windows will reserve x29
9+
; RUN: llc -mtriple=aarch64-darwin -frame-pointer=none < %s | \
10+
; RUN: FileCheck %s --check-prefixes=CHECK,RESERVED
11+
; RUN: llc -mtriple=aarch64-darwin -frame-pointer=none < %s | \
12+
; RUN: FileCheck %s --check-prefixes=CHECK,RESERVED
213
@var = global i32 0
314

415
declare void @bar()
516

617
define void @test_w29_reserved() {
718
; CHECK-LABEL: test_w29_reserved:
8-
; CHECK: mov x29, sp
19+
; ALL: add x29, sp
20+
; NONE-NOT: add x29
21+
; NONE-NOT: mov x29
22+
; RESERVED-NOT: add x29
23+
; RESERVED-NOT: mov x29
924

1025
%val1 = load volatile i32, ptr @var
1126
%val2 = load volatile i32, ptr @var
@@ -16,8 +31,11 @@ define void @test_w29_reserved() {
1631
%val7 = load volatile i32, ptr @var
1732
%val8 = load volatile i32, ptr @var
1833
%val9 = load volatile i32, ptr @var
34+
%val10 = load volatile i32, ptr @var
1935

20-
; CHECK-NOT: ldr w29,
36+
; NONE: ldr w29,
37+
; ALL-NOT: ldr w29,
38+
; RESERVED-NOT: ldr w29,
2139

2240
; Call to prevent fp-elim that occurs regardless in leaf functions.
2341
call void @bar()
@@ -31,6 +49,7 @@ define void @test_w29_reserved() {
3149
store volatile i32 %val7, ptr @var
3250
store volatile i32 %val8, ptr @var
3351
store volatile i32 %val9, ptr @var
52+
store volatile i32 %val10, ptr @var
3453

3554
ret void
3655
; CHECK: ret

llvm/test/CodeGen/AArch64/win-sve.ll

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -65,14 +65,18 @@ define i32 @f(<vscale x 2 x i64> %x) {
6565
; CHECK-NEXT: .seh_save_zreg z22, 16
6666
; CHECK-NEXT: str z23, [sp, #17, mul vl] // 16-byte Folded Spill
6767
; CHECK-NEXT: .seh_save_zreg z23, 17
68-
; CHECK-NEXT: stp x29, x30, [sp, #-16]! // 16-byte Folded Spill
69-
; CHECK-NEXT: .seh_save_fplr_x 16
68+
; CHECK-NEXT: str x28, [sp, #-16]! // 8-byte Folded Spill
69+
; CHECK-NEXT: .seh_save_reg_x x28, 16
70+
; CHECK-NEXT: str x30, [sp, #8] // 8-byte Folded Spill
71+
; CHECK-NEXT: .seh_save_reg x30, 8
7072
; CHECK-NEXT: .seh_endprologue
7173
; CHECK-NEXT: bl g
7274
; CHECK-NEXT: mov w0, #3 // =0x3
7375
; CHECK-NEXT: .seh_startepilogue
74-
; CHECK-NEXT: ldp x29, x30, [sp] // 16-byte Folded Reload
75-
; CHECK-NEXT: .seh_save_fplr 0
76+
; CHECK-NEXT: ldr x30, [sp, #8] // 8-byte Folded Reload
77+
; CHECK-NEXT: .seh_save_reg x30, 8
78+
; CHECK-NEXT: ldr x28, [sp] // 8-byte Folded Reload
79+
; CHECK-NEXT: .seh_save_reg x28, 0
7680
; CHECK-NEXT: add sp, sp, #16
7781
; CHECK-NEXT: .seh_stackalloc 16
7882
; CHECK-NEXT: ldr z8, [sp, #2, mul vl] // 16-byte Folded Reload
@@ -365,8 +369,10 @@ define void @f3(i64 %n, <vscale x 2 x i64> %x) {
365369
; CHECK-NEXT: .seh_save_zreg z22, 16
366370
; CHECK-NEXT: str z23, [sp, #17, mul vl] // 16-byte Folded Spill
367371
; CHECK-NEXT: .seh_save_zreg z23, 17
368-
; CHECK-NEXT: stp x29, x30, [sp, #-16]! // 16-byte Folded Spill
369-
; CHECK-NEXT: .seh_save_fplr_x 16
372+
; CHECK-NEXT: str x28, [sp, #-16]! // 8-byte Folded Spill
373+
; CHECK-NEXT: .seh_save_reg_x x28, 16
374+
; CHECK-NEXT: str x30, [sp, #8] // 8-byte Folded Spill
375+
; CHECK-NEXT: .seh_save_reg x30, 8
370376
; CHECK-NEXT: sub sp, sp, #16
371377
; CHECK-NEXT: .seh_stackalloc 16
372378
; CHECK-NEXT: .seh_endprologue
@@ -376,8 +382,10 @@ define void @f3(i64 %n, <vscale x 2 x i64> %x) {
376382
; CHECK-NEXT: .seh_startepilogue
377383
; CHECK-NEXT: add sp, sp, #16
378384
; CHECK-NEXT: .seh_stackalloc 16
379-
; CHECK-NEXT: ldp x29, x30, [sp] // 16-byte Folded Reload
380-
; CHECK-NEXT: .seh_save_fplr 0
385+
; CHECK-NEXT: ldr x30, [sp, #8] // 8-byte Folded Reload
386+
; CHECK-NEXT: .seh_save_reg x30, 8
387+
; CHECK-NEXT: ldr x28, [sp] // 8-byte Folded Reload
388+
; CHECK-NEXT: .seh_save_reg x28, 0
381389
; CHECK-NEXT: add sp, sp, #16
382390
; CHECK-NEXT: .seh_stackalloc 16
383391
; CHECK-NEXT: ldr z8, [sp, #2, mul vl] // 16-byte Folded Reload
@@ -511,8 +519,10 @@ define void @f4(i64 %n, <vscale x 2 x i64> %x) {
511519
; CHECK-NEXT: .seh_save_zreg z22, 16
512520
; CHECK-NEXT: str z23, [sp, #17, mul vl] // 16-byte Folded Spill
513521
; CHECK-NEXT: .seh_save_zreg z23, 17
514-
; CHECK-NEXT: stp x29, x30, [sp, #-16]! // 16-byte Folded Spill
515-
; CHECK-NEXT: .seh_save_fplr_x 16
522+
; CHECK-NEXT: str x28, [sp, #-16]! // 8-byte Folded Spill
523+
; CHECK-NEXT: .seh_save_reg_x x28, 16
524+
; CHECK-NEXT: str x30, [sp, #8] // 8-byte Folded Spill
525+
; CHECK-NEXT: .seh_save_reg x30, 8
516526
; CHECK-NEXT: sub sp, sp, #16
517527
; CHECK-NEXT: .seh_stackalloc 16
518528
; CHECK-NEXT: addvl sp, sp, #-1
@@ -526,8 +536,10 @@ define void @f4(i64 %n, <vscale x 2 x i64> %x) {
526536
; CHECK-NEXT: .seh_allocz 1
527537
; CHECK-NEXT: add sp, sp, #16
528538
; CHECK-NEXT: .seh_stackalloc 16
529-
; CHECK-NEXT: ldp x29, x30, [sp] // 16-byte Folded Reload
530-
; CHECK-NEXT: .seh_save_fplr 0
539+
; CHECK-NEXT: ldr x30, [sp, #8] // 8-byte Folded Reload
540+
; CHECK-NEXT: .seh_save_reg x30, 8
541+
; CHECK-NEXT: ldr x28, [sp] // 8-byte Folded Reload
542+
; CHECK-NEXT: .seh_save_reg x28, 0
531543
; CHECK-NEXT: add sp, sp, #16
532544
; CHECK-NEXT: .seh_stackalloc 16
533545
; CHECK-NEXT: ldr z8, [sp, #2, mul vl] // 16-byte Folded Reload
@@ -1093,8 +1105,10 @@ define void @f7(i64 %n) {
10931105
; CHECK-LABEL: f7:
10941106
; CHECK: .seh_proc f7
10951107
; CHECK-NEXT: // %bb.0:
1096-
; CHECK-NEXT: stp x29, x30, [sp, #-16]! // 16-byte Folded Spill
1097-
; CHECK-NEXT: .seh_save_fplr_x 16
1108+
; CHECK-NEXT: str x28, [sp, #-16]! // 8-byte Folded Spill
1109+
; CHECK-NEXT: .seh_save_reg_x x28, 16
1110+
; CHECK-NEXT: str x30, [sp, #8] // 8-byte Folded Spill
1111+
; CHECK-NEXT: .seh_save_reg x30, 8
10981112
; CHECK-NEXT: addvl sp, sp, #-1
10991113
; CHECK-NEXT: .seh_allocz 1
11001114
; CHECK-NEXT: .seh_endprologue
@@ -1103,8 +1117,10 @@ define void @f7(i64 %n) {
11031117
; CHECK-NEXT: .seh_startepilogue
11041118
; CHECK-NEXT: addvl sp, sp, #1
11051119
; CHECK-NEXT: .seh_allocz 1
1106-
; CHECK-NEXT: ldp x29, x30, [sp], #16 // 16-byte Folded Reload
1107-
; CHECK-NEXT: .seh_save_fplr_x 16
1120+
; CHECK-NEXT: ldr x30, [sp, #8] // 8-byte Folded Reload
1121+
; CHECK-NEXT: .seh_save_reg x30, 8
1122+
; CHECK-NEXT: ldr x28, [sp], #16 // 8-byte Folded Reload
1123+
; CHECK-NEXT: .seh_save_reg_x x28, 16
11081124
; CHECK-NEXT: .seh_endepilogue
11091125
; CHECK-NEXT: ret
11101126
; CHECK-NEXT: .seh_endfunclet

llvm/test/CodeGen/AArch64/wincfi-missing-seh-directives.ll

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,23 @@
55
; prologue has a corresponding seh directive.
66
;
77
; CHECK-NOT: error: Incorrect size for
8-
; CHECK: foo:
9-
; CHECK: .seh_proc foo
10-
; CHECK: sub sp, sp, #288
11-
; CHECK: .seh_stackalloc 288
12-
; CHECK: str x19, [sp] // 8-byte Folded Spill
13-
; CHECK: .seh_save_reg x19, 0
14-
; CHECK: str x21, [sp, #8] // 8-byte Folded Spill
15-
; CHECK: .seh_save_reg x21, 8
16-
; CHECK: stp x23, x24, [sp, #16] // 16-byte Folded Spill
17-
; CHECK: .seh_save_regp x23, 16
18-
; CHECK: stp x25, x26, [sp, #32] // 16-byte Folded Spill
19-
; CHECK: .seh_save_regp x25, 32
20-
; CHECK: stp x27, x28, [sp, #48] // 16-byte Folded Spill
21-
; CHECK: .seh_save_regp x27, 48
22-
; CHECK: stp x29, x30, [sp, #64] // 16-byte Folded Spill
23-
; CHECK: .seh_save_fplr 64
24-
; CHECK: sub sp, sp, #224
25-
; CHECK: .seh_stackalloc 224
26-
; CHECK: .seh_endprologue
8+
; CHECK-LABEL: foo:
9+
; CHECK-NEXT: .seh_proc foo
10+
; CHECK: sub sp, sp, #496
11+
; CHECK-NEXT: .seh_stackalloc 496
12+
; CHECK-NEXT: str x19, [sp, #208] // 8-byte Folded Spill
13+
; CHECK-NEXT: .seh_save_reg x19, 208
14+
; CHECK-NEXT: str x21, [sp, #216] // 8-byte Folded Spill
15+
; CHECK-NEXT: .seh_save_reg x21, 216
16+
; CHECK-NEXT: stp x23, x24, [sp, #224] // 16-byte Folded Spill
17+
; CHECK-NEXT: .seh_save_regp x23, 224
18+
; CHECK-NEXT: stp x25, x26, [sp, #240] // 16-byte Folded Spill
19+
; CHECK-NEXT: .seh_save_regp x25, 240
20+
; CHECK-NEXT: stp x27, x28, [sp, #256] // 16-byte Folded Spill
21+
; CHECK-NEXT: .seh_save_regp x27, 256
22+
; CHECK-NEXT: str x30, [sp, #272] // 8-byte Folded Spill
23+
; CHECK-NEXT: .seh_save_reg x30, 272
24+
; CHECK-NEXT: .seh_endprologue
2725

2826
target datalayout = "e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128-Fn32"
2927
target triple = "aarch64-unknown-windows-msvc19.42.34436"

llvm/test/CodeGen/AArch64/wineh-frame5.mir

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@
55
# CHECK-LABEL: bb.0.entry:
66
# CHECK: early-clobber $sp = frame-setup STRXpre killed $x19, $sp, -32
77
# CHECK-NEXT: frame-setup SEH_SaveReg_X 19, -32
8-
# CHECK-NEXT: frame-setup STPXi killed $fp, killed $lr, $sp, 1
9-
# CHECK-NEXT: frame-setup SEH_SaveFPLR 8
8+
# CHECK-NEXT: frame-setup STRXui killed $x28, $sp, 1
9+
# CHECK-NEXT: frame-setup SEH_SaveReg 28, 8
10+
# CHECK-NEXT: frame-setup STRXui killed $lr, $sp, 2
11+
# CHECK-NEXT: frame-setup SEH_SaveReg 30, 16
1012
# CHECK-NEXT: $sp = frame-setup SUBXri $sp, 496, 0
1113
# CHECK-NEXT: frame-setup SEH_StackAlloc 496
1214
# CHECK-NEXT: frame-setup SEH_PrologEnd
@@ -15,8 +17,10 @@
1517
# CHECK: frame-destroy SEH_EpilogStart
1618
# CHECK-NEXT: $sp = frame-destroy ADDXri $sp, 496, 0
1719
# CHECK-NEXT: frame-destroy SEH_StackAlloc 496
18-
# CHECK-NEXT: $fp, $lr = frame-destroy LDPXi $sp, 1
19-
# CHECK-NEXT: frame-destroy SEH_SaveFPLR 8
20+
# CHECK-NEXT: $lr = frame-destroy LDRXui $sp, 2
21+
# CHECK-NEXT: frame-destroy SEH_SaveReg 30, 16
22+
# CHECK-NEXT: $x28 = frame-destroy LDRXui $sp, 1
23+
# CHECK-NEXT: frame-destroy SEH_SaveReg 28, 8
2024
# CHECK-NEXT: early-clobber $sp, $x19 = frame-destroy LDRXpost $sp, 32
2125
# CHECK-NEXT: frame-destroy SEH_SaveReg_X 19, -32
2226
# CHECK-NEXT: frame-destroy SEH_EpilogEnd

llvm/test/CodeGen/AArch64/wineh-frame7.mir

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@
33
# Test that stack probe results in Nop unwind codes in the prologue. Test
44
# save_fplr, save_reg_x and stack_alloc with multiple updates.
55

6-
# CHECK: early-clobber $sp = frame-setup STPXpre killed $fp, killed $lr, $sp, -2
7-
# CHECK-NEXT: frame-setup SEH_SaveFPLR_X -16
6+
# CHECK: early-clobber $sp = frame-setup STRXpre killed $x28, $sp, -32
7+
# CHECK-NEXT: frame-setup SEH_SaveReg_X 28, -32
8+
# CHECK-NEXT: frame-setup STPXi killed $fp, killed $lr, $sp, 1
9+
# CHECK-NEXT: frame-setup SEH_SaveFPLR 8
810
# CHECK-NEXT: $x15 = frame-setup MOVZXi 56009, 0
911
# CHECK-NEXT: frame-setup SEH_Nop
1012
# CHECK-NEXT: $x15 = frame-setup MOVKXi $x15, 2, 16
1113
# CHECK-NEXT: frame-setup SEH_Nop
12-
# CHECK-NEXT: frame-setup BL &__chkstk, implicit-def $lr, implicit $sp, implicit $x15
14+
# CHECK-NEXT: frame-setup BL &__chkstk, implicit-def $lr, implicit $sp, implicit $x15, implicit-def dead $x16, implicit-def dead $x17, implicit-def dead $nzcv
1315
# CHECK-NEXT: frame-setup SEH_Nop
1416
# CHECK-NEXT: $sp = frame-setup SUBXrx64 killed $sp, killed $x15, 28
1517
# CHECK-NEXT: frame-setup SEH_StackAlloc 2993296
@@ -19,8 +21,10 @@
1921
# CHECK-NEXT: frame-destroy SEH_StackAlloc 2990080
2022
# CHECK-NEXT: $sp = frame-destroy ADDXri $sp, 3216, 0
2123
# CHECK-NEXT: frame-destroy SEH_StackAlloc 3216
22-
# CHECK-NEXT: early-clobber $sp, $fp, $lr = frame-destroy LDPXpost $sp, 2
23-
# CHECK-NEXT: frame-destroy SEH_SaveFPLR_X -16
24+
# CHECK-NEXT: $fp, $lr = frame-destroy LDPXi $sp, 1
25+
# CHECK-NEXT: frame-destroy SEH_SaveFPLR 8
26+
# CHECK-NEXT: early-clobber $sp, $x28 = frame-destroy LDRXpost $sp, 32
27+
# CHECK-NEXT: frame-destroy SEH_SaveReg_X 28, -32
2428
# CHECK-NEXT: frame-destroy SEH_EpilogEnd
2529
# CHECK-NEXT: RET_ReallyLR implicit killed $w0
2630
--- |

0 commit comments

Comments
 (0)