[PATCH] D30049: x86 interrupt calling convention: re-align stack pointer on 64-bit if an error code was pushed

Philipp Oppermann via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Feb 16 11:44:38 PST 2017


phil-opp created this revision.

The x86_64 ABI requires that the stack is 16 byte aligned on function calls. Thus, the 8-byte error code, which is pushed by the CPU for certain exceptions, leads to a misaligned stack. This results in bugs such as Bug 26413 <https://bugs.llvm.org//show_bug.cgi?id=26413>, where misaligned movaps instructions are generated.

This commit fixes the misalignment by adjusting the stack pointer in these cases. The adjustment is done at the beginning of the prologue generation by subtracting another 8 bytes from the stack pointer. These additional bytes are popped again in the function epilogue.

Fixes Bug 26413 <https://bugs.llvm.org//show_bug.cgi?id=26413>


https://reviews.llvm.org/D30049

Files:
  lib/Target/X86/X86FrameLowering.cpp
  lib/Target/X86/X86ISelLowering.cpp
  test/CodeGen/X86/x86-64-intrcc-nosse.ll
  test/CodeGen/X86/x86-64-intrcc.ll


Index: test/CodeGen/X86/x86-64-intrcc.ll
===================================================================
--- test/CodeGen/X86/x86-64-intrcc.ll
+++ test/CodeGen/X86/x86-64-intrcc.ll
@@ -35,7 +35,7 @@
   ; CHECK: movq 40(%rsp), %rcx
   ; CHECK: popq %rcx
   ; CHECK: popq %rax
-  ; CHECK: addq $8, %rsp
+  ; CHECK: addq $16, %rsp
   ; CHECK: iretq
   ; CHECK0-LABEL: test_isr_ecode
   ; CHECK0: pushq %rax
@@ -45,7 +45,7 @@
   ; CHECK0: movq 16(%rcx), %rcx
   ; CHECK0: popq %rcx
   ; CHECK0: popq %rax
-  ; CHECK0: addq $8, %rsp
+  ; CHECK0: addq $16, %rsp
   ; CHECK0: iretq
   %pflags = getelementptr inbounds %struct.interrupt_frame, %struct.interrupt_frame* %frame, i32 0, i32 2
   %flags = load i64, i64* %pflags, align 4
Index: test/CodeGen/X86/x86-64-intrcc-nosse.ll
===================================================================
--- test/CodeGen/X86/x86-64-intrcc-nosse.ll
+++ test/CodeGen/X86/x86-64-intrcc-nosse.ll
@@ -9,10 +9,11 @@
 define x86_intrcc void @test_isr_sse_clobbers(%struct.interrupt_frame* %frame, i64 %ecode) {
   ; CHECK-LABEL: test_isr_sse_clobbers:
   ; CHECK:       # BB#0:
+  ; CHECK-NEXT:    pushq %rax
   ; CHECK-NEXT:    cld
   ; CHECK-NEXT:    #APP
   ; CHECK-NEXT:    #NO_APP
-  ; CHECK-NEXT:    addq $8, %rsp
+  ; CHECK-NEXT:    addq $16, %rsp
   ; CHECK-NEXT:    iretq
   call void asm sideeffect "", "~{xmm0},~{xmm6}"()
   ret void
Index: lib/Target/X86/X86ISelLowering.cpp
===================================================================
--- lib/Target/X86/X86ISelLowering.cpp
+++ lib/Target/X86/X86ISelLowering.cpp
@@ -3113,8 +3113,9 @@
                        MF.getTarget().Options.GuaranteedTailCallOpt)) {
     FuncInfo->setBytesToPopOnReturn(StackSize); // Callee pops everything.
   } else if (CallConv == CallingConv::X86_INTR && Ins.size() == 2) {
-    // X86 interrupts must pop the error code if present
-    FuncInfo->setBytesToPopOnReturn(Is64Bit ? 8 : 4);
+    // X86 interrupts must pop the error code (and the alignment padding)
+    // if present
+    FuncInfo->setBytesToPopOnReturn(Is64Bit ? 16 : 4);
   } else {
     FuncInfo->setBytesToPopOnReturn(0); // Callee pops nothing.
     // If this is an sret function, the return should pop the hidden pointer.
Index: lib/Target/X86/X86FrameLowering.cpp
===================================================================
--- lib/Target/X86/X86FrameLowering.cpp
+++ lib/Target/X86/X86FrameLowering.cpp
@@ -959,6 +959,15 @@
         .getValueAsString()
         .getAsInteger(0, StackProbeSize);
 
+  // Re-align the stack on 64-bit if the x86-interrupt calling convention is used
+  // and an error code was pushed, since the x86-64 ABI requires a 16-byte stack
+  // alignment.
+  if (Fn->getCallingConv() == CallingConv::X86_INTR && Is64Bit && Fn->arg_size() == 2) {
+    StackSize += 8;
+    MFI.setStackSize(StackSize);
+    emitSPUpdate(MBB, MBBI, -8, /*InEpilogue=*/false);
+  }
+
   // If this is x86-64 and the Red Zone is not disabled, if we are a leaf
   // function, and use up to 128 bytes of stack space, don't have a frame
   // pointer, calls, or dynamic alloca then we do not need to adjust the


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D30049.88761.patch
Type: text/x-patch
Size: 3127 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170216/33f3c330/attachment.bin>


More information about the llvm-commits mailing list