[WinEH] Push and pop EBP for 32-bit funclets
authorReid Kleckner <rnk@google.com>
Thu, 10 Sep 2015 22:00:02 +0000 (22:00 +0000)
committerReid Kleckner <rnk@google.com>
Thu, 10 Sep 2015 22:00:02 +0000 (22:00 +0000)
The Win32 EH runtime caller does not preserve EBP, even though it does
preserve the CSRs (EBX, ESI, EDI) for us. The result was that each
finally funclet call would leave the frame pointer off by 12 bytes.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@247348 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/X86/X86FrameLowering.cpp
test/CodeGen/X86/win-catchpad-csrs.ll
test/CodeGen/X86/win-catchpad.ll
test/CodeGen/X86/win32-seh-cleanupendpad.ll

index 032e003fe4781e16b092c83cb7501579279035c4..05ab69cb870aa6057deff0f906c728b318ac8eac 100644 (file)
@@ -702,6 +702,11 @@ void X86FrameLowering::emitPrologue(MachineFunction &MF,
     // Set up the FramePtr and BasePtr physical registers using the address
     // passed as EBP or RDX by the MSVC EH runtime.
     if (STI.is32Bit()) {
+      // PUSH32r %ebp
+      BuildMI(MBB, MBBI, DL, TII.get(X86::PUSH32r))
+          .addReg(MachineFramePtr, RegState::Kill)
+          .setMIFlag(MachineInstr::FrameSetup);
+      // Reset EBP / ESI to something good.
       MBBI = restoreWin32EHFrameAndBasePtr(MBB, MBBI, DL);
     } else {
       // FIXME: Add SEH directives.
@@ -715,7 +720,7 @@ void X86FrameLowering::emitPrologue(MachineFunction &MF,
         .addReg(RDX)
         .setMIFlag(MachineInstr::FrameSetup);
       // PUSH64r %rbp
-      BuildMI(MBB, MBBI, DL, TII.get(Is64Bit ? X86::PUSH64r : X86::PUSH32r))
+      BuildMI(MBB, MBBI, DL, TII.get(X86::PUSH64r))
           .addReg(MachineFramePtr, RegState::Kill)
           .setMIFlag(MachineInstr::FrameSetup);
       // MOV64rr %rdx, %rbp
@@ -1066,13 +1071,11 @@ void X86FrameLowering::emitEpilogue(MachineFunction &MF,
 
   if (isFuncletReturnInstr(MBBI)) {
     NumBytes = MFI->getMaxCallFrameSize();
+    assert(hasFP(MF) && "win64 EH funclets without FP not yet implemented");
 
-    if (Is64Bit) {
-      assert(hasFP(MF) && "win64 EH funclets without FP not yet implemented");
-      // POP64r %rbp
-      BuildMI(MBB, MBBI, DL, TII.get(Is64Bit ? X86::POP64r : X86::POP32r),
-              MachineFramePtr);
-    }
+    // Pop EBP.
+    BuildMI(MBB, MBBI, DL, TII.get(Is64Bit ? X86::POP64r : X86::POP32r),
+            MachineFramePtr);
   } else if (hasFP(MF)) {
     // Calculate required stack adjustment.
     uint64_t FrameSize = StackSize - SlotSize;
index 6e72268432a3fef11f0c88fb8dfcd55b8cd18f9e..c4cc945fe7d1fe8913a593188437e53fcefba600 100644 (file)
@@ -73,6 +73,7 @@ catchendblock:                                    ; preds = %catch,
 ; X86: retl
 
 ; X86: [[catch1bb:LBB0_[0-9]+]]: # %catch{{$}}
+; X86: pushl %ebp
 ; X86-NOT: pushl
 ; X86: addl $12, %ebp
 ; X86: subl $16, %esp
@@ -81,7 +82,7 @@ catchendblock:                                    ; preds = %catch,
 ; X86: calll _f
 ; X86: movl $[[contbb]], %eax
 ; X86-NEXT: addl $16, %esp
-; X86-NOT: popl
+; X86-NEXT: popl %ebp
 ; X86-NEXT: retl
 
 ; X86: L__ehtable$try_catch_catch:
index c41087a4deb356f880fc8b23eb456d82cebb127b..a6600fb1f8ab66ad7a3fe38e377cddf281bc7589 100644 (file)
@@ -76,6 +76,7 @@ catchendblock:                                    ; preds = %catch, %catch.2, %c
 ; X86: retl
 
 ; X86: [[catch1bb:LBB0_[0-9]+]]: # %catch{{$}}
+; X86: pushl %ebp
 ; X86: addl $12, %ebp
 ; X86: subl $8, %esp
 ; X86: movl $1, -{{[0-9]+}}(%ebp)
@@ -85,9 +86,11 @@ catchendblock:                                    ; preds = %catch, %catch.2, %c
 ; X86: calll _f
 ; X86: movl $[[contbb]], %eax
 ; X86-NEXT: addl $8, %esp
+; X86-NEXT: popl %ebp
 ; X86-NEXT: retl
 
 ; X86: [[catch2bb:LBB0_[0-9]+]]: # %catch.2{{$}}
+; X86: pushl %ebp
 ; X86: addl $12, %ebp
 ; X86: subl $8, %esp
 ; X86: movl $1, -{{[0-9]+}}(%ebp)
@@ -97,6 +100,7 @@ catchendblock:                                    ; preds = %catch, %catch.2, %c
 ; X86: calll _f
 ; X86: movl $[[contbb]], %eax
 ; X86-NEXT: addl $8, %esp
+; X86-NEXT: popl %ebp
 ; X86-NEXT: retl
 
 ; X86: L__ehtable$try_catch_catch:
index 7f1fc322d18d95e519065a3401d6303ff58e25aa..35d9bfeb66ec9d4c5802e914bb8de0eb4e56d801 100644 (file)
@@ -63,14 +63,22 @@ attributes #3 = { noinline }
 ; CHECK: retl
 
 ; CHECK: LBB0_[[inner:[0-9]+]]: # %ehcleanup
+; CHECK: pushl %ebp
+; CHECK: addl $12, %ebp
 ; CHECK: movl $0, -[[state]](%ebp)
 ; CHECK: movl $2, (%esp)
 ; CHECK: calll _f
+; CHECK: popl %ebp
+; CHECK: retl
 
 ; CHECK: LBB0_[[outer:[0-9]+]]: # %ehcleanup.3
+; CHECK: pushl %ebp
+; CHECK: addl $12, %ebp
 ; CHECK: movl $-1, -[[state]](%ebp)
 ; CHECK: movl $3, (%esp)
 ; CHECK: calll _f
+; CHECK: popl %ebp
+; CHECK: retl
 
 ; CHECK: L__ehtable$nested_finally:
 ; CHECK:        .long   -1