[llvm] r253084 - [WinEH] Fix ESP management with 32-bit __CxxFrameHandler3

Reid Kleckner via llvm-commits llvm-commits at lists.llvm.org
Fri Nov 13 13:27:00 PST 2015


Author: rnk
Date: Fri Nov 13 15:27:00 2015
New Revision: 253084

URL: http://llvm.org/viewvc/llvm-project?rev=253084&view=rev
Log:
[WinEH] Fix ESP management with 32-bit __CxxFrameHandler3

The C++ EH personality automatically restores ESP from the C++ EH
registration node after a catchret. I mistakenly thought it was like
SEH, which does not restore ESP.

It makes sense for C++ EH to differ from SEH here because SEH does not
use funclets for catches, and does not allow catching inside of finally.
C++ EH may need to unwind through multiple catch funclets and eventually
catchret to some outer funclet. Therefore, the runtime has to keep track
of which ESP to use with catchret, rather than having the compiler
reload it manually.

Modified:
    llvm/trunk/lib/Target/X86/X86ExpandPseudo.cpp
    llvm/trunk/lib/Target/X86/X86FrameLowering.cpp
    llvm/trunk/test/CodeGen/X86/catchret-fallthrough.ll
    llvm/trunk/test/CodeGen/X86/win-catchpad-csrs.ll
    llvm/trunk/test/CodeGen/X86/win-catchpad.ll

Modified: llvm/trunk/lib/Target/X86/X86ExpandPseudo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ExpandPseudo.cpp?rev=253084&r1=253083&r2=253084&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86ExpandPseudo.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ExpandPseudo.cpp Fri Nov 13 15:27:00 2015
@@ -19,6 +19,7 @@
 #include "X86InstrInfo.h"
 #include "X86MachineFunctionInfo.h"
 #include "X86Subtarget.h"
+#include "llvm/Analysis/LibCallSemantics.h"
 #include "llvm/CodeGen/Passes.h" // For IDs of passes that are preserved.
 #include "llvm/CodeGen/MachineFunctionPass.h"
 #include "llvm/CodeGen/MachineInstrBuilder.h"
@@ -144,7 +145,9 @@ bool X86ExpandPseudo::ExpandMI(MachineBa
 
   case X86::EH_RESTORE: {
     // Restore ESP and EBP, and optionally ESI if required.
-    X86FL->restoreWin32EHStackPointers(MBB, MBBI, DL, /*RestoreSP=*/true);
+    bool IsSEH = isAsynchronousEHPersonality(classifyEHPersonality(
+        MBB.getParent()->getFunction()->getPersonalityFn()));
+    X86FL->restoreWin32EHStackPointers(MBB, MBBI, DL, /*RestoreSP=*/IsSEH);
     MBBI->eraseFromParent();
     return true;
   }

Modified: llvm/trunk/lib/Target/X86/X86FrameLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86FrameLowering.cpp?rev=253084&r1=253083&r2=253084&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86FrameLowering.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86FrameLowering.cpp Fri Nov 13 15:27:00 2015
@@ -1246,6 +1246,19 @@ void X86FrameLowering::emitPrologue(Mach
   } else if (IsFunclet && STI.is32Bit()) {
     // Reset EBP / ESI to something good for funclets.
     MBBI = restoreWin32EHStackPointers(MBB, MBBI, DL);
+    // If we're a catch funclet, we can be returned to via catchret. Save ESP
+    // into the registration node so that the runtime will restore it for us.
+    if (!MBB.isCleanupFuncletEntry()) {
+      assert(classifyEHPersonality(Fn->getPersonalityFn()) ==
+             EHPersonality::MSVC_CXX);
+      unsigned FrameReg;
+      int FI = MMI.getWinEHFuncInfo(Fn).EHRegNodeFrameIndex;
+      int64_t EHRegOffset = getFrameIndexReference(MF, FI, FrameReg);
+      // ESP is the first field, so no extra displacement is needed.
+      addRegOffset(BuildMI(MBB, MBBI, DL, TII.get(X86::MOV32mr)), FrameReg,
+                   false, EHRegOffset)
+          .addReg(X86::ESP);
+    }
   }
 
   while (MBBI != MBB.end() && MBBI->getFlag(MachineInstr::FrameSetup)) {

Modified: llvm/trunk/test/CodeGen/X86/catchret-fallthrough.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/catchret-fallthrough.ll?rev=253084&r1=253083&r2=253084&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/catchret-fallthrough.ll (original)
+++ llvm/trunk/test/CodeGen/X86/catchret-fallthrough.ll Fri Nov 13 15:27:00 2015
@@ -41,6 +41,5 @@ nrvo.skipdtor:
 ; CHECK-NOT: jmp
 ; CHECK-NOT: movl {{.*}}, %esp
 ; CHECK: retl
-; CHECK: movl {{.*}}, %esp
 ; CHECK: addl $12, %ebp
 ; CHECK: jmp LBB0_{{.*}}

Modified: llvm/trunk/test/CodeGen/X86/win-catchpad-csrs.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/win-catchpad-csrs.ll?rev=253084&r1=253083&r2=253084&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/win-catchpad-csrs.ll (original)
+++ llvm/trunk/test/CodeGen/X86/win-catchpad-csrs.ll Fri Nov 13 15:27:00 2015
@@ -67,7 +67,6 @@ catchendblock:
 ; X86: retl
 
 ; X86: [[restorebb:LBB0_[0-9]+]]:
-; X86: movl -16(%ebp), %esp
 ; X86: addl $12, %ebp
 ; X86: jmp [[contbb]]
 

Modified: llvm/trunk/test/CodeGen/X86/win-catchpad.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/win-catchpad.ll?rev=253084&r1=253083&r2=253084&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/win-catchpad.ll (original)
+++ llvm/trunk/test/CodeGen/X86/win-catchpad.ll Fri Nov 13 15:27:00 2015
@@ -66,6 +66,7 @@ catchendblock:
 }
 
 ; X86-LABEL: _try_catch_catch:
+; X86: movl %esp, -[[sp_offset:[0-9]+]](%ebp)
 ; X86: movl $0, -{{[0-9]+}}(%ebp)
 ; X86: leal -[[local_offs:[0-9]+]](%ebp), %[[addr_reg:[a-z]+]]
 ; X86-DAG: movl %[[addr_reg]], 4(%esp)
@@ -76,15 +77,13 @@ catchendblock:
 
 ; X86: [[restorebb1:LBB0_[0-9]+]]: # Block address taken
 ; X86-NEXT:                        # %invoke.cont.2
-; X86: movl -16(%ebp), %esp
-; X86: addl $12, %ebp
+; X86-NEXT: addl $12, %ebp
 ; X86: jmp [[contbb]]
 
 ; FIXME: These should be de-duplicated.
 ; X86: [[restorebb2:LBB0_[0-9]+]]: # Block address taken
 ; X86-NEXT:                        # %invoke.cont.3
-; X86: movl -16(%ebp), %esp
-; X86: addl $12, %ebp
+; X86-NEXT: addl $12, %ebp
 ; X86: jmp [[contbb]]
 
 ; X86: "?catch$[[catch1bb:[0-9]+]]@?0?try_catch_catch at 4HA":
@@ -92,6 +91,7 @@ catchendblock:
 ; X86: pushl %ebp
 ; X86: subl $8, %esp
 ; X86: addl $12, %ebp
+; X86: movl %esp, -[[sp_offset]](%ebp)
 ; X86: leal -[[local_offs]](%ebp), %[[addr_reg:[a-z]+]]
 ; X86: movl -32(%ebp), %[[e_reg:[a-z]+]]
 ; X86: movl $1, -{{[0-9]+}}(%ebp)
@@ -108,6 +108,7 @@ catchendblock:
 ; X86: pushl %ebp
 ; X86: subl $8, %esp
 ; X86: addl $12, %ebp
+; X86: movl %esp, -[[sp_offset]](%ebp)
 ; X86: leal -[[local_offs]](%ebp), %[[addr_reg:[a-z]+]]
 ; X86: movl $1, -{{[0-9]+}}(%ebp)
 ; X86-DAG: movl %[[addr_reg]], 4(%esp)
@@ -258,8 +259,7 @@ catchendblock:
 
 ; X86: [[restorebb:LBB1_[0-9]+]]: # Block address taken
 ; X86-NEXT:                       # %catch.done
-; X86: movl -16(%ebp), %esp
-; X86: addl $12, %ebp
+; X86-NEXT: addl $12, %ebp
 ; X86: jmp [[contbb]]
 
 ; X86: "?catch$[[catchdispbb:[0-9]+]]@?0?branch_to_normal_dest at 4HA":




More information about the llvm-commits mailing list