Author: David Spickett Date: 2025-07-03T10:02:43+01:00 New Revision: 8763227d14aae0994e33e34ffc1948ca95c1efcb
URL: https://github.com/llvm/llvm-project/commit/8763227d14aae0994e33e34ffc1948ca95c1efcb DIFF: https://github.com/llvm/llvm-project/commit/8763227d14aae0994e33e34ffc1948ca95c1efcb.diff LOG: Revert "[win][aarch64] Always reserve frame pointers for Arm64 Windows (#146582)" This reverts commit a74c7d877637f31ff25308969ef7ca6ed94aacc5. Added: Modified: clang/lib/Driver/ToolChains/CommonArgs.cpp clang/test/Driver/frame-pointer-elim.c llvm/lib/Target/AArch64/AArch64FrameLowering.cpp llvm/lib/Target/AArch64/AArch64FrameLowering.h llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp llvm/test/CodeGen/AArch64/regress-w29-reserved-with-fp.ll llvm/test/CodeGen/AArch64/win-sve.ll llvm/test/CodeGen/AArch64/wincfi-missing-seh-directives.ll llvm/test/CodeGen/AArch64/wineh-frame5.mir llvm/test/CodeGen/AArch64/wineh-frame7.mir Removed: ################################################################################ diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp index 2fcf9b28dc746..070901f037823 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -174,13 +174,7 @@ static bool mustUseNonLeafFramePointerForTarget(const llvm::Triple &Triple) { // even if new frame records are not created. static bool mustMaintainValidFrameChain(const llvm::opt::ArgList &Args, const llvm::Triple &Triple) { - switch (Triple.getArch()) { - default: - return false; - case llvm::Triple::arm: - case llvm::Triple::armeb: - case llvm::Triple::thumb: - case llvm::Triple::thumbeb: + if (Triple.isARM() || Triple.isThumb()) { // For 32-bit Arm, the -mframe-chain=aapcs and -mframe-chain=aapcs+leaf // options require the frame pointer register to be reserved (or point to a // new AAPCS-compilant frame record), even with -fno-omit-frame-pointer. @@ -189,13 +183,8 @@ static bool mustMaintainValidFrameChain(const llvm::opt::ArgList &Args, return V != "none"; } return false; - - case llvm::Triple::aarch64: - // Arm64 Windows requires that the frame chain is valid, as there is no - // way to indicate during a stack walk that a frame has used the frame - // pointer as a general purpose register. - return Triple.isOSWindows(); } + return false; } // True if a target-specific option causes -fno-omit-frame-pointer to also diff --git a/clang/test/Driver/frame-pointer-elim.c b/clang/test/Driver/frame-pointer-elim.c index 0dd7eb0c738db..f64ff6efc7261 100644 --- a/clang/test/Driver/frame-pointer-elim.c +++ b/clang/test/Driver/frame-pointer-elim.c @@ -4,8 +4,6 @@ // KEEP-NON-LEAF: "-mframe-pointer=non-leaf" // KEEP-NONE-NOT: warning: argument unused // KEEP-NONE: "-mframe-pointer=none" -// KEEP-RESERVED-NOT: warning: argument unused -// KEEP-RESERVED: "-mframe-pointer=reserved" // On Linux x86, omit frame pointer when optimization is enabled. // RUN: %clang -### --target=i386-linux -S -fomit-frame-pointer %s 2>&1 | \ @@ -217,9 +215,5 @@ // RUN: %clang -### --target=aarch64-none-elf -S -O1 -fno-omit-frame-pointer %s 2>&1 | \ // RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s -// AArch64 Windows requires that the frame pointer be reserved -// RUN: %clang -### --target=aarch64-pc-windows-msvc -S -fomit-frame-pointer %s 2>&1 | \ -// RUN: FileCheck --check-prefix=KEEP-RESERVED %s - void f0() {} void f1() { f0(); } diff --git a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp index 3ef7e5265c724..6f1ce5bdbe286 100644 --- a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp @@ -518,27 +518,6 @@ bool AArch64FrameLowering::hasFPImpl(const MachineFunction &MF) const { return false; } -/// Should the Frame Pointer be reserved for the current function? -bool AArch64FrameLowering::isFPReserved(const MachineFunction &MF) const { - const TargetMachine &TM = MF.getTarget(); - const Triple &TT = TM.getTargetTriple(); - - // These OSes require the frame chain is valid, even if the current frame does - // not use a frame pointer. - if (TT.isOSDarwin() || TT.isOSWindows()) - return true; - - // If the function has a frame pointer, it is reserved. - if (hasFP(MF)) - return true; - - // Frontend has requested to preserve the frame pointer. - if (TM.Options.FramePointerIsReserved(MF)) - return true; - - return false; -} - /// hasReservedCallFrame - Under normal circumstances, when a frame pointer is /// not required, we reserve argument space for call sites in the function /// immediately on entry to the current function. This eliminates the need for diff --git a/llvm/lib/Target/AArch64/AArch64FrameLowering.h b/llvm/lib/Target/AArch64/AArch64FrameLowering.h index ced69c9cd3699..e7d52bb350f13 100644 --- a/llvm/lib/Target/AArch64/AArch64FrameLowering.h +++ b/llvm/lib/Target/AArch64/AArch64FrameLowering.h @@ -126,8 +126,6 @@ class AArch64FrameLowering : public TargetFrameLowering { orderFrameObjects(const MachineFunction &MF, SmallVectorImpl<int> &ObjectsToAllocate) const override; - bool isFPReserved(const MachineFunction &MF) const; - protected: bool hasFPImpl(const MachineFunction &MF) const override; diff --git a/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp b/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp index dd23bf51a98c4..fb472ddc719fc 100644 --- a/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp @@ -441,7 +441,7 @@ AArch64RegisterInfo::getStrictlyReservedRegs(const MachineFunction &MF) const { markSuperRegs(Reserved, AArch64::WSP); markSuperRegs(Reserved, AArch64::WZR); - if (TFI->isFPReserved(MF)) + if (TFI->hasFP(MF) || TT.isOSDarwin()) markSuperRegs(Reserved, AArch64::W29); if (MF.getSubtarget<AArch64Subtarget>().isWindowsArm64EC()) { diff --git a/llvm/test/CodeGen/AArch64/regress-w29-reserved-with-fp.ll b/llvm/test/CodeGen/AArch64/regress-w29-reserved-with-fp.ll index 347f777187af7..01943f40d41e8 100644 --- a/llvm/test/CodeGen/AArch64/regress-w29-reserved-with-fp.ll +++ b/llvm/test/CodeGen/AArch64/regress-w29-reserved-with-fp.ll @@ -1,26 +1,11 @@ -; RUN: llc -mtriple=aarch64-none-linux-gnu -frame-pointer=none < %s | \ -; RUN: FileCheck %s --check-prefixes=CHECK,NONE -; RUN: llc -mtriple=aarch64-none-linux-gnu -frame-pointer=reserved < %s | \ -; RUN: FileCheck %s --check-prefixes=CHECK,RESERVED -; RUN: llc -mtriple=aarch64-none-linux-gnu -frame-pointer=all < %s | \ -; RUN: FileCheck %s --check-prefixes=CHECK,ALL - -; By default, Darwin and Windows will reserve x29 -; RUN: llc -mtriple=aarch64-darwin -frame-pointer=none < %s | \ -; RUN: FileCheck %s --check-prefixes=CHECK,RESERVED -; RUN: llc -mtriple=aarch64-darwin -frame-pointer=none < %s | \ -; RUN: FileCheck %s --check-prefixes=CHECK,RESERVED +; RUN: llc -mtriple=aarch64-none-linux-gnu -frame-pointer=all < %s | FileCheck %s @var = global i32 0 declare void @bar() define void @test_w29_reserved() { ; CHECK-LABEL: test_w29_reserved: -; ALL: add x29, sp -; NONE-NOT: add x29 -; NONE-NOT: mov x29 -; RESERVED-NOT: add x29 -; RESERVED-NOT: mov x29 +; CHECK: mov x29, sp %val1 = load volatile i32, ptr @var %val2 = load volatile i32, ptr @var @@ -31,11 +16,8 @@ define void @test_w29_reserved() { %val7 = load volatile i32, ptr @var %val8 = load volatile i32, ptr @var %val9 = load volatile i32, ptr @var - %val10 = load volatile i32, ptr @var -; NONE: ldr w29, -; ALL-NOT: ldr w29, -; RESERVED-NOT: ldr w29, +; CHECK-NOT: ldr w29, ; Call to prevent fp-elim that occurs regardless in leaf functions. call void @bar() @@ -49,7 +31,6 @@ define void @test_w29_reserved() { store volatile i32 %val7, ptr @var store volatile i32 %val8, ptr @var store volatile i32 %val9, ptr @var - store volatile i32 %val10, ptr @var ret void ; CHECK: ret diff --git a/llvm/test/CodeGen/AArch64/win-sve.ll b/llvm/test/CodeGen/AArch64/win-sve.ll index 53ac9344175a3..691230af3e67d 100644 --- a/llvm/test/CodeGen/AArch64/win-sve.ll +++ b/llvm/test/CodeGen/AArch64/win-sve.ll @@ -65,18 +65,14 @@ define i32 @f(<vscale x 2 x i64> %x) { ; CHECK-NEXT: .seh_save_zreg z22, 16 ; CHECK-NEXT: str z23, [sp, #17, mul vl] // 16-byte Folded Spill ; CHECK-NEXT: .seh_save_zreg z23, 17 -; CHECK-NEXT: str x28, [sp, #-16]! // 8-byte Folded Spill -; CHECK-NEXT: .seh_save_reg_x x28, 16 -; CHECK-NEXT: str x30, [sp, #8] // 8-byte Folded Spill -; CHECK-NEXT: .seh_save_reg x30, 8 +; CHECK-NEXT: stp x29, x30, [sp, #-16]! // 16-byte Folded Spill +; CHECK-NEXT: .seh_save_fplr_x 16 ; CHECK-NEXT: .seh_endprologue ; CHECK-NEXT: bl g ; CHECK-NEXT: mov w0, #3 // =0x3 ; CHECK-NEXT: .seh_startepilogue -; CHECK-NEXT: ldr x30, [sp, #8] // 8-byte Folded Reload -; CHECK-NEXT: .seh_save_reg x30, 8 -; CHECK-NEXT: ldr x28, [sp] // 8-byte Folded Reload -; CHECK-NEXT: .seh_save_reg x28, 0 +; CHECK-NEXT: ldp x29, x30, [sp] // 16-byte Folded Reload +; CHECK-NEXT: .seh_save_fplr 0 ; CHECK-NEXT: add sp, sp, #16 ; CHECK-NEXT: .seh_stackalloc 16 ; CHECK-NEXT: ldr z8, [sp, #2, mul vl] // 16-byte Folded Reload @@ -369,10 +365,8 @@ define void @f3(i64 %n, <vscale x 2 x i64> %x) { ; CHECK-NEXT: .seh_save_zreg z22, 16 ; CHECK-NEXT: str z23, [sp, #17, mul vl] // 16-byte Folded Spill ; CHECK-NEXT: .seh_save_zreg z23, 17 -; CHECK-NEXT: str x28, [sp, #-16]! // 8-byte Folded Spill -; CHECK-NEXT: .seh_save_reg_x x28, 16 -; CHECK-NEXT: str x30, [sp, #8] // 8-byte Folded Spill -; CHECK-NEXT: .seh_save_reg x30, 8 +; CHECK-NEXT: stp x29, x30, [sp, #-16]! // 16-byte Folded Spill +; CHECK-NEXT: .seh_save_fplr_x 16 ; CHECK-NEXT: sub sp, sp, #16 ; CHECK-NEXT: .seh_stackalloc 16 ; CHECK-NEXT: .seh_endprologue @@ -382,10 +376,8 @@ define void @f3(i64 %n, <vscale x 2 x i64> %x) { ; CHECK-NEXT: .seh_startepilogue ; CHECK-NEXT: add sp, sp, #16 ; CHECK-NEXT: .seh_stackalloc 16 -; CHECK-NEXT: ldr x30, [sp, #8] // 8-byte Folded Reload -; CHECK-NEXT: .seh_save_reg x30, 8 -; CHECK-NEXT: ldr x28, [sp] // 8-byte Folded Reload -; CHECK-NEXT: .seh_save_reg x28, 0 +; CHECK-NEXT: ldp x29, x30, [sp] // 16-byte Folded Reload +; CHECK-NEXT: .seh_save_fplr 0 ; CHECK-NEXT: add sp, sp, #16 ; CHECK-NEXT: .seh_stackalloc 16 ; CHECK-NEXT: ldr z8, [sp, #2, mul vl] // 16-byte Folded Reload @@ -519,10 +511,8 @@ define void @f4(i64 %n, <vscale x 2 x i64> %x) { ; CHECK-NEXT: .seh_save_zreg z22, 16 ; CHECK-NEXT: str z23, [sp, #17, mul vl] // 16-byte Folded Spill ; CHECK-NEXT: .seh_save_zreg z23, 17 -; CHECK-NEXT: str x28, [sp, #-16]! // 8-byte Folded Spill -; CHECK-NEXT: .seh_save_reg_x x28, 16 -; CHECK-NEXT: str x30, [sp, #8] // 8-byte Folded Spill -; CHECK-NEXT: .seh_save_reg x30, 8 +; CHECK-NEXT: stp x29, x30, [sp, #-16]! // 16-byte Folded Spill +; CHECK-NEXT: .seh_save_fplr_x 16 ; CHECK-NEXT: sub sp, sp, #16 ; CHECK-NEXT: .seh_stackalloc 16 ; CHECK-NEXT: addvl sp, sp, #-1 @@ -536,10 +526,8 @@ define void @f4(i64 %n, <vscale x 2 x i64> %x) { ; CHECK-NEXT: .seh_allocz 1 ; CHECK-NEXT: add sp, sp, #16 ; CHECK-NEXT: .seh_stackalloc 16 -; CHECK-NEXT: ldr x30, [sp, #8] // 8-byte Folded Reload -; CHECK-NEXT: .seh_save_reg x30, 8 -; CHECK-NEXT: ldr x28, [sp] // 8-byte Folded Reload -; CHECK-NEXT: .seh_save_reg x28, 0 +; CHECK-NEXT: ldp x29, x30, [sp] // 16-byte Folded Reload +; CHECK-NEXT: .seh_save_fplr 0 ; CHECK-NEXT: add sp, sp, #16 ; CHECK-NEXT: .seh_stackalloc 16 ; CHECK-NEXT: ldr z8, [sp, #2, mul vl] // 16-byte Folded Reload @@ -1105,10 +1093,8 @@ define void @f7(i64 %n) { ; CHECK-LABEL: f7: ; CHECK: .seh_proc f7 ; CHECK-NEXT: // %bb.0: -; CHECK-NEXT: str x28, [sp, #-16]! // 8-byte Folded Spill -; CHECK-NEXT: .seh_save_reg_x x28, 16 -; CHECK-NEXT: str x30, [sp, #8] // 8-byte Folded Spill -; CHECK-NEXT: .seh_save_reg x30, 8 +; CHECK-NEXT: stp x29, x30, [sp, #-16]! // 16-byte Folded Spill +; CHECK-NEXT: .seh_save_fplr_x 16 ; CHECK-NEXT: addvl sp, sp, #-1 ; CHECK-NEXT: .seh_allocz 1 ; CHECK-NEXT: .seh_endprologue @@ -1117,10 +1103,8 @@ define void @f7(i64 %n) { ; CHECK-NEXT: .seh_startepilogue ; CHECK-NEXT: addvl sp, sp, #1 ; CHECK-NEXT: .seh_allocz 1 -; CHECK-NEXT: ldr x30, [sp, #8] // 8-byte Folded Reload -; CHECK-NEXT: .seh_save_reg x30, 8 -; CHECK-NEXT: ldr x28, [sp], #16 // 8-byte Folded Reload -; CHECK-NEXT: .seh_save_reg_x x28, 16 +; CHECK-NEXT: ldp x29, x30, [sp], #16 // 16-byte Folded Reload +; CHECK-NEXT: .seh_save_fplr_x 16 ; CHECK-NEXT: .seh_endepilogue ; CHECK-NEXT: ret ; CHECK-NEXT: .seh_endfunclet diff --git a/llvm/test/CodeGen/AArch64/wincfi-missing-seh-directives.ll b/llvm/test/CodeGen/AArch64/wincfi-missing-seh-directives.ll index 6d14abdc2ed75..2002c37cb2528 100644 --- a/llvm/test/CodeGen/AArch64/wincfi-missing-seh-directives.ll +++ b/llvm/test/CodeGen/AArch64/wincfi-missing-seh-directives.ll @@ -5,23 +5,25 @@ ; prologue has a corresponding seh directive. ; ; CHECK-NOT: error: Incorrect size for -; CHECK-LABEL: foo: -; CHECK-NEXT: .seh_proc foo -; CHECK: sub sp, sp, #496 -; CHECK-NEXT: .seh_stackalloc 496 -; CHECK-NEXT: str x19, [sp, #208] // 8-byte Folded Spill -; CHECK-NEXT: .seh_save_reg x19, 208 -; CHECK-NEXT: str x21, [sp, #216] // 8-byte Folded Spill -; CHECK-NEXT: .seh_save_reg x21, 216 -; CHECK-NEXT: stp x23, x24, [sp, #224] // 16-byte Folded Spill -; CHECK-NEXT: .seh_save_regp x23, 224 -; CHECK-NEXT: stp x25, x26, [sp, #240] // 16-byte Folded Spill -; CHECK-NEXT: .seh_save_regp x25, 240 -; CHECK-NEXT: stp x27, x28, [sp, #256] // 16-byte Folded Spill -; CHECK-NEXT: .seh_save_regp x27, 256 -; CHECK-NEXT: str x30, [sp, #272] // 8-byte Folded Spill -; CHECK-NEXT: .seh_save_reg x30, 272 -; CHECK-NEXT: .seh_endprologue +; CHECK: foo: +; CHECK: .seh_proc foo +; CHECK: sub sp, sp, #288 +; CHECK: .seh_stackalloc 288 +; CHECK: str x19, [sp] // 8-byte Folded Spill +; CHECK: .seh_save_reg x19, 0 +; CHECK: str x21, [sp, #8] // 8-byte Folded Spill +; CHECK: .seh_save_reg x21, 8 +; CHECK: stp x23, x24, [sp, #16] // 16-byte Folded Spill +; CHECK: .seh_save_regp x23, 16 +; CHECK: stp x25, x26, [sp, #32] // 16-byte Folded Spill +; CHECK: .seh_save_regp x25, 32 +; CHECK: stp x27, x28, [sp, #48] // 16-byte Folded Spill +; CHECK: .seh_save_regp x27, 48 +; CHECK: stp x29, x30, [sp, #64] // 16-byte Folded Spill +; CHECK: .seh_save_fplr 64 +; CHECK: sub sp, sp, #224 +; CHECK: .seh_stackalloc 224 +; CHECK: .seh_endprologue target datalayout = "e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128-Fn32" target triple = "aarch64-unknown-windows-msvc19.42.34436" diff --git a/llvm/test/CodeGen/AArch64/wineh-frame5.mir b/llvm/test/CodeGen/AArch64/wineh-frame5.mir index 0589d97ca64a2..180c20f0148f5 100644 --- a/llvm/test/CodeGen/AArch64/wineh-frame5.mir +++ b/llvm/test/CodeGen/AArch64/wineh-frame5.mir @@ -5,10 +5,8 @@ # CHECK-LABEL: bb.0.entry: # CHECK: early-clobber $sp = frame-setup STRXpre killed $x19, $sp, -32 # CHECK-NEXT: frame-setup SEH_SaveReg_X 19, -32 -# CHECK-NEXT: frame-setup STRXui killed $x28, $sp, 1 -# CHECK-NEXT: frame-setup SEH_SaveReg 28, 8 -# CHECK-NEXT: frame-setup STRXui killed $lr, $sp, 2 -# CHECK-NEXT: frame-setup SEH_SaveReg 30, 16 +# CHECK-NEXT: frame-setup STPXi killed $fp, killed $lr, $sp, 1 +# CHECK-NEXT: frame-setup SEH_SaveFPLR 8 # CHECK-NEXT: $sp = frame-setup SUBXri $sp, 496, 0 # CHECK-NEXT: frame-setup SEH_StackAlloc 496 # CHECK-NEXT: frame-setup SEH_PrologEnd @@ -17,10 +15,8 @@ # CHECK: frame-destroy SEH_EpilogStart # CHECK-NEXT: $sp = frame-destroy ADDXri $sp, 496, 0 # CHECK-NEXT: frame-destroy SEH_StackAlloc 496 -# CHECK-NEXT: $lr = frame-destroy LDRXui $sp, 2 -# CHECK-NEXT: frame-destroy SEH_SaveReg 30, 16 -# CHECK-NEXT: $x28 = frame-destroy LDRXui $sp, 1 -# CHECK-NEXT: frame-destroy SEH_SaveReg 28, 8 +# CHECK-NEXT: $fp, $lr = frame-destroy LDPXi $sp, 1 +# CHECK-NEXT: frame-destroy SEH_SaveFPLR 8 # CHECK-NEXT: early-clobber $sp, $x19 = frame-destroy LDRXpost $sp, 32 # CHECK-NEXT: frame-destroy SEH_SaveReg_X 19, -32 # CHECK-NEXT: frame-destroy SEH_EpilogEnd diff --git a/llvm/test/CodeGen/AArch64/wineh-frame7.mir b/llvm/test/CodeGen/AArch64/wineh-frame7.mir index b30afd2b57153..6d44ad3716111 100644 --- a/llvm/test/CodeGen/AArch64/wineh-frame7.mir +++ b/llvm/test/CodeGen/AArch64/wineh-frame7.mir @@ -3,15 +3,13 @@ # Test that stack probe results in Nop unwind codes in the prologue. Test # save_fplr, save_reg_x and stack_alloc with multiple updates. -# CHECK: early-clobber $sp = frame-setup STRXpre killed $x28, $sp, -32 -# CHECK-NEXT: frame-setup SEH_SaveReg_X 28, -32 -# CHECK-NEXT: frame-setup STPXi killed $fp, killed $lr, $sp, 1 -# CHECK-NEXT: frame-setup SEH_SaveFPLR 8 +# CHECK: early-clobber $sp = frame-setup STPXpre killed $fp, killed $lr, $sp, -2 +# CHECK-NEXT: frame-setup SEH_SaveFPLR_X -16 # CHECK-NEXT: $x15 = frame-setup MOVZXi 56009, 0 # CHECK-NEXT: frame-setup SEH_Nop # CHECK-NEXT: $x15 = frame-setup MOVKXi $x15, 2, 16 # CHECK-NEXT: frame-setup SEH_Nop -# 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 +# CHECK-NEXT: frame-setup BL &__chkstk, implicit-def $lr, implicit $sp, implicit $x15 # CHECK-NEXT: frame-setup SEH_Nop # CHECK-NEXT: $sp = frame-setup SUBXrx64 killed $sp, killed $x15, 28 # CHECK-NEXT: frame-setup SEH_StackAlloc 2993296 @@ -21,10 +19,8 @@ # CHECK-NEXT: frame-destroy SEH_StackAlloc 2990080 # CHECK-NEXT: $sp = frame-destroy ADDXri $sp, 3216, 0 # CHECK-NEXT: frame-destroy SEH_StackAlloc 3216 -# CHECK-NEXT: $fp, $lr = frame-destroy LDPXi $sp, 1 -# CHECK-NEXT: frame-destroy SEH_SaveFPLR 8 -# CHECK-NEXT: early-clobber $sp, $x28 = frame-destroy LDRXpost $sp, 32 -# CHECK-NEXT: frame-destroy SEH_SaveReg_X 28, -32 +# CHECK-NEXT: early-clobber $sp, $fp, $lr = frame-destroy LDPXpost $sp, 2 +# CHECK-NEXT: frame-destroy SEH_SaveFPLR_X -16 # CHECK-NEXT: frame-destroy SEH_EpilogEnd # CHECK-NEXT: RET_ReallyLR implicit killed $w0 --- | _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits