[llvm] [X86] Don't discard over-16 stack alignment for 32-bit interrupt handlers (PR #225366)

via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 22 04:11:54 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-x86

Author: Timur Golubovich (timurgol007)

<details>
<summary>Changes</summary>

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.

---
Full diff: https://github.com/llvm/llvm-project/pull/225366.diff


2 Files Affected:

- (modified) llvm/lib/Target/X86/X86FrameLowering.cpp (+3-6) 
- (modified) llvm/test/CodeGen/X86/x86-interrupt_cc.ll (+6-6) 


``````````diff
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

``````````

</details>


https://github.com/llvm/llvm-project/pull/225366


More information about the llvm-commits mailing list