[llvm] 988a533 - [Win64] Ensure all stack frames are 8 byte aligned
Reid Kleckner via llvm-commits
llvm-commits at lists.llvm.org
Mon Jan 25 10:39:34 PST 2021
Author: Reid Kleckner
Date: 2021-01-25T10:39:27-08:00
New Revision: 988a5334ed40ee65c91bf30be93631b092316390
URL: https://github.com/llvm/llvm-project/commit/988a5334ed40ee65c91bf30be93631b092316390
DIFF: https://github.com/llvm/llvm-project/commit/988a5334ed40ee65c91bf30be93631b092316390.diff
LOG: [Win64] Ensure all stack frames are 8 byte aligned
The unwind info format requires that all adjustments are 8 byte aligned,
and the bottom three bits are masked out. Most Win64 calling conventions
have 32 bytes of shadow stack space for spilling parameters, and I
believe that constructing these fixed stack objects had the side effect
of ensuring an alignment of 8. However, the Intel regcall convention
does not have this shadow space, so when using that convention, it was
possible to make a 4 byte stack frame, which was impossible to describe
with unwind info.
Fixes pr48867
Added:
llvm/test/CodeGen/X86/win64_regcall.ll
Modified:
llvm/lib/Target/X86/X86FrameLowering.cpp
llvm/lib/Target/X86/X86FrameLowering.h
Removed:
################################################################################
diff --git a/llvm/lib/Target/X86/X86FrameLowering.cpp b/llvm/lib/Target/X86/X86FrameLowering.cpp
index 8339f512158d..866f11364004 100644
--- a/llvm/lib/Target/X86/X86FrameLowering.cpp
+++ b/llvm/lib/Target/X86/X86FrameLowering.cpp
@@ -3516,13 +3516,21 @@ void X86FrameLowering::processFunctionBeforeFrameFinalized(
// emitPrologue if it gets called and emits CFI.
MF.setHasWinCFI(false);
+ // If we are using Windows x64 CFI, ensure that the stack is always 8 byte
+ // aligned. The format doesn't support misaligned stack adjustments.
+ if (MF.getTarget().getMCAsmInfo()->usesWindowsCFI())
+ MF.getFrameInfo().ensureMaxAlignment(Align(SlotSize));
+
// If this function isn't doing Win64-style C++ EH, we don't need to do
// anything.
- const Function &F = MF.getFunction();
- if (!STI.is64Bit() || !MF.hasEHFunclets() ||
- classifyEHPersonality(F.getPersonalityFn()) != EHPersonality::MSVC_CXX)
- return;
+ if (STI.is64Bit() && MF.hasEHFunclets() &&
+ classifyEHPersonality(MF.getFunction().getPersonalityFn()) ==
+ EHPersonality::MSVC_CXX) {
+ adjustFrameForMsvcCxxEh(MF);
+ }
+}
+void X86FrameLowering::adjustFrameForMsvcCxxEh(MachineFunction &MF) const {
// Win64 C++ EH needs to allocate the UnwindHelp object at some fixed offset
// relative to RSP after the prologue. Find the offset of the last fixed
// object, so that we can allocate a slot immediately following it. If there
diff --git a/llvm/lib/Target/X86/X86FrameLowering.h b/llvm/lib/Target/X86/X86FrameLowering.h
index f77a4843bba4..26e80811af2e 100644
--- a/llvm/lib/Target/X86/X86FrameLowering.h
+++ b/llvm/lib/Target/X86/X86FrameLowering.h
@@ -224,6 +224,8 @@ class X86FrameLowering : public TargetFrameLowering {
const DebugLoc &DL, uint64_t Offset,
uint64_t Align) const;
+ void adjustFrameForMsvcCxxEh(MachineFunction &MF) const;
+
/// Aligns the stack pointer by ANDing it with -MaxAlign.
void BuildStackAlignAND(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MBBI, const DebugLoc &DL,
diff --git a/llvm/test/CodeGen/X86/win64_regcall.ll b/llvm/test/CodeGen/X86/win64_regcall.ll
new file mode 100644
index 000000000000..4cd051928f36
--- /dev/null
+++ b/llvm/test/CodeGen/X86/win64_regcall.ll
@@ -0,0 +1,12 @@
+; RUN: llc < %s -mtriple=x86_64-windows-msvc | FileCheck %s
+
+define dso_local x86_regcallcc void @ensure_align() local_unnamed_addr #0 {
+entry:
+ %b = alloca i32, align 4
+ call void asm sideeffect "nopl $0", "=*m,~{dirflag},~{fpsr},~{flags}"(i32* nonnull %b)
+ ret void
+}
+
+; CHECK-LABEL: ensure_align: # @ensure_align
+; CHECK: .seh_stackalloc 8
+; CHECK: .seh_endprologue
More information about the llvm-commits
mailing list