diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp @@ -4334,8 +4334,6 @@ int Imm = (int)(ThisVal << LocalShiftSize); if ((DestReg == AArch64::FP && SrcReg == AArch64::SP) || (SrcReg == AArch64::FP && DestReg == AArch64::SP)) { - if (HasWinCFI) - *HasWinCFI = true; if (Imm == 0) BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_SetFP)).setMIFlag(Flag); else @@ -4345,12 +4343,13 @@ assert(Offset == 0 && "Expected remaining offset to be zero to " "emit a single SEH directive"); } else if (DestReg == AArch64::SP) { - if (HasWinCFI) - *HasWinCFI = true; assert(SrcReg == AArch64::SP && "Unexpected SrcReg for SEH_StackAlloc"); BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_StackAlloc)) .addImm(Imm) .setMIFlag(Flag); + } else { + BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_Nop)) + .setMIFlag(Flag); } if (HasWinCFI) *HasWinCFI = true; diff --git a/llvm/test/CodeGen/AArch64/wineh-align-stack.ll b/llvm/test/CodeGen/AArch64/wineh-align-stack.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/wineh-align-stack.ll @@ -0,0 +1,27 @@ +; RUN: llc < %s -mtriple=aarch64-windows | FileCheck %s + +define dso_local void @func() { +entry: + %buf = alloca [64 x i8], align 32 + %arraydecay = getelementptr inbounds [64 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: stp x29, x30, [sp, #-16]! +; CHECK-NEXT: .seh_save_fplr_x 16 +; CHECK-NEXT: mov x29, sp +; CHECK-NEXT: .seh_set_fp +; CHECK-NEXT: sub x9, sp, #80 +; CHECK-NEXT: .seh_nop +; CHECK-NEXT: and sp, x9, #0xffffffffffffffe0 +; CHECK-NEXT: .seh_stackalloc 80 +; CHECK-NEXT: .seh_endprologue + +; FIXME: Ideally, the SEH prologue wouldn't include the stack realigning +; instructions at all, but it's enough to end the prologue after .seh_set_fp.