[llvm] [X86] Don't discard over-16 stack alignment for 32-bit interrupt handlers (PR #225366)
Timur Golubovich via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 22 04:11:11 PDT 2026
https://github.com/timurgol007 created https://github.com/llvm/llvm-project/pull/225366
calculateMaxStackAlign assigned Align(16) instead of taking the maximum, so an alloca with align 64 in a 32-bit handler got andl $-16 and landed only 16-byte aligned, even though PEI had laid the frame out for 64. With AVX512 the compiler then emits vmovaps to that object, which faults.
>From 5a9d3a6949a9efeda4c7f7ca64a4ce1c4a0997a6 Mon Sep 17 00:00:00 2001
From: Timur Golubovich <timur.golubovich at intel.com>
Date: Wed, 16 Sep 2026 15:39:48 +0200
Subject: [PATCH] [X86] Don't discard over-16 stack alignment for 32-bit
interrupt handlers
calculateMaxStackAlign assigned Align(16) instead of taking the maximum, so
an alloca with align 64 in a 32-bit handler got andl $-16 and landed only
16-byte aligned, even though PEI had laid the frame out for 64. With AVX512
the compiler then emits vmovaps to that object, which faults.
---
llvm/lib/Target/X86/X86FrameLowering.cpp | 9 +++------
llvm/test/CodeGen/X86/x86-interrupt_cc.ll | 12 ++++++------
2 files changed, 9 insertions(+), 12 deletions(-)
diff --git a/llvm/lib/Target/X86/X86FrameLowering.cpp b/llvm/lib/Target/X86/X86FrameLowering.cpp
index fad665e31bbe5..5b9251917a634 100644
--- a/llvm/lib/Target/X86/X86FrameLowering.cpp
+++ b/llvm/lib/Target/X86/X86FrameLowering.cpp
@@ -1351,12 +1351,9 @@ X86FrameLowering::calculateMaxStackAlign(const MachineFunction &MF) const {
MaxAlign = Align(SlotSize);
}
- if (!Is64Bit && MF.getFunction().getCallingConv() == CallingConv::X86_INTR) {
- if (HasRealign)
- MaxAlign = (MaxAlign > 16) ? MaxAlign : Align(16);
- else
- MaxAlign = Align(16);
- }
+ if (!Is64Bit && MF.getFunction().getCallingConv() == CallingConv::X86_INTR)
+ MaxAlign = std::max(MaxAlign, Align(16));
+
return MaxAlign.value();
}
diff --git a/llvm/test/CodeGen/X86/x86-interrupt_cc.ll b/llvm/test/CodeGen/X86/x86-interrupt_cc.ll
index ff40a3404d5ef..c6777d18f898a 100644
--- a/llvm/test/CodeGen/X86/x86-interrupt_cc.ll
+++ b/llvm/test/CodeGen/X86/x86-interrupt_cc.ll
@@ -514,9 +514,9 @@ define x86_intrcc void @foo(ptr byval(i8) %frame) {
; CHECK32-KNL-NEXT: pushl %edx ## encoding: [0x52]
; CHECK32-KNL-NEXT: pushl %ecx ## encoding: [0x51]
; CHECK32-KNL-NEXT: pushl %eax ## encoding: [0x50]
-; CHECK32-KNL-NEXT: andl $-16, %esp ## encoding: [0x83,0xe4,0xf0]
-; CHECK32-KNL-NEXT: subl $560, %esp ## encoding: [0x81,0xec,0x30,0x02,0x00,0x00]
-; CHECK32-KNL-NEXT: ## imm = 0x230
+; CHECK32-KNL-NEXT: andl $-64, %esp ## encoding: [0x83,0xe4,0xc0]
+; CHECK32-KNL-NEXT: subl $576, %esp ## encoding: [0x81,0xec,0x40,0x02,0x00,0x00]
+; CHECK32-KNL-NEXT: ## imm = 0x240
; CHECK32-KNL-NEXT: kmovw %k7, {{[-0-9]+}}(%e{{[sb]}}p) ## 2-byte Spill
; CHECK32-KNL-NEXT: ## encoding: [0xc5,0xf8,0x91,0x7d,0xf2]
; CHECK32-KNL-NEXT: kmovw %k6, {{[-0-9]+}}(%e{{[sb]}}p) ## 2-byte Spill
@@ -620,9 +620,9 @@ define x86_intrcc void @foo(ptr byval(i8) %frame) {
; CHECK32-SKX-NEXT: pushl %edx ## encoding: [0x52]
; CHECK32-SKX-NEXT: pushl %ecx ## encoding: [0x51]
; CHECK32-SKX-NEXT: pushl %eax ## encoding: [0x50]
-; CHECK32-SKX-NEXT: andl $-16, %esp ## encoding: [0x83,0xe4,0xf0]
-; CHECK32-SKX-NEXT: subl $624, %esp ## encoding: [0x81,0xec,0x70,0x02,0x00,0x00]
-; CHECK32-SKX-NEXT: ## imm = 0x270
+; CHECK32-SKX-NEXT: andl $-64, %esp ## encoding: [0x83,0xe4,0xc0]
+; CHECK32-SKX-NEXT: subl $640, %esp ## encoding: [0x81,0xec,0x80,0x02,0x00,0x00]
+; CHECK32-SKX-NEXT: ## imm = 0x280
; CHECK32-SKX-NEXT: kmovq %k7, {{[-0-9]+}}(%e{{[sb]}}p) ## 8-byte Spill
; CHECK32-SKX-NEXT: ## encoding: [0xc4,0xe1,0xf8,0x91,0x7d,0xe8]
; CHECK32-SKX-NEXT: kmovq %k6, {{[-0-9]+}}(%e{{[sb]}}p) ## 8-byte Spill
More information about the llvm-commits
mailing list