diff --git a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp --- a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp @@ -1638,6 +1638,10 @@ if (EmitCFI) emitCalleeSavedGPRLocations(MBB, MBBI); + // Alignment is required for the parent frame, not the funclet + const bool NeedsRealignment = + NumBytes && !IsFunclet && RegInfo->hasStackRealignment(MF); + if (windowsRequiresStackProbe(MF, NumBytes)) { uint64_t NumWords = NumBytes >> 4; if (NeedsWinCFI) { @@ -1768,10 +1772,7 @@ (int64_t)MFI.getStackSize() - NumBytes)); // Allocate space for the rest of the frame. - if (NumBytes) { - // Alignment is required for the parent frame, not the funclet - const bool NeedsRealignment = - !IsFunclet && RegInfo->hasStackRealignment(MF); + if (NumBytes || NeedsRealignment) { unsigned scratchSPReg = AArch64::SP; if (NeedsRealignment) { @@ -1780,7 +1781,7 @@ } // If we're a leaf function, try using the red zone. - if (!canUseRedZone(MF)) { + if (NumBytes && !canUseRedZone(MF)) { // FIXME: in the case of dynamic re-alignment, NumBytes doesn't have // the correct value here, as NumBytes also includes padding bytes, // which shouldn't be counted here. @@ -1790,6 +1791,11 @@ false, NeedsWinCFI, &HasWinCFI, EmitCFI && !HasFP, SVEStackSize + StackOffset::getFixed((int64_t)MFI.getStackSize() - NumBytes)); + } else if (NeedsRealignment) { + BuildMI(MBB, MBBI, DL, TII->get(AArch64::ADDXri), scratchSPReg) + .addReg(AArch64::SP) + .addImm(0) + .addImm(0); } if (NeedsRealignment) { const unsigned NrBitsToZero = Log2(MFI.getMaxAlign()); diff --git a/llvm/test/CodeGen/AArch64/win-align-chkstk.ll b/llvm/test/CodeGen/AArch64/win-align-chkstk.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/win-align-chkstk.ll @@ -0,0 +1,27 @@ +; RUN: llc < %s -mtriple=aarch64-windows | FileCheck %s + +define dso_local void @func() { +entry: + %buf = alloca [8192 x i8], align 32 + %arraydecay = getelementptr inbounds [8192 x i8], ptr %buf, i64 0, i64 0 + call void @other(ptr noundef %arraydecay) + ret void +} + +declare dso_local void @other(ptr noundef) + +; CHECK-LABEL: func: +; CHECK-NEXT: .seh_proc func +; CHECK-NEXT: // %bb.0: +; CHECK-NEXT: str x28, [sp, #-32]! +; CHECK-NEXT: .seh_save_reg_x x28, 32 +; CHECK-NEXT: stp x29, x30, [sp, #8] +; CHECK-NEXT: .seh_save_fplr 8 +; CHECK-NEXT: add x29, sp, #8 +; CHECK-NEXT: .seh_add_fp 8 +; CHECK-NEXT: .seh_endprologue +; CHECK-NEXT: mov x15, #512 +; CHECK-NEXT: bl __chkstk +; CHECK-NEXT: sub sp, sp, x15, lsl #4 +; CHECK-NEXT: mov x9, sp +; CHECK-NEXT: and sp, x9, #0xffffffffffffffe0