[llvm] r262294 - [WinEH] Allocate the registration node before the catch objects

David Majnemer via llvm-commits llvm-commits at lists.llvm.org
Mon Feb 29 20:30:16 PST 2016


Author: majnemer
Date: Mon Feb 29 22:30:16 2016
New Revision: 262294

URL: http://llvm.org/viewvc/llvm-project?rev=262294&view=rev
Log:
[WinEH] Allocate the registration node before the catch objects

The CatchObjOffset is relative to the end of the EH registration node
for 32-bit x86 WinEH targets.  A special sentinel value, 0, is used to
indicate that no catch object should be initialized.

This means that a catch object allocated immediately before the
registration node would be assigned a CatchObjOffset of 0, leading the
runtime to believe that a catch object should not be initialized.

To handle this, allocate the registration node prior to any other frame
object.  This will ensure that catch objects will not be allocated
before the registration node.

This fixes PR26757.

Differential Revision: http://reviews.llvm.org/D17689

Added:
    llvm/trunk/test/CodeGen/X86/pr26757.ll
Modified:
    llvm/trunk/lib/CodeGen/AsmPrinter/WinException.cpp
    llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp
    llvm/trunk/test/CodeGen/X86/cleanuppad-inalloca.ll

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/WinException.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/WinException.cpp?rev=262294&r1=262293&r2=262294&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/WinException.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/WinException.cpp Mon Feb 29 22:30:16 2016
@@ -793,6 +793,7 @@ void WinException::emitCXXFrameHandler3T
         const MCExpr *FrameAllocOffsetRef = nullptr;
         if (HT.CatchObj.FrameIndex != INT_MAX) {
           int Offset = getFrameIndexOffset(HT.CatchObj.FrameIndex, FuncInfo);
+          assert(Offset != 0 && "Illegal offset for catch object!");
           FrameAllocOffsetRef = MCConstantExpr::create(Offset, Asm->OutContext);
         } else {
           FrameAllocOffsetRef = MCConstantExpr::create(0, Asm->OutContext);

Modified: llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp?rev=262294&r1=262293&r2=262294&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp (original)
+++ llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp Mon Feb 29 22:30:16 2016
@@ -709,6 +709,10 @@ void PEI::calculateFrameObjectOffsets(Ma
 
   SmallVector<int, 8> ObjectsToAllocate;
 
+  int EHRegNodeFrameIndex = INT_MAX;
+  if (const WinEHFuncInfo *FuncInfo = Fn.getWinEHFuncInfo())
+    EHRegNodeFrameIndex = FuncInfo->EHRegNodeFrameIndex;
+
   // Then prepare to assign frame offsets to stack objects that are not used to
   // spill callee saved registers.
   for (unsigned i = 0, e = MFI->getObjectIndexEnd(); i != e; ++i) {
@@ -723,12 +727,20 @@ void PEI::calculateFrameObjectOffsets(Ma
       continue;
     if (MFI->getStackProtectorIndex() == (int)i)
       continue;
+    if (EHRegNodeFrameIndex == (int)i)
+      continue;
     if (ProtectedObjs.count(i))
       continue;
 
     // Add the objects that we need to allocate to our working set.
     ObjectsToAllocate.push_back(i);
   }
+
+  // Allocate the EH registration node first if one is present.
+  if (EHRegNodeFrameIndex != INT_MAX)
+    AdjustStackOffset(MFI, EHRegNodeFrameIndex, StackGrowsDown, Offset,
+                      MaxAlign, Skew);
+
   // Give the targets a chance to order the objects the way they like it.
   if (Fn.getTarget().getOptLevel() != CodeGenOpt::None &&
       Fn.getTarget().Options.StackSymbolOrdering)

Modified: llvm/trunk/test/CodeGen/X86/cleanuppad-inalloca.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/cleanuppad-inalloca.ll?rev=262294&r1=262293&r2=262294&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/cleanuppad-inalloca.ll (original)
+++ llvm/trunk/test/CodeGen/X86/cleanuppad-inalloca.ll Mon Feb 29 22:30:16 2016
@@ -51,7 +51,7 @@ ehcleanup:
 ; CHECK: "?dtor$2@?0?passes_two at 4HA":
 ; CHECK: pushl %ebp
 ; CHECK: subl $8, %esp
-; CHECK: addl $16, %ebp
+; CHECK: addl $12, %ebp
 ; CHECK: {{movl|leal}} -{{[0-9]+}}(%ebp), %ecx
 ; CHECK: calll "??1A@@QAE at XZ"
 ; CHECK: addl $8, %esp

Added: llvm/trunk/test/CodeGen/X86/pr26757.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/pr26757.ll?rev=262294&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/pr26757.ll (added)
+++ llvm/trunk/test/CodeGen/X86/pr26757.ll Mon Feb 29 22:30:16 2016
@@ -0,0 +1,34 @@
+; RUN: llc < %s | FileCheck %s
+target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
+target triple = "i386-pc-windows-msvc"
+
+declare void @throw()
+
+define void @test1() personality i32 (...)* @__CxxFrameHandler3 {
+  %e = alloca i8, align 4
+  invoke void @throw()
+          to label %.noexc unwind label %catch.dispatch
+
+.noexc:
+  unreachable
+
+catch.object.Exception:
+  %cp = catchpad within %cs [i8* null, i32 0, i8* %e]
+  catchret from %cp to label %catchhandler
+
+catch.dispatch:
+  %cs = catchswitch within none [label %catch.object.Exception] unwind to caller
+
+catchhandler:
+  call void @use(i8* %e)
+  ret void
+}
+
+; CHECK-LABEL: $handlerMap$0$test1:
+; CHECK:      .long 0
+; CHECK-NEXT: .long 0
+; CHECK-NEXT: .long -20
+
+declare void @use(i8*)
+
+declare i32 @__CxxFrameHandler3(...)




More information about the llvm-commits mailing list